Esempio n. 1
0
        public void SyncFolders(FolderConfig folderConfig1, FolderConfig folderConfig2, string restorePointDirectoryPath)
        {
            var folderConfig1List = GetOperationEventsFromFolderConfig(folderConfig1).SelectMany(t => t.OperationEvents).FilteredOperationEvents().ToList();
            var folderConfig2List = GetOperationEventsFromFolderConfig(folderConfig2).SelectMany(t => t.OperationEvents).FilteredOperationEvents().ToList();

            //Remove OperationEvents from both Lists
            FilterOperationEvents(folderConfig1List, folderConfig1.FolderPath, folderConfig2List, folderConfig2.FolderPath);

            if (folderConfig1List.Count == 0 && folderConfig2List.Count == 0)
            {
                return;
            }

            string restorePointPath = CreateRestorePointDirectory(restorePointDirectoryPath);

            var operationFactory = new OperationFactoryViaOperationEvent(folderConfig1.FolderPath);

            folderConfig1List.GetOperations(operationFactory).FilterOperations().ExecuteAll(folderConfig2.FolderPath);

            var operationFactory2 = new OperationFactoryViaOperationEvent(folderConfig2.FolderPath);

            folderConfig2List.GetOperations(operationFactory2).FilterOperations().ExecuteAll(folderConfig2.FolderPath);

            _logger.LogDebug("Successfully synchronized folders: {folderPath1} and {folderPath2}", folderConfig1.FolderPath, folderConfig2.FolderPath);

            CreateRestorePoints(restorePointPath, folderConfig1, folderConfig2);
        }
Esempio n. 2
0
 public Producer(ILogger <Producer> logger,
                 Channel <string> channel, IOptions <FolderConfig> folderConfig)
 {
     _logger       = logger;
     _folderConfig = folderConfig.Value;
     _channel      = channel;
 }
        public void WatchHiddenFilesTester3()
        {
            string path   = $"{Guid.NewGuid()}.xml";
            var    stream = File.Create(path);

            try
            {
                new FileInfo(stream.Name).Attributes |= FileAttributes.Hidden;

                var folderConfig = new FolderConfig
                {
                    FolderPath = stream.Name.GetDirectoryPath(),
                    //WatchLogFiles = true,
                    WatchHiddenFiles = false
                };

                var op = new CreateOperationEvent
                {
                    FilePath   = stream.Name,
                    RaisedTime = new DateTime(2017, 11, 27)
                };

                Assert.AreEqual(false, folderConfig.IsValid(op));
            }
            finally
            {
                stream.Close();
                File.Delete(path);
            }
        }
        public void TextLogFileNameTester2()
        {
            string path   = $"SomeDateTime - {Constants.TextLogFileName}";
            var    stream = File.Create(path);

            try
            {
                var folderConfig = new FolderConfig
                {
                    FolderPath       = stream.Name.GetDirectoryPath(),
                    WatchHiddenFiles = false
                };

                var op = new CreateOperationEvent
                {
                    FilePath   = stream.Name,
                    RaisedTime = new DateTime(2017, 11, 27)
                };

                Assert.AreEqual(true, folderConfig.IsValid(op));
            }
            finally
            {
                stream.Close();
                File.Delete(path);
            }
        }
        public void FilteredFilesTester2()
        {
            string path   = $"SomeTempFile.txt";
            var    stream = File.Create(path);

            try
            {
                var folderConfig = new FolderConfig
                {
                    FolderPath       = stream.Name.GetDirectoryPath(),
                    WatchHiddenFiles = false,
                    FilteredFiles    = new List <string>()
                    {
                        $"{stream.Name.GetDirectoryPath()}SomeTempFile2.txt"
                    }
                };

                var op = new CreateOperationEvent
                {
                    FilePath   = stream.Name,
                    RaisedTime = new DateTime(2017, 11, 27)
                };

                Assert.AreEqual(true, folderConfig.IsValid(op));
            }
            finally
            {
                stream.Close();
                File.Delete(path);
            }
        }
        public void JsonLogFileNameTester2()
        {
            string path   = $"SomeDateTime - {Constants.JsonLogFileName}";
            var    stream = File.Create(path);

            try
            {
                var folderConfig = new FolderConfig
                {
                    FolderPath       = stream.Name.GetDirectoryPath(),
                    WatchHiddenFiles = false
                };

                var op = new CreateOperationEvent
                {
                    FilePath   = stream.Name,
                    RaisedTime = new DateTime(2017, 11, 27)
                };

                Assert.AreEqual(
                    !FolderConfig.IsLogFile(op.FilePath,
                                            Path.GetFullPath($"{folderConfig.FolderPath}/{Constants.JsonLogFileName}")),
                    folderConfig.IsValid(op, jsonLogFileName: Constants.JsonLogFileName));
            }
            finally
            {
                stream.Close();
                File.Delete(path);
            }
        }
 public AzureBlobHelper(AppSetting options, FolderConfig config)
 {
     _appSettings      = options;
     _config           = config;
     _connectionString = _appSettings.StorageConnectionString;
     _containerName    = config.ContainerName;
     _localFolderPath  = config.LocalFolderPath;
     if (OperatingSystem.IsWindows() && _localFolderPath.LastOrDefault() != '\\')
     {
         if (config.IsFolder == true)
         {
             _localFolderPath = _localFolderPath + '\\';
         }
         //_localFolderPath = _localFolderPath + '\\';
     }
     else if (OperatingSystem.IsWindows() && _localFolderPath.LastOrDefault() != '/')
     {
         if (config.IsFolder == true)
         {
             _localFolderPath = _localFolderPath + '/';
         }
         //_localFolderPath = _localFolderPath + '/';
     }
     _blobContainer = GetBlobContainer();
     if (null == _blobContainer)
     {
         NLogManager.LogError("ERROR: Can not get BlobContainer.");
     }
 }
Esempio n. 8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="relPath"></param>
        /// <param name="topFolder"></param>
        /// <returns></returns>
        public static bool IsProtetedUrl(string relPath)
        {
            if (string.IsNullOrEmpty(relPath))
            {
                return(false);
            }
            FolderConfig targetFolder = null;

            string[] relPathParts = relPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries).ToArray();
            if (relPathParts.Length == 0)
            {
                return(false);
            }
            string topRelPath = relPathParts[0];

            foreach (var sf in config.Folders)
            {
                string shareRelPath = sf.Title;
                if (topRelPath.Equals(shareRelPath, StringComparison.OrdinalIgnoreCase))
                {
                    targetFolder = sf;
                    break;
                }
            }
            if (targetFolder != null && targetFolder.isProtected)
            {
                return(true);
            }
            return(false);
        }
Esempio n. 9
0
 /// <summary>
 /// если был создан каталог - добавляем его
 /// </summary>
 private static void AddFolderIfPrepared()
 {
     if (temp_folder != null)
     {
         ContestFolders.Add(temp_folder);
         temp_folder = null;
     }
 }
Esempio n. 10
0
 public static void RemoveJsonLogs(this FolderConfig folderConfig)
 {
     Thread.Sleep(1000);
     GC.Collect();
     GC.WaitForPendingFinalizers();
     foreach (var filePath in folderConfig.GetFolderConfigJsonLogs())
     {
         File.Delete(filePath);
     }
 }
Esempio n. 11
0
        public void DeleteOperationEventLoggedCorrectly()
        {
            var delOp = new DeleteOperationEvent()
            {
                FilePath = GetType().Assembly.Location, RaisedTime = new DateTime(2017, 11, 23)
            };
            var folderConfig = new FolderConfig {
                FolderPath = "D:\\DVL_Sync_WatcherTestingFile2"
            };

            OperationEventLoggedCorrectly(delOp, folderConfig);
        }
        private void AddFolderConfigToForm(FolderConfig folderConfig)
        {
            var index = this.dataGridViewFolderConfigs.Rows.Add();

            this.dataGridViewFolderConfigs.Rows[index].Cells["ColumnFolderPath"].Value =
                folderConfig.FolderPath;
            this.dataGridViewFolderConfigs.Rows[index].Cells["ColumnIncludeSubdirectories"].Value =
                folderConfig.IncludeSubDirectories;
            this.dataGridViewFolderConfigs.Rows[index].Cells["ColumnWatchHiddenFiles"].Value =
                folderConfig.WatchHiddenFiles;
            this.dataGridViewFolderConfigs.Rows[index].Cells["ColumnFilteredFiles"].Value =
                string.Join(", ", folderConfig.FilteredFiles);
        }
        private void ButtonSaveConfiguration_Click(object sender, EventArgs e)
        {
            if (this.folderConfig == null)
            {
                this.folderConfig = new FolderConfig();
            }

            this.folderConfig.FolderPath            = this.textBoxFolderPath.Text;
            this.folderConfig.FilteredFiles         = GetFilteredFilesFromGrid().Select(file => file.FilePath).ToList();
            this.folderConfig.IncludeSubDirectories = this.checkBoxIncludeSubdirectories.Checked;
            this.folderConfig.WatchHiddenFiles      = this.checkBoxWatchHiddenFiles.Checked;
            Close();
        }
Esempio n. 14
0
        public void RenameOperationEventLoggedCorrectly()
        {
            var renameOp = new RenameOperationEvent()
            {
                FilePath    = GetType().Assembly.Location, RaisedTime = new DateTime(2017, 11, 23),
                OldFilePath = "D:\\SomeInValidPath"
            };
            var folderConfig = new FolderConfig {
                FolderPath = "D:\\DVL_Sync_WatcherTestingFile2"
            };

            OperationEventLoggedCorrectly(renameOp, folderConfig);
        }
 public TextExtractor(
     ILogger <TextExtractor> logger,
     IOptions <AppSetting> appSetting,
     IOptions <FolderConfig> folderConfig,
     IGoogleOCRService googleOCRService,
     IMetadataParser metadataParser,
     IServiceProvider service)
 {
     _logger           = logger;
     _appSetting       = appSetting.Value;
     _folderConfig     = folderConfig.Value;
     _services         = service;
     _googleOCRService = googleOCRService;
     _metadataParser   = metadataParser;
 }
 public async Task WriteLastRunTime(string fileName, string content, FolderConfig folder)
 {
     try
     {
         string localFilePath = System.IO.Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName)
                                + "\\" + fileName + ".json";
         var str     = File.ReadAllText(localFilePath);
         var configs = JsonSerializer.Deserialize <AppJson>(str);
         var fl      = configs.Settings.Folders.FirstOrDefault(x => x.Id == folder.Id);
         fl.LastRunTime = content;
         File.WriteAllText(localFilePath, JsonSerializer.Serialize(configs));
     }
     catch (Exception ex)
     {
         NLogManager.LogInfo("WriteLastRunTime  ==>  " + ex);
     }
 }
Esempio n. 17
0
        private FolderConfig LoadSettings(XElement config)
        {
            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            var settings = new FolderConfig();

            settings.Folder = config.Element("folder").ValueOrDefault(string.Empty);
            if (string.IsNullOrWhiteSpace(settings.Folder))
            {
                throw new ArgumentOutOfRangeException(nameof(config), "No Folder setting");
            }

            return(settings);
        }
Esempio n. 18
0
 /// <summary>
 /// Working on json files only
 /// </summary>
 /// <param name="folderConfig"></param>
 /// <param name="restorePointDirectoryPath"></param>
 /// <param name="logger"></param>
 public static void CreateRestorePoint(this FolderConfig folderConfig, string restorePointDirectoryPath, ILogger logger)
 {
     logger.LogDebug("Creating restore point for {folderConfig}", folderConfig.FolderPath);
     foreach (var filePath in folderConfig.GetFolderConfigJsonLogs())
     {
         string path = Path.Combine(restorePointDirectoryPath, Path.GetFileName(filePath));
         string destinationFilePath = path.Substring(0, path.Length - 5);
         int    i = 1;
         while (File.Exists($"{ destinationFilePath }.json"))
         {
             destinationFilePath = $"{ path } { i++ }";
         }
         File.Copy(filePath, $"{ destinationFilePath }.json");
         logger.LogDebug("Copied {filePath} to {restorePointDirectoryPath}", filePath, restorePointDirectoryPath);
     }
     folderConfig.RemoveJsonLogContents();
     logger.LogDebug("Removed json log file contents successfully");
 }
