using Microsoft.Extensions.Logging; using PARR.BLL.Services.Interfaces; using PARR.BLL.Settings; using PARR.EsppTemplateSync.Services; namespace PARR.EsppTemplateSync { internal class TemplateSyncer : ITemplateSyncer { private readonly ILogger logger; private readonly IParserService parserService; private readonly IFileService fileService; private readonly string dirPath; private readonly string filterExtensions; private FileSystemWatcher? watcher; public TemplateSyncer( StorageSettings storageSettings, ILogger logger, IParserService parserService, IFileService fileService ) { this.logger = logger; this.parserService = parserService; this.fileService = fileService; if (storageSettings.EsppTemplates == null) { logger.LogError("Нет секции настроек хранилища. StorageSettings, EsppTemplates"); throw new Exception("Нет секции настроек хранилища. StorageSettings, EsppTemplates"); } string dirPath = Path.Combine(storageSettings.EsppTemplates.TemplatePath); this.dirPath = Path.Combine(storageSettings.StoragePath, dirPath); filterExtensions = string.Join(",", storageSettings.EsppTemplates!.AllowedExtensions).Replace(".", "*."); } public void StartWatching() { //смотрим, доступна ли папка if (!Directory.Exists(dirPath)) { logger.LogError($"Не найдена папка: {dirPath}."); throw new Exception($"Не найдена папка: {dirPath}."); } // сначала обрабатываем существующие файлы, до тех пор пока все не обработаем // после обработки всех файлов, запускаем вотчер GetExistingFilesAsync(); watcher = new FileSystemWatcher(dirPath); watcher.NotifyFilter = NotifyFilters.FileName; //watcher.Changed += OnChanged; //todo: тут await??? watcher.Created += OnChanged; watcher.Filter = filterExtensions; watcher.EnableRaisingEvents = true; logger.LogInformation($"--- --- --- FileWatcher запущен --- --- ---"); } public void StopWatching() { watcher?.Dispose(); logger.LogInformation($"=== === === FileWatcher остановлен === === ==="); } private async void OnChanged(object sender, FileSystemEventArgs e) { var path = e.FullPath; await ParseFileAsync(path); } private async void GetExistingFilesAsync() { // при первом запуске воркера, обрабатываем существующие файлы var files = Directory.GetFiles(this.dirPath, filterExtensions); logger.LogInformation($"Запуск первоначальной загрузки файлов после старта сервиса. (До старта вотчера). Найдено файлов: {files.Length} шт."); foreach (var file in files) await ParseFileAsync(file); //если были файлы, запустим еще раз ручную обработку, вдруг за это время еще загрузили, а вотчер еще не был запущен //запускаем до тех пор, пока не останется необработанных файлов if (files.Any()) GetExistingFilesAsync(); } private async Task ParseFileAsync(string path) { logger.LogInformation($"--- --- Найден файл. Готов для парсинга {path} --- ---"); var parseResult = await parserService.ParseAsync(path); if (parseResult) { logger.LogInformation($"Парсинг успешно завершен. Удаляю файл {path}"); var removeResult = fileService.DeleteFile(path); } else { logger.LogError($"Парсинг завершен c ошибкой. Файл не удален {path}"); } } } }