/// <summary> /// Распаковывает архив с файлами импорта /// </summary> /// <returns></returns> private static FileInfo[] ExtractArchive(FileInfo archive) { try { SrvcLogger.Info("{work}", $"распаковка архива: {archive.Name}"); SrvcLogger.Info("{work}", $"директория: {archive.DirectoryName}"); ZipFile.ExtractToDirectory(archive.FullName, archive.DirectoryName); DirectoryInfo di = new DirectoryInfo(archive.DirectoryName); if (di != null) { FileInfo[] temp = di.GetFiles() .Where(w => !w.Name.ToLower().Contains(".zip")) .ToArray(); var cat = temp.Where(w => w.Name.ToLower().Contains(".xml")) .Where(w => w.Name.ToLower().Contains("cat")) .SingleOrDefault(); SrvcLogger.Info("{work}", $"категории: {cat.Name}"); var prod = temp.Where(w => w.Name.ToLower().Contains(".xml")) .Where(w => w.Name.ToLower().Contains("prod")) .SingleOrDefault(); SrvcLogger.Info("{work}", $"продукция: {prod.Name}"); FileInfo[] result = { cat, prod }; return(result); } } catch (Exception e) { SrvcLogger.Error("{error}", e.ToString()); } return(null); }
/// <summary> /// Обнуляем значения свойств перед новым импортом /// </summary> private static void Preparing() { try { using (var db = new dbModel(CONNECTION)) { CleaningTempTables(db); } distinctProducts = null; emailHelper = new EmailParamsHelper(); EmailBody = String.Empty; CountSuccess = CountFalse = 0; Total = "0 час. 0 мин. 0 сек. 0 мс."; Log = new List <string>(); Steps = new List <string>(); dictionary = new Dictionary <string, string> { { "catalogs", "категории" }, { "products", "товары" }, { "catalogproductlinks", "связи категорий и товаров" }, { "images", "изображения" }, { "certificates", "сертификаты" }, }; if (!IsCompleted) { Percent = Step = CountProducts = 0; } } catch (Exception e) { SrvcLogger.Error("{error}", e.ToString()); } }
/// <summary> /// Работа с файлами импорта /// </summary> /// <param name="file"></param> private static bool FileProcessing(FileInfo file, dbModel db, ReceiverParamsHelper receiverParams) { try { SrvcLogger.Info("{preparing}", $"импорт данных из: '{file.Name}'"); Log.Insert(0, $"Чтение данных: {file.Name}"); using (FileStream fileStream = new FileStream(file.FullName, FileMode.Open)) { SrvcLogger.Info("{preparing}", $"данные прочитаны из файла: {file.Name}"); Log.Insert(0, "Данные прочитаны"); var helper = new InsertHelper { FileStream = fileStream, Db = db, Entity = Entity.Catalogs }; if (file.Name.StartsWith("cat")) { InsertWithLogging(helper); } else if (file.Name.StartsWith("prod")) { foreach (Entity entity in Enum.GetValues(typeof(Entity))) { if (!entity.Equals(Entity.Catalogs)) { helper.Entity = entity; InsertWithLogging(helper); } } Step++; SrvcLogger.Info("{work}", "перенос данных из буферных таблиц"); Log.Insert(0, "Перенос данных из буферных таблиц"); Finalizer(db); Step++; } else if (file.Name.Contains(".zip")) { ImageService imageService = new ImageService(receiverParams); imageService.Execute(file); } } return(true); } catch (Exception e) { SrvcLogger.Error("{error}", e.ToString()); return(false); } }
/// <summary> /// Запуск /// </summary> /// <param name="args"></param> protected override void OnStart(string[] args) { try { integrationWorker = new Thread(DoIntegration); integrationWorker.Start(); } catch (Exception e) { SrvcLogger.Error("{work}", $"глобальная ошибка {e.ToString()}"); } }
/// <summary> /// Попытка вставки списка данных с логированием /// </summary> /// <param name="insert"></param> private static void InsertWithLogging(InsertHelper insert) { string title = insert.Entity.ToString().ToLower(); try { SrvcLogger.Info("{work}", $"{dictionary[title]} начало"); EmailBody += $"<p><b>{dictionary[title]}</b> начало</p>"; switch (insert.Entity) { case Entity.Catalogs: AddCategories(insert); break; case Entity.Products: distinctProducts = AddProducts(insert); break; case Entity.CatalogProductLinks: AddCatalogProdLinks(insert); break; case Entity.Images: AddImageProdLinks(insert); break; case Entity.Certificates: AddCertificateProdLinks(insert); break; } SrvcLogger.Info("{work}", $"{dictionary[title]} конец"); EmailBody += $"<p><b>{dictionary[title]}</b> конец</p>"; UpdateCurrentStep(); } catch (Exception e) { string errorMessage = e.ToString(); EmailBody += $"<p>{errorMessage}</p>"; SrvcLogger.Error("{error}", $"ошибка при импорте {dictionary[title]}"); SrvcLogger.Error("{error}", errorMessage); CountFalse++; } }
/// <summary> /// Удаление файлов импорта /// </summary> /// <param name="files"></param> private static void DropImportFiles(FileInfo[] files) { try { SrvcLogger.Info("{work}", "удаление файлов импорта"); foreach (var file in files) { if (file.Exists) { file.Delete(); } } } catch (Exception e) { SrvcLogger.Error("{work}", e.ToString()); } }
/// <summary> /// Удаляет файлы с предыдущего импорта /// </summary> /// <param name="files"></param> private void DropFiles(FileInfo[] files) { try { SrvcLogger.Info("{work}", "удаление файлов с предыдущего импорта"); foreach (var file in files) { if (file.Exists) { file.Delete(); } } } catch (Exception e) { SrvcLogger.Error("{error}", e.ToString()); } }
/// <summary> /// Возвращает список email для получения информации по импорту /// </summary> /// <param name="db"></param> /// <returns></returns> private static List <string> GetAdminEmails(dbModel db) { try { string email = db.cms_sitess .Select(s => s.c_tech_email).FirstOrDefault(); return(email.Split(';') .Select(s => s.Trim()) .Where(w => !String.IsNullOrWhiteSpace(w)) .ToList()); } catch (Exception e) { SrvcLogger.Error("{error}", e.ToString()); return(null); } }
/// <summary> /// Очищает буферные таблицы /// </summary> private static void CleaningTempTables(dbModel db) { try { using (var tr = db.BeginTransaction()) { db.import_productss.Delete(); db.import_catalogss.Delete(); db.import_product_categoriess.Delete(); db.import_product_certificatess.Delete(); db.import_product_imagess.Delete(); tr.Commit(); } } catch (Exception e) { SrvcLogger.Error("{error}", e.ToString()); } }
/// <summary> /// Обрабатывает изображения /// </summary> public void ResizingImages(FileInfo[] files) { int countFiles = files.Count(); ImageCreator imageCreator = new ImageCreator(); int i = 0; // итерация foreach (var img in files) { try { if (transferParams.AllowedPicTypes.Contains(img.Extension.ToLower())) { string barcode = $"{img.Name.Substring(0, img.Name.LastIndexOf("_"))}"; string saveImgPath = $"{transferParams.To}{barcode}"; if (!Directory.Exists(saveImgPath)) { Directory.CreateDirectory(saveImgPath); } ImageItemHelper[] imageSizes = new ImageItemHelper[] { new ImageItemHelper(img.FullName, $"{saveImgPath}\\{barcode}_1_mini.jpg", 200, 200, "center", "center", null), new ImageItemHelper(img.FullName, $"{saveImgPath}\\{barcode}_1_preview.jpg", 400, 400, "center", "center", null), new ImageItemHelper(img.FullName, $"{saveImgPath}\\{barcode}_1.jpg", 1150, 600, null, null, "width") }; imageCreator.SaveImages(imageSizes); i++; if (i % 100 == 0) { SrvcLogger.Info("{info}", $"обработано {i} изображений из {countFiles}"); } } } catch (Exception e) { SrvcLogger.Error("{error}", e.ToString()); } } }
/// <summary> /// Рассылает оповещения /// </summary> /// <param name="body"></param> private static void SendEmail(string body, dbModel db) { try { SrvcLogger.Info("{work}", "рассылка оповещения"); Log.Insert(0, "Рассылка оповещений"); var receiverEmails = GetAdminEmails(db); receiverEmails.AddRange(emailHelper.EmailTo); foreach (var emailTo in receiverEmails) { var from = new MailAddress(emailHelper.EmailFromAddress, emailHelper.EmailFromName); var to = new MailAddress(emailTo); var message = new MailMessage(from, to) { Subject = "Сервис импорта сайта Малышок-ПрессМарк", Body = body, IsBodyHtml = true }; var smtp = new SmtpClient(emailHelper.EmailHost, emailHelper.EmailPort) { Credentials = new NetworkCredential(emailHelper.EmailFromAddress, emailHelper.EmailPassword), EnableSsl = emailHelper.EmailEnableSsl, }; smtp.Send(message); } Log.Insert(0, "Рассылка оповещений завершена"); SrvcLogger.Info("{work}", "рассылка оповещения проведена"); CountSuccess++; Step++; Percent = 100; } catch (Exception e) { SrvcLogger.Error("{error}", "рассылка оповещений завершилась ошибкой"); SrvcLogger.Error("{error}", e.ToString()); CountFalse++; } }
/// <summary> /// Время ожидания запуска интеграции /// </summary> /// <param name="runTime"></param> /// <returns></returns> private int[] MilisecondsToWait(string[] runTimes) { List <int> startTimeList = new List <int>(); foreach (string runTime in runTimes) { if (TimeSpan.TryParse(runTime, out TimeSpan _runTime)) { startTimeList.Add(MilisecondsToWait(_runTime)); } } if (startTimeList != null && startTimeList.Count() > 0) { return(startTimeList.ToArray()); } string errorMessage = "ошибка определения времени выполнения"; SrvcLogger.Error("{error}", errorMessage); throw new Exception(errorMessage); }
/// <summary> /// Создаёт xml-файл для обратной совместимости /// </summary> /// <param name="path"></param> private static void CreateXmlExport(string path) { try { SrvcLogger.Info("{work}", "создание xml-файла для обратной совместимости"); var productList = GetProducts(); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } DataContractSerializer serializer = new DataContractSerializer(typeof(List <ProductExport>)); using (FileStream writer = new FileStream($"{path}export.xml", FileMode.Create)) { serializer.WriteObject(writer, productList); } } catch (Exception e) { SrvcLogger.Error("{work}", e.ToString()); } }
/// <summary> /// Запускает хранимку для переноса данных из буферных таблиц в боевые /// </summary> /// <param name="db"></param> private static void Finalizer(dbModel db) { try { distinctProducts = null; using (var tr = db.BeginTransaction()) { db.import(); tr.Commit(); } UpdateCurrentStep(); } catch (Exception e) { string errorMessage = e.ToString(); EmailBody += $"<p>{errorMessage}</p>"; SrvcLogger.Error("{error}", errorMessage); CountFalse++; } }
/// <summary> /// Добавляет список сущностей в таблицы /// </summary> /// <typeparam name="T"></typeparam> /// <param name="db"></param> /// <param name="list"></param> private static void AddEntities <T>(EntityHelper <T> entity) { SrvcLogger.Info("{work}", $"{dictionary[entity.Title]} кол-во: {entity.List.Count()}"); Log.Insert(0, $"Кол-во {dictionary[entity.Title]}: {entity.List.Count()}"); EmailBody += $"<p><b>{dictionary[entity.Title]}</b> кол-во: {entity.List.Count()}</p>"; try { using (var tr = entity.Db.BeginTransaction()) { entity.Db.BulkCopy(entity.List); tr.Commit(); } } catch (Exception e) { string errorMessage = e.ToString(); EmailBody += $"<p>{errorMessage}</p>"; SrvcLogger.Error("{error}", errorMessage); } }
/// <summary> /// Возвращает список изображений из директории /// </summary> /// <returns></returns> private static FileInfo[] GetImages(string[] barcodes, TransferParams transferParams) { try { DirectoryInfo oldDirectory = new DirectoryInfo(transferParams.From); DirectoryInfo newDirectory = new DirectoryInfo(transferParams.To); if (oldDirectory != null && newDirectory != null) { var existingDirs = newDirectory .GetDirectories().Select(s => s.Name); return(oldDirectory.GetFiles("*_2.jpg") .Where(w => !existingDirs.Any(a => w.Name.StartsWith(a))) .Where(w => barcodes.Any(a => w.Name.StartsWith(a))) .ToArray()); } } catch (Exception e) { SrvcLogger.Error("{error}", e.ToString()); } return(null); }
/// <summary> /// Запуск интеграции /// </summary> /// <param name="data"></param> private void DoIntegration(object data) { SrvcLogger.Info("{preparing}", "I work!"); ReceiverParamsHelper helperParams = new ReceiverParamsHelper(); string times = String.Join(";", helperParams.StartTime); SrvcLogger.Info("{preparing}", $"время запуска интеграции {times}"); SrvcLogger.Info("{preparing}", $"директория с файлами {helperParams.DirName}"); while (enableIntegration) { int[] executeWaitArray = MilisecondsToWait(helperParams.StartTime); int executeWait = executeWaitArray.Min(); int hoursWait = executeWait / 1000 / 60 / 60; int minutesWait = (executeWait - (hoursWait * 60 * 60 * 1000)) / 1000 / 60; int secWait = (executeWait - (hoursWait * 60 * 60 * 1000) - (minutesWait * 60 * 1000)) / 1000; SrvcLogger.Info("{preparing}", $"импорт будет выполнен через: " + $"{hoursWait} час. {minutesWait} мин. {secWait} сек."); Thread.Sleep(executeWait); DirectoryInfo info = new DirectoryInfo(helperParams.DirName); FileInfo[] files = info.GetFiles("*.zip") .OrderByDescending(p => p.LastWriteTime) .Take(3) .ToArray(); //FileInfo[] filesToDrop = info.GetFiles("*.xml"); //DropFiles(filesToDrop); SrvcLogger.Info("{preparing}", "запуск ядра импорта"); SrvcLogger.Info("{work}", $"директория: {helperParams.DirName}"); if (files != null && files.Any(a => a != null)) { string listFiles = "список найденных файлов: "; foreach (var file in files) { if (file != null) { listFiles += $"{file.Name}; "; } } SrvcLogger.Info("{work}", $"{listFiles}"); Importer.DoImport(files); foreach (var file in files) { if (file != null && file.Exists) { try { SrvcLogger.Info("{work}", $"удаление файла: {file}"); file.Delete(); } catch (Exception e) { SrvcLogger.Error("{error}", $"{e.ToString()}"); } } } } else { SrvcLogger.Info("{work}", "файлов для импорта не найдено"); } } }
/// <summary> /// Основной метод /// </summary> public static void DoImport(FileInfo[] files) { ReceiverParamsHelper receiverParams = new ReceiverParamsHelper(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Preparing(); BackUpFiles(files, receiverParams); if (files != null && files.Any(a => a != null)) { Step++; files = files.Where(w => w != null).ToArray(); var _files = FilesOrdering(files); SrvcLogger.Info("{preparing}", $"кол-во файлов: {_files.Count()}"); string ff = String.Empty; foreach (var f in _files) { ff += f.ToString() + "; "; } SrvcLogger.Info("{preparing}", $"файлы: {ff}"); try { if (_files.Any(a => a.Name.Contains(".xml"))) { if (_files.Any(a => a.Name.Contains(".zip"))) { SetSteps(3); } else { SetSteps(1); } } else if (_files.Any(a => a.Name.Contains(".zip"))) { SetSteps(2); } UpdateCurrentStep(); using (var db = new dbModel(CONNECTION)) { foreach (var file in _files) { try { if (file != null) { bool resultEx = false; resultEx = FileProcessing(file, db, receiverParams); if (!resultEx) { Thread.Sleep(1000 * 60 * 5); FileProcessing(file, db, receiverParams); } } } catch (Exception e) { SrvcLogger.Error("{error}", e.ToString()); } } stopwatch.Stop(); EmailBody += ResultLogging(stopwatch); SendEmail(EmailBody, db); CreateXmlExport(receiverParams.DirName); DropImportFiles(_files); } } catch (Exception e) { SrvcLogger.Error("{error}", e.ToString()); } } else { SrvcLogger.Info("{work}", "файлов для импорта не найдено"); } }