Esempio n. 19
0
        private void OperationEventLoggedCorrectly(OperationEvent opEvent, FolderConfig folderConfig)
        {
            //using (var stream = new MemoryStream())
            //using (var eventsLogger = new FolderEventsLoggerInFile(folderConfig, CreateStreamWriter(stream)))
            //{
            //    eventsLogger.LogOperation(opEvent);

            //    //Check if two equals
            //    string actual = Encoding.Default.GetString(stream.ToArray());

            //    if (folderConfig.IsValid(opEvent, Constants.TextLogFileName))
            //    {
            //        string expected = $"{opEvent}{Environment.NewLine}";
            //        Assert.AreEqual(expected, actual);
            //    }
            //    else Assert.AreEqual(string.Empty, actual);
            //}
        }
Esempio n. 20
0
 public static void RemoveJsonLogContents(this FolderConfig folderConfig)
 {
     Thread.Sleep(1000);
     GC.Collect();
     GC.WaitForPendingFinalizers();
     foreach (var filePath in folderConfig.GetFolderConfigJsonLogs())
     {
         if (Path.GetFileName(filePath).GetCustomDateTime() < DateTime.Now.Date)
         {
             File.Delete(filePath);
         }
         else
         {
             var fileStream = File.Open(filePath, FileMode.Open);
             fileStream.SetLength(0);
             fileStream.Close();
         }
     }
 }
Esempio n. 21
0
        public static bool TryGetRelPath(string absPath, out string relPath)
        {
            relPath = string.Empty;
            FolderConfig targetFolder = null;

            foreach (var sf in config.Folders)
            {
                string sfPath = sf.Path;
                if (sf.Path == absPath)
                {
                    relPath = "/" + sf.Title;
                    return(true);
                }
                if (absPath.StartsWith(sfPath, StringComparison.OrdinalIgnoreCase))
                {
                    targetFolder = sf;
                    break;
                }
            }

            if (targetFolder == null)
            {
                return(false);
            }
            relPath = absPath.Substring(targetFolder.Path.Length);
            if (relPath == string.Empty)
            {
                relPath = "/";
            }
            else
            {
                relPath = relPath.Replace(Path.DirectorySeparatorChar, '/');
                relPath = "/" + targetFolder.Title + relPath;
            }


            return(true);
        }
Esempio n. 22
0
        /// <summary>
        /// 跟 configFolder比對的部份有問題
        /// /H-Anime123 也會被判斷符合
        /// 要改成先拆會一個一個 folder 再針對第1個folder做比對
        /// </summary>
        /// <param name="relPath"></param>
        /// <returns></returns>
        public static bool TryGetAbsolutePath(string relPath, out string absolutePath)
        {
            //~/Anime/2018連載-3/高分少女
            absolutePath = string.Empty;
            if (string.IsNullOrEmpty(relPath))
            {
                return(true);
            }
            FolderConfig targetFolder = null;

            string[] relPathParts = relPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries).ToArray();
            if (relPathParts.Length == 0)
            {
                return(false);
            }
            string topRelPath = relPathParts[0];

            string[] bottomRelPaths = relPathParts.Skip(1).ToArray();
            foreach (var sf in config.Folders)
            {
                string shareRelPath = sf.Title;
                if (topRelPath.Equals(shareRelPath, StringComparison.OrdinalIgnoreCase))
                {
                    targetFolder = sf;
                    break;
                }
            }
            if (targetFolder == null)
            {
                return(false);
            }
            absolutePath = Path.Combine(
                targetFolder.Path,
                string.Join(Path.DirectorySeparatorChar, bottomRelPaths));
            return(true);
        }
Esempio n. 23
0
 public IFolderEventsLogger CreateLoggerInJsonFile(FolderConfig folderConfig, Func <DateTime, string> logFilePathFunc) =>
 new FolderEventsLoggerInJsonFile(folderConfig, logFilePathFunc);
 public FolderEventsLoggerInWindows10Notifications(FolderConfig folderConfig, string appid)
 {
     this.folderConfig = folderConfig;
     applicationID     = appid;
     Windows10NotificationsHelper.TryCreateShortcut(applicationID);
 }
 public FolderEventsLoggerInConsole(FolderConfig folderConfig) => this.folderConfig = folderConfig;
