コード例 #1
0
        /// <summary>
        /// Сихронизация задания
        /// </summary>
        /// <param name="task">Задания</param>
        /// <param name="serv">Удаленный сервер</param>
        /// <param name="WorkNoteNotation">Текущее задание в WorkNote</param>
        /// <param name="NameAndValue">Колекция для ответа в журнал</param>
        /// <param name="IsOk">Выполнено задание или нет</param>
        private static void Sync(Task task, RemoteServer serv, Notation WorkNoteNotation, out List <More> NameAndValue, ref bool IsOk)
        {
            #region Ошибка подключения
            if (!serv.IsConnected)
            {
                NameAndValue = new List <More>()
                {
                    new More("Состояние", $"Ошибка подключения к {task.TypeSunc.ToString()}")
                };
                return;
            }
            #endregion

            try
            {
                #region Получаем список папок в которых были ошибки при синхронизации
                string PathSyncToErrorLocalFolder = $"{Folders.Sync}/tk-{task.Id}.ErrorLocalFolders.json";
                var    NewListErrorLocalFolders   = new List <string>(); // Новый список папок с ошибкой синхронизации
                var    oldListErrorLocalFolders   = new List <string>(); // Текущий список папок с ошибкой синхронизации
                if (File.Exists(PathSyncToErrorLocalFolder))
                {
                    oldListErrorLocalFolders = JsonConvert.DeserializeObject <List <string> >(File.ReadAllText(PathSyncToErrorLocalFolder));
                }
                #endregion

                #region Переменные
                // Список новых папок
                var ListNewLocalFolders = new List <string>();

                // Время старта задания
                var TimeStartTask = DateTime.Now;

                // Количиство созданных папок и загруженых файлов
                int CountUploadToFilesOK = 0, CountUploadToFilesAll = 0, CountCreateToDirectoryOk = 0, CountCreateToDirectoryAll = 0;

                // Количиство провереных обьектов - (папок/файлов)
                int CountToCheckedObject = 0;

                // Общий размер переданых файлов в byte
                long CountUploadToBytes = 0;

                // Отчет созданных папок
                string       ReportNameToCreateFolders = $"tk-{task.Id}_{DateTime.Now.ToString("dd-MM-yyy_HH-mm")}-{Generate.Passwd(6)}.folders.txt";
                StreamWriter ReportToCreateFolders     = new StreamWriter($"{Folders.ReportSync}/{ReportNameToCreateFolders}", false, Encoding.UTF8);

                // Отчет загруженных файлов
                string       ReportNameToUploadFiles = $"tk-{task.Id}_{DateTime.Now.ToString("dd-MM-yyy_HH-mm")}-{Generate.Passwd(6)}.files.txt";
                StreamWriter ReportToUploadFiles     = new StreamWriter($"{Folders.ReportSync}/{ReportNameToUploadFiles}", false, Encoding.UTF8);
                #endregion

                // Получаем список всех папок
                foreach (var LocalFolder in SearchDirectory.Get(task.Whence))
                {
                    CountToCheckedObject++;

                    // Если папка в списке игнорируемых папок
                    if (task.IgnoreFileOrFolders.Exists(i => Regex.IsMatch(LocalFolder, i.Patch.Replace("\\", "/"), RegexOptions.IgnoreCase)))
                    {
                        continue;
                    }

                    // Проверяем папку, нужно ее синхронизировать или нет
                    if (CacheLastWriteTimeToFiles(LocalFolder, task.CacheSync, ref CountToCheckedObject) ||          // Если дата изменения любого файла внутри папки LocalFolder выше чем CacheSync
                        Directory.GetCreationTime(LocalFolder) > task.CacheSync ||                                   // Если дата создания папки выше CacheSync
                        Directory.GetLastWriteTime(LocalFolder) > task.CacheSync ||                                  // Если дата изменения в папке выше CacheSync
                        ListNewLocalFolders.Exists(i => LocalFolder.Contains(i)) ||                                  // Если эта папка является новой, нужно сихронизировать все включая все подпапки в ней
                        oldListErrorLocalFolders.Exists(i => LocalFolder == i))                                      // Список папок в котрых в прошлый раз была ошибка при синхронизации
                    {
                        #region Переменные
                        // Количиство потоков
                        int ActiveConnections = 1;
                        switch (task.TypeSunc)
                        {
                        case TypeSunc.OneDrive:
                            ActiveConnections = 10;
                            break;

                        case TypeSunc.SFTP:
                            ActiveConnections = task.FTP.ActiveConnections;
                            break;
                        }

                        // Расширения файлов и папок
                        string SyncRemoveFileAddExtension = ".remove";
                        string SyncRemoveFoldersExtension = $".SyncRemove.{DateTime.Now.ToBinary()}";
                        #endregion

                        #region Локальный метод - "GetRemoteFolder"
                        string GetRemoteFolder()
                        {
                            // Удаленный каталог
                            string where = Tools.ConvertPatchToUnix(task.Where);

                            // Локальный каталог
                            string whence = Tools.ConvertPatchToUnix(task.Whence);

                            // Результат
                            return(LocalFolder.Replace(whence, where));
                        }
                        #endregion

                        // Папка на удаленном сервере Linux
                        string RemoteFolder = GetRemoteFolder();

                        // Создаем папку на удаленом сервере
                        serv.CreateDirectory(RemoteFolder, NotReport: true);

                        // Список файлов и папок
                        var ListRemoteServer         = serv.ListDirectoryAndFiles(RemoteFolder);
                        var ListLocalDirectoryToName = Directory.GetDirectories(LocalFolder, "*", SearchOption.TopDirectoryOnly).Select(i => Path.GetFileName(i)).ToList();
                        var ListLocalFilesToName     = Directory.GetFiles(LocalFolder, "*", SearchOption.TopDirectoryOnly).
                                                       Where(dir => !task.IgnoreFileOrFolders.Exists(i => Regex.IsMatch(dir, i.Patch, RegexOptions.IgnoreCase))).
                                                       Select(dir => Path.GetFileName(dir)).ToList();

                        // Модель Tools
                        ToolsModel md = new ToolsModel()
                        {
                            serv = serv,
                            ActiveConnections        = ActiveConnections,
                            LocalFolder              = LocalFolder,
                            RemoteFolder             = RemoteFolder,
                            NewListErrorLocalFolders = NewListErrorLocalFolders
                        };

                        // Переименовывем папки в 'SyncRemoveFoldersExtension' на удаленом сервере - (если их нету на локальном)
                        Tools.RenameToRemoveDirectory(md, ListRemoteServer.Directory, SyncRemoveFoldersExtension);

                        // Переименовывем файлы в 'SyncRemoveFileAddExtension' на удаленом сервере - (если их нету на локальном)
                        Tools.RenameToRemoveFiles(md, ListRemoteServer.Files, SyncRemoveFileAddExtension);

                        // Создаем папки на удаленом сервере - (папки есть на локальном но нету на удаленом сервере)
                        foreach (string createFolder in Tools.CreateToDirectory(md, ListRemoteServer.Directory, ListLocalDirectoryToName, ref CountCreateToDirectoryOk, ref CountCreateToDirectoryAll, ListNewLocalFolders))
                        {
                            // Сохраняем список созданных папок
                            ReportToCreateFolders.WriteLine(createFolder);
                        }

                        // Удаляем файлы которые не до конца загружены
                        Tools.DeleteFilesToErrorUpload(md, ref ListRemoteServer.Files, SyncRemoveFileAddExtension);

                        // Загружаем файлы на удаленный сервер - (если файла нету на сервере)
                        foreach (string uploadFile in Tools.UploadToFiles(md, ListRemoteServer.Files, ListLocalFilesToName, task.EncryptionAES, task.PasswdAES, ref CountUploadToFilesOK, ref CountUploadToFilesAll, ref CountUploadToBytes))
                        {
                            // Сохраняем список загруженных файлов
                            ReportToUploadFiles.WriteLine(uploadFile);
                        }

                        #region Очистка старых бекапов
                        if (task.CountActiveBackup >= 1)
                        {
                            if (task.CountActiveBackup == 1)
                            {
                                // Удаляем все папки и файлы с пометкй "SyncRemoveFoldersExtension или SyncRemoveFoldersExtension"
                                Tools.DeleteFilesOrDirectoryToRemove(md);
                            }

                            // Удаляем старые бекапы
                            Tools.DeleteFilesToActiveBackup(md, task.CountActiveBackup);
                        }

                        // Удаляем старые по времени бекапы
                        if (task.CountActiveDayBackup > 0)
                        {
                            Tools.DeleteFilesToActiveDayBackup(md, task.CountActiveDayBackup);
                        }
                        #endregion

                        #region Обновляем WorkNote
                        WorkNoteNotation.More = new List <More>
                        {
                            new More("Состояние", $"Выполняется {GetToWorkTime("")}"),
                            new More("Проверено объектов", $"{CountToCheckedObject:N0}")
                        };

                        if (CountUploadToFilesOK > 0)
                        {
                            WorkNoteNotation.More.Add(new More("Передано данных", ToSize(CountUploadToBytes)));
                            WorkNoteNotation.More.Add(new More("Загружено файлов", $"{CountUploadToFilesOK:N0}"));
                        }

                        if (CountCreateToDirectoryOk > 0)
                        {
                            WorkNoteNotation.More.Add(new More("Создано папок", $"{CountCreateToDirectoryOk:N0}"));
                        }
                        #endregion
                    }
                }

                // Закрываем потоки
                ReportToCreateFolders.Dispose();
                ReportToUploadFiles.Dispose();

                // Сохраняем новый список папок с ошибками, вместо старого
                File.WriteAllText(PathSyncToErrorLocalFolder, JsonConvert.SerializeObject(NewListErrorLocalFolders));

                #region Локальный метод GetToWorkTime
                string GetToWorkTime(string arg)
                {
                    var WorkTime = (DateTime.Now - TimeStartTask);

                    if (WorkTime.TotalSeconds <= 60)
                    {
                        return("");
                    }

                    if (WorkTime.TotalMinutes <= 60)
                    {
                        return($"{arg}{(int)WorkTime.TotalMinutes} {EndOfText.get("минуту", "минуты", "минут", (int)WorkTime.TotalMinutes)}");
                    }

                    return($"{arg}{(int)WorkTime.TotalHours} {EndOfText.get("час", "часа", "часов", (int)WorkTime.TotalHours)}");
                }
                #endregion

                #region Локальный метод ToSize
                string ToSize(double bytes)
                {
                    string[] Suffix = { "Byte", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
                    int      index  = 0;

                    while (bytes >= 1024)
                    {
                        bytes /= 1024;
                        index++;
                    }

                    return($"{bytes:N3} {Suffix[index]}");
                }
                #endregion

                #region Выполнено
                NameAndValue = new List <More>()
                {
                    new More("Состояние", $"Выполнено {GetToWorkTime("за ")}"),
                    new More("Проверено объектов", $"{CountToCheckedObject:N0}")
                };

                if (CountCreateToDirectoryAll > 0)
                {
                    NameAndValue.Add(new More("Создано папок", $"<a href='/reports/sync/{ReportNameToCreateFolders}' target='_blank'>{CountCreateToDirectoryOk:N0} из {CountCreateToDirectoryAll:N0}</a>"));
                }

                if (CountUploadToFilesAll > 0)
                {
                    NameAndValue.Add(new More("Загружено файлов", $"<a href='/reports/sync/{ReportNameToUploadFiles}' target='_blank'>{CountUploadToFilesOK:N0} из {CountUploadToFilesAll:N0}</a>"));
                    NameAndValue.Add(new More("Передано данных", ToSize(CountUploadToBytes)));
                }
                #endregion

                IsOk = true;
            }
            catch (Exception ex)
            {
                NameAndValue = new List <More>()
                {
                    new More("Состояние", "Ошибка при выполнении задания"),
                    new More("Код", ex.ToString())
                };
            }

            // Отключаемся от сервера
            serv.Disconnect();
        }
コード例 #2
0
        /// <summary>
        /// Восстановить данные
        /// </summary>
        /// <param name="task">Задания</param>
        /// <param name="serv">Удаленный сервер</param>
        /// <param name="WorkNoteNotation">Текущее задание в WorkNote</param>
        /// <param name="NameAndValue">Колекция для ответа в журнал</param>
        /// <param name="typeRecovery">Режим востановления файлов</param>
        /// <param name="DateRecovery">Отметка бекапа для востановления по дате</param>
        public static void Recovery(Models.SyncBackup.Tasks.Task task, RemoteServer serv, Notation WorkNoteNotation, out List <More> NameAndValue, TypeRecovery typeRecovery, DateTime DateRecovery)
        {
            try
            {
                #region Переменные
                // Список папок которые нужно пропустить
                var ListSkipFolders = new List <string>();

                // Время старта задания
                var TimeStartTask = DateTime.Now;

                // Количиство загруженых файлов и созданых папок
                int CountDownloadToFilesOK = 0, CountDownloadToFilesAll = 0, CountCreateToDirectoryOk = 0;

                // Общий размер загруженых файлов в byte
                long CountDownloadToBytes = 0;
                #endregion

                #region Получаем список всех папок
                var RemoteFolders = new List <DirectoryModel>();
                RemoteFolders.Add(new DirectoryModel()
                {
                    Folder             = task.Where,
                    RemoteCreated      = default(DateTime),
                    RemoteLastModified = DateTime.Now,
                });
                serv.ListAllDirectory(task.Where, ref RemoteFolders);
                #endregion

                // Проходим список всех папок
                foreach (var RemoteFolder in RemoteFolders)
                {
                    // Папки и их подпапки которые не нужно восстанавливать
                    if (ListSkipFolders.Exists(i => RemoteFolder.Folder.Contains(i)))
                    {
                        continue;
                    }

                    // Пропускаем удаленые папки
                    if (typeRecovery == TypeRecovery.Topical && RemoteFolder.Folder.Contains(".SyncRemove"))
                    {
                        continue;
                    }

                    #region Локальный метод - "GetLocalFolder"
                    string GetLocalFolder()
                    {
                        // Удаленный каталог
                        string where = ConvertPatchToUnix(task.Where);

                        // Локальный каталог
                        string whence = ConvertPatchToUnix(task.Whence);

                        // Результат
                        return(RemoteFolder.Folder.Replace(where, whence));
                    }
                    #endregion

                    // Локальная дириктория
                    string LocalFolder = GetLocalFolder();

                    #region Востановление по дате
                    if (typeRecovery == TypeRecovery.Date)
                    {
                        if (RemoteFolder.Folder.Contains(".SyncRemove"))
                        {
                            // Если дата модификации папки ниже отметки
                            if (RemoteFolder.RemoteLastModified < DateRecovery)
                            {
                                ListSkipFolders.Add(RemoteFolder.Folder);
                                continue;
                            }
                        }
                        else
                        {
                            // Если дата создания папки выше отметки
                            if (RemoteFolder.RemoteCreated > DateRecovery)
                            {
                                ListSkipFolders.Add(RemoteFolder.Folder);
                                continue;
                            }
                        }

                        // Удаляем 'SyncRemove' в 'LocalFolder'
                        LocalFolder = Regex.Replace(LocalFolder, @"\.SyncRemove\.-[0-9]+", "");
                    }
                    #endregion

                    // Создаем локальную папку
                    Directory.CreateDirectory(LocalFolder);
                    CountCreateToDirectoryOk++;

                    // Количиство потоков
                    int ActiveConnections = task.TypeSunc == TypeSunc.SFTP ? task.FTP.ActiveConnections : 1;

                    #region Загружаем файлы на локальный сервер
                    Parallel.ForEach(SortedFiles(serv.ListDirectoryAndFiles(RemoteFolder.Folder).Files, SortedToLocalTime: false), new ParallelOptions {
                        MaxDegreeOfParallelism = ActiveConnections
                    }, RemoteData =>
                    {
                        if (typeRecovery == TypeRecovery.Date)
                        {
                            // Ищем файл который ближе всего подходит к отметки бекапа
                            if (RemoteData.Value.FirstOrDefault(i => i.RemoteCreated < DateRecovery) is SortedModel item)
                            {
                                // Загружаем файл который подходит по дате
                                DownloadFile(item, RemoteData.Key);
                            }
                        }
                        else
                        {
                            // Загружаем актуальный файл
                            DownloadFile(RemoteData.Value[0], RemoteData.Key);

                            // Загружаем бекапы
                            if (typeRecovery == TypeRecovery.all)
                            {
                                // Пропускаем актуальный файл и загружаем остальные
                                foreach (var RemoteFile in RemoteData.Value.Skip(1))
                                {
                                    // Загружаем файл
                                    DownloadFile(RemoteFile, RemoteFile.Name.Replace(".sync.aes.", ".sync."));
                                }
                            }
                        }
                    });
                    #endregion

                    #region Обновляем WorkNote
                    if (CountDownloadToFilesOK > 0)
                    {
                        WorkNoteNotation.More = new List <More>
                        {
                            new More("Состояние", $"Выполняется {GetToWorkTime("")}"),
                            new More("Загружено файлов", $"{CountDownloadToFilesOK:N0}"),
                            new More("Получено данных", ToSize(CountDownloadToBytes))
                        };
                    }
                    #endregion

                    #region Локальный метод DownloadFile
                    void DownloadFile(FileModel RemoteFile, string LocalFileName)
                    {
                        // Пропускаем удаленые файлы
                        if (typeRecovery == TypeRecovery.Topical && RemoteFile.Name.Contains(".remove") || RemoteFile.FileSize < 1)
                        {
                            return;
                        }

                        // Пути к файлам
                        string LocalFilePatch  = LocalFolder + LocalFileName;
                        string RemoteFilePatch = (RemoteFolder.Folder + "/" + RemoteFile.Name).Replace("//", "/");

                        // Проверяем на существование файла
                        if (!task.EncryptionAES && File.Exists(LocalFilePatch) && (new FileInfo(LocalFilePatch)).Length == RemoteFile.FileSize)
                        {
                            return;
                        }

                        int CountReDownload = 0;

                        // Загружаем удаленый файл в локальную папку
                        ReDownloadFile : if (serv.DownloadFile(LocalFilePatch, RemoteFilePatch, task.EncryptionAES, task.PasswdAES, RemoteFile.FileSize))
                        {
                            CountDownloadToFilesOK++;
                            CountDownloadToBytes += RemoteFile.FileSize;
                        }
                        else
                        {
                            if (++CountReDownload < 3)  // 3 попытки что-бы загрузить файл
                            {
                                goto ReDownloadFile;
                            }
                        }

                        CountDownloadToFilesAll++;
                    }
                    #endregion
                }

                #region Локальный метод GetToWorkTime
                string GetToWorkTime(string arg)
                {
                    var WorkTime = (DateTime.Now - TimeStartTask);

                    if (WorkTime.TotalSeconds <= 60)
                    {
                        return("");
                    }

                    if (WorkTime.TotalMinutes <= 60)
                    {
                        return($"{arg}{(int)WorkTime.TotalMinutes} {EndOfText.get("минуту", "минуты", "минут", (int)WorkTime.TotalMinutes)}");
                    }

                    return($"{arg}{(int)WorkTime.TotalHours} {EndOfText.get("час", "часа", "часов", (int)WorkTime.TotalHours)}");
                }
                #endregion

                #region Локальный метод ToSize
                string ToSize(double bytes)
                {
                    string[] Suffix = { "Byte", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
                    int      index  = 0;

                    while (bytes >= 1024)
                    {
                        bytes /= 1024;
                        index++;
                    }

                    return($"{bytes:N3} {Suffix[index]}");
                }
                #endregion

                #region Выполнено
                NameAndValue = new List <More>()
                {
                    new More("Состояние", $"Выполнено {GetToWorkTime("за ")}")
                };

                if (CountCreateToDirectoryOk > 0)
                {
                    NameAndValue.Add(new More("Создано папок", $"{CountCreateToDirectoryOk:N0}"));
                }

                if (CountDownloadToFilesAll > 0)
                {
                    NameAndValue.Add(new More("Загружено файлов", $"{CountDownloadToFilesOK:N0} из {CountDownloadToFilesAll:N0}"));
                    NameAndValue.Add(new More("Получено данных", ToSize(CountDownloadToBytes)));
                }
                #endregion
            }
            catch (Exception ex)
            {
                NameAndValue = new List <More>()
                {
                    new More("Состояние", "Ошибка при выполнении задания"),
                    new More("Код", ex.ToString())
                };
            }

            // Отключаемся от сервера
            serv.Disconnect();
        }
コード例 #3
0
ファイル: Access.cs プロジェクト: vincenthfrance/ISPCore
        public JsonResult Open(string host, string IP, int AccessTimeToMinutes, AccessType accessType)
        {
            #region Демо режим
            if (Platform.IsDemo)
            {
                return(Json(new Modal("Операция недоступна в демо-режиме")));
            }
            #endregion

            // Проверка IP
            if (string.IsNullOrWhiteSpace(IP) || (!IP.Contains(".") && !IP.Contains(":")) || (IP.Contains(".") && !Regex.IsMatch(IP, @"^[0-9]+\.[0-9]+\.[0-9]+\.([0-9]+|\*)$")))
            {
                return(Json(new Modal("Поле 'IP-адрес' имеет недопустимое значение")));
            }

            // ППроверка домена
            if (accessType != AccessType.allDomain && string.IsNullOrWhiteSpace(host))
            {
                return(Json(new Modal("Поле 'Домен' не может быть пустым")));
            }

            // Коректор времени
            if (AccessTimeToMinutes <= 0)
            {
                AccessTimeToMinutes = 2160;
            }

            // Достаем IMemoryCache
            var memoryCache = Service.Get <IMemoryCache>();

            // Добавляем данные в список разрешенных IP, для вывода информации и отмены доступа
            AccessIP.Add(IP, accessType == AccessType.allDomain ? "все домены" : host, DateTime.Now.AddMinutes(AccessTimeToMinutes), accessType);

            // IP для кеша
            string ipCache = IP.Replace(".*", "").Replace(":*", "");

            // Добовляем IP в белый список
            switch (accessType)
            {
            case AccessType.all:
                memoryCache.Set(KeyToMemoryCache.CheckLinkWhitelistToAll(host, ipCache), (byte)1, TimeSpan.FromMinutes(AccessTimeToMinutes));
                break;

            case AccessType.Is2FA:
                memoryCache.Set(KeyToMemoryCache.CheckLinkWhitelistTo2FA(host, ipCache), (byte)1, TimeSpan.FromMinutes(AccessTimeToMinutes));
                break;

            case AccessType.allDomain:
                memoryCache.Set(KeyToMemoryCache.CheckLinkWhitelistToAllDomain(ipCache), (byte)1, TimeSpan.FromMinutes(AccessTimeToMinutes));
                break;
            }

            // Отдаем ответ
            return(Json(new Modal($"Разрешен доступ для '{IP}' на {AccessTimeToMinutes} {EndOfText.get("минуту", "минуты", "минут", AccessTimeToMinutes)}", true)));
        }