using AutoMapper; using MailKit.Search; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using MimeKit; using PARR.AIHIT.Settings; using PARR.DAL.Models; using PARR.DAL.Services.Interfaces; using PARR.Mail.Services; using System.Text; using System.Xml; namespace PARR.AIHIT { internal class Syncher : ISyncher { private readonly ILogger logger; private readonly IMailService mailService; private readonly SyncherSettings syncherSettings; private readonly IHostService hostService; private readonly IMapper mapper; public Syncher( ILogger logger, IMailService mailService, SyncherSettings syncherSettings, IHostService hostService, IMapper mapper ) { this.hostService = hostService; this.mapper = mapper; this.logger = logger; this.mailService = mailService; this.syncherSettings = syncherSettings; } public async Task InvokeAsync() { var hosts = await hostService.Get().ToListAsync(); var messages = await mailService.CheckMailAsync(SearchQuery.NotSeen); if (!messages.Any()) { return; } var filtered = messages.Where(m => syncherSettings.IncludeAddressesArray.Any(i => m.Envelope.From.Mailboxes.First().Address == i)).ToList(); var lastMessage = filtered.OrderByDescending(f => f.Date).First(); var attachments = await mailService.GetAttachmentsAsync(lastMessage); foreach (var attachment in attachments) { if (attachment is MessagePart) { continue; } else { var stream = new MemoryStream(); ((MimePart)attachment).Content.DecodeTo(stream); if (stream.Position > 0) stream.Position = 0; var fileName = EncodeString(((MimePart)attachment).FileName); logger.LogInformation($" Получен файл {fileName}"); if (fileName.Equals("Компонентный состав регионального ЭК.xml")) { XmlDocument doc = new XmlDocument(); doc.Load(stream); var vms = doc.GetElementsByTagName("Сведения"); //var hosts = await hostService.Get().ToListAsync(); foreach (XmlNode vm in vms) { var ip = vm?.Attributes?["IP_АДРЕС"]?.Value.Trim(); if (ip == null) continue; var regionalEK = vm!.Attributes!["РЕГИОНАЛЬНЫЙ_ЭК"]!.Value.Trim(); var eK = vm!.Attributes!["СВЯЗАННЫЙ_ЭК"]!.Value.Trim(); if (!eK.StartsWith("ВРТ")) continue; var foundHost = await hostService.GetHostByIPAndRegionalEKAsync(ip, regionalEK); var mappedHost = mapper.Map(vm); if (foundHost != null) { var isChanged = false; if (!foundHost.RegionalEK!.Equals(mappedHost.RegionalEK)) { foundHost.RegionalEK = mappedHost.RegionalEK; isChanged = true; } else if (!foundHost.LinkEK!.Equals(mappedHost.LinkEK)) { foundHost.LinkEK = mappedHost.LinkEK; isChanged = true; } else if (!foundHost.Status!.Equals(mappedHost.Status)) { foundHost.Status = mappedHost.Status; isChanged = true; } else if (!foundHost.WorkGroup!.Equals(mappedHost.WorkGroup)) { foundHost.WorkGroup = mappedHost.WorkGroup; isChanged = true; } else if (!foundHost.Responsible!.Equals(mappedHost.Responsible)) { foundHost.Responsible = mappedHost.Responsible; isChanged = true; } else if (!foundHost.OS!.Equals(mappedHost.OS)) { foundHost.OS = mappedHost.OS; isChanged = true; } else if (!foundHost.DB!.Equals(mappedHost.DB)) { foundHost.DB = mappedHost.DB; isChanged = true; } else if (!foundHost.APP!.Equals(mappedHost.APP)) { foundHost.APP = mappedHost.APP; isChanged = true; } foundHost.DateModified = DateTimeOffset.UtcNow; ; if (isChanged && !await hostService.CommitAsync()) logger.LogError($"Не удалось обновить узел {mappedHost.IP} {mappedHost.RegionalEK}"); else logger.LogInformation($"Обновлён узел {mappedHost.IP} {mappedHost.RegionalEK}"); } else { if (!await hostService.CreateAsync(mappedHost) || !await hostService.CommitAsync()) logger.LogError($"Не удалось создать узел {mappedHost.IP} {mappedHost.RegionalEK}"); } //host.DateModified = ... //var host = new PARR.DAL.Models.Host //{ // HostName = "", // IP = vm!.Attributes["IP_АДРЕС"]!.Value, // RegionalEK = vm?.Attributes?["РЕГИОНАЛЬНЫЙ_ЭК"]?.Value, // LinkEK = vm?.Attributes?["СВЯЗАННЫЙ_ЭК"]?.Value, // Status = vm?.Attributes?["СТАТУС"]?.Value, // WorkGroup = vm?.Attributes?["РАБОЧАЯ_ГР_ОТВ_ЗА_ЭК"]?.Value, // Responsible = vm?.Attributes?["ОТВЕТСТВЕННЫЙ_ЗА_ЭК"]?.Value, // OS = vm?.Attributes?["ОС"]?.Value, // DB = vm?.Attributes?["СУБД"]?.Value, // APP = vm?.Attributes?["СП"]?.Value, //}; //logger.LogInformation($"Запись сервера {mappedHost.IP}, региональный ЭК {mappedHost.RegionalEK}"); //if (String.IsNullOrEmpty(host.Status) || !host.Status.Equals("3-В эксплуатации")) continue; //if (String.IsNullOrEmpty(host.IP)) continue; } } break; } } //прочитано для всех foreach (var message in filtered) { await mailService.SetAsSeenAsync(message); } } private bool IsChanged(Host host, Host mappedHost) { if (host == null) return true; if (mappedHost == null) return true; if (!host.IP.Equals(mappedHost.IP)) return true; if (!host.RegionalEK!.Equals(mappedHost.RegionalEK)) return true; if (!host.LinkEK!.Equals(mappedHost.LinkEK)) return true; if (!host.Status!.Equals(mappedHost.Status)) return true; if (!host.WorkGroup!.Equals(mappedHost.WorkGroup)) return true; if (!host.Responsible!.Equals(mappedHost.Responsible)) return true; if (!host.OS!.Equals(mappedHost.OS)) return true; if (!host.DB!.Equals(mappedHost.DB)) return true; if (!host.APP!.Equals(mappedHost.APP)) return true; return false; } private static string EncodeString(string str) { byte[] bStr = Encoding.GetEncoding("koi8r").GetBytes(str); Encoding encoding = Encoding.GetEncoding("koi8r"); str = encoding.GetString(bStr, 0, bStr.Length); return str; } } }