Esempio n. 26
0
        /// <summary>
        /// разбор одной строки из настроек
        /// </summary>
        /// <param name="s"></param>
        private static void ParseLine(string s)
        {
            // списки
            if (Util.StrExists(s, "period"))
            {
                string[] data = s.Substring(s.IndexOf('=') + 1).Split(',');
                if (data.Count() != 2)
                {
                    throw new Exception("Ошибка в периоде!");
                }
                ContestPeriod.Add(new Period(DateTime.ParseExact(data[0].TrimStart(), "yyyy-MM-dd HHmm", CultureInfo.InvariantCulture), DateTime.ParseExact(data[1].TrimStart(), "yyyy-MM-dd HHmm", CultureInfo.InvariantCulture)));
            }
            if (Util.StrExists(s, "band"))
            {
                string[] data = s.Substring(s.IndexOf('=') + 1).Split(',');
                if (data.Count() != 2)
                {
                    throw new Exception("Ошибка в очках за диапазон!");
                }
                int band = Int32.Parse(data[0]);
                if (!Standards.Bands.Check(band))
                {
                    throw new Exception("Ошибка в частоте " + data[0]);
                }
                ContestBandPoints.Add(new BandPoint(band, Double.Parse(data[1], CultureInfo.InvariantCulture)));
            }

            // папки
            if (Util.StrExists(s, "name"))
            {
                AddFolderIfPrepared();
                temp_folder = new FolderConfig(s.Substring(s.IndexOf('=') + 1).Trim());
            }
            else if (Util.StrExists(s, "desc"))
            {
                if (temp_folder != null)
                {
                    temp_folder.Desc = s.Substring(s.IndexOf('=') + 1).Trim();
                }
            }
            else if (Util.StrExists(s, "freq"))
            {
                if (temp_folder != null)
                {
                    temp_folder.AllowBands = new AllowBands();
                    foreach (string str in s.Substring(s.IndexOf('=') + 1).Split(','))
                    {
                        int band = Int32.Parse(str);
                        if (!Standards.Bands.Check(band))
                        {
                            throw new Exception("Ошибка в частоте " + str);
                        }
                        temp_folder.AllowBands.Add(band);
                    }
                }
            }
            else if (Util.StrExists(s, "mode"))
            {
                if (temp_folder != null)
                {
                    temp_folder.AllowModes = new AllowModes();
                    foreach (string str in s.Substring(s.IndexOf('=') + 1).Split(',').Select(p => p.Trim()).ToList())
                    {
                        if (Standards.Modes.Check(str))
                        {
                            throw new Exception("Ошибка в режиме работы " + str);
                        }
                        temp_folder.AllowModes.Add(str);
                    }
                }
            }
            else
            {
                AddFolderIfPrepared();
            }

            // штучные параметры
            if (Util.StrExists(s, "folder_check"))
            {
                folder_check = s.Substring(s.IndexOf('=') + 1).Trim();
            }
            if (Util.StrExists(s, "folder_ubn"))
            {
                folder_ubn = s.Substring(s.IndexOf('=') + 1).Trim();
            }
            if (Util.StrExists(s, "folder_report"))
            {
                folder_report = s.Substring(s.IndexOf('=') + 1).Trim();
            }
            if (Util.StrExists(s, "subtour_min"))
            {
                subtour_min = Int32.Parse(s.Substring(s.IndexOf('=') + 1));
            }
            if (Util.StrExists(s, "offset_min"))
            {
                offset_min = Int32.Parse(s.Substring(s.IndexOf('=') + 1));
            }
            if (Util.StrExists(s, "repeat_call"))
            {
                repeat_call = Int32.Parse(s.Substring(s.IndexOf('=') + 1));
            }
            if (Util.StrExists(s, "double_check"))
            {
                double_check = Int32.Parse(s.Substring(s.IndexOf('=') + 1));
            }
            if (Util.StrExists(s, "rst_check"))
            {
                rst_check = Int32.Parse(s.Substring(s.IndexOf('=') + 1));
            }
            if (Util.StrExists(s, "band_changes"))
            {
                band_changes = Int32.Parse(s.Substring(s.IndexOf('=') + 1));
            }
            if (Util.StrExists(s, "control"))
            {
                control = Int32.Parse(s.Substring(s.IndexOf('=') + 1));
            }
            if (Util.StrExists(s, "control:loc"))
            {
                control_loc = Int32.Parse(s.Substring(s.IndexOf('=') + 1));
            }
        }
Esempio n. 27
0
 public IFolderEventsLogger CreateLoggerAsWindows10Notification(FolderConfig folderConfig, string appid) =>
 new FolderEventsLoggerInWindows10Notifications(folderConfig, appid);
Esempio n. 28
0
 public static IEnumerable <string> GetFolderConfigJsonLogs(this FolderConfig folderConfig) =>
 Directory.GetFiles(folderConfig.FolderPath).Where(filePath =>
                                                   folderConfig.IsLogFileWithLogName(filePath, Constants.JsonLogFileName));
Esempio n. 29
0
 public IFolderEventsLogger CreateLoggerInConsole(FolderConfig folderConfig) =>
 new FolderEventsLoggerInConsole(folderConfig);
Esempio n. 30
0
        private async Task <bool> IsAllow(FolderConfig folder)
        {
            // return true;
            //if (GetIsRunNow("appsettings") == true)
            //{
            //    return false; // return đây để run worker  Warring
            //}

            var strTimer    = folder.TimerString;
            var timerArray  = strTimer.Split('|');
            var lastTimeRun = folder.LastRunTime;

            //if (Convert.ToInt32(timerArray[0]) == 1)  // hàng ngay
            //{
            //    var currentHour = DateTime.Now.Hour;
            //    var currentMinute = DateTime.Now.Minute;
            //    if (Convert.ToInt32(timerArray[2]) == 3) //theo nhiều giờ cố định
            //    {
            //        var listHour = timerArray[3].Split(',');
            //        foreach (var item in listHour)
            //        {
            //            if (currentHour == int.Parse(item) && currentMinute < 60)
            //            {
            //                return true;
            //            }
            //        }
            //    }
            //    // xác định mốc giờ cố định?
            //    if (Convert.ToInt32(timerArray[2]) == 1)  // theo mốc cố định
            //    {
            //        var hour = Convert.ToInt32(timerArray[3]) % 24;
            //        if (currentHour == hour && currentMinute < timerRun)
            //        {
            //            return true;
            //        }

            //    }
            //    if(Convert.ToInt32(timerArray[2]) == 2)
            //    {
            //        var hour = Convert.ToInt32(timerArray[3]) % 24;
            //        if (lastTimeRun.Hour + hour == currentHour && currentMinute < timerRun)
            //        {
            //            return true;
            //        }
            //    }
            //}
            //else  //theo tuan
            //{
            if (!string.IsNullOrEmpty(timerArray[1]) && folder.Id > 0)
            {
                //return true;

                var dayOfWeekArray = timerArray[1].Split(',').Select(s => Convert.ToInt32(s)).ToList();
                var dayOfWeek      = (int)DateTime.Now.DayOfWeek;
                //xem còn mấy ngày đến lượt chạy tiếp
                var day = 7;
                for (int i = 0; i < dayOfWeekArray.Count(); i++)
                {
                    var dayTemp = 0;
                    if (dayOfWeekArray[i] > dayOfWeek)
                    {
                        dayTemp = dayOfWeekArray[i] - dayOfWeek;
                    }
                    else
                    {
                        dayTemp = 7 - (dayOfWeek - dayOfWeekArray[i]);
                    }
                    if (dayTemp > 0 && dayTemp < day)
                    {
                        day = dayTemp;
                    }
                }

                var currentHour   = DateTime.Now;
                var currentMinute = DateTime.Now.Minute;
                if (Convert.ToInt32(timerArray[2]) == 3) //theo nhiều giờ cố định
                {
                    if (dayOfWeekArray.Contains(dayOfWeek))
                    {
                        var listHour = timerArray[3].Split(',');
                        foreach (var item in listHour)
                        {
                            var Time = DateTime.Parse(item);
                            if (currentHour.Hour == Time.Hour && currentHour.Minute == Time.Minute)
                            {
                                return(true);
                            }
                        }
                    }
                }
                // xác định lặp lại sau bao lâu
                if (Convert.ToInt32(timerArray[2]) == 2)
                {
                    var hour = Convert.ToInt32(timerArray[3]) % 24;
                    //hour sẽ là sau bao nhiêu giờ chạy tiếp

                    var lastRun = DateTime.Parse(folder.LastRunTime == "" ? folder.CreateTime : folder.LastRunTime);
                    if (lastRun.AddHours(hour).Hour == currentHour.Hour)
                    {
                        return(true);
                    }
                }
                //}
            }

            return(false);
        }