Exemplo n.º 1
0
        /// <summary>
        /// Подготовка к копированию. Сбор сведений.
        /// </summary>
        public void Prepare(Dispatcher DGUI, ProjectItemIn projectSettings, DirInfoModel infoModel, Status status)
        {
            DGUI.BeginInvoke(() =>
            {
                status.IsError = false;
                status.Message = "Подготовка..";
                infoModel.OnPreparing();
            }, DispatcherPriority.Normal);
            //+ checks
            if (projectSettings == null)
            {
                DGUI.BeginInvoke(() =>
                {
                    status.IsError       = true;
                    status.Message       = "Укажите проект";
                    infoModel.CanPrepare = true;
                });
                return;
            }
            if (String.IsNullOrWhiteSpace(projectSettings.DirFrom))
            {
                DGUI.BeginInvoke(() =>
                {
                    status.IsError       = true;
                    status.Message       = "Укажите путь к источникам";
                    infoModel.CanPrepare = true;
                });
                return;
            }
            if (String.IsNullOrWhiteSpace(projectSettings.DirTo))
            {
                DGUI.BeginInvoke(() =>
                {
                    status.IsError       = true;
                    status.Message       = "Укажите путь назначения";
                    infoModel.CanPrepare = true;
                });
                return;
            }
            var       dirUtils   = new DirectoryUtils();
            var       totalFiles = 0;
            Stopwatch stopWatch  = new Stopwatch();

            stopWatch.Start();
            var             filePrepareIndex = 0;
            Action <String> onCheckFn        = (d) =>
            {
                TimeSpan ts = stopWatch.Elapsed; //? а точно ли в этом потоке замер времени останалвивать?
                DGUI.BeginInvoke(() =>
                {
                    status.Message = String.Format("Подготовка (шаг 1).. {0} ({1:00}:{2:00}:{3:00}) -> {4}", ++filePrepareIndex, ts.Hours, ts.Minutes, ts.Seconds, d);
                });
            };
            //+ 1. ищем все папки для работы (исходящие)
            var dirsIgnore = dirUtils.SearchDirs(StringUtils.StringSplitNewLines(projectSettings.DirFromIgnore), null, onCheckFn); //, Conventions.DirSeparatorStr);
            var dirs       = dirUtils.SearchDirs(StringUtils.StringSplitNewLines(projectSettings.DirFrom), dirsIgnore, onCheckFn); //, Conventions.DirSeparatorStr);

            //+ 2. собираем все файлы (с их полными путями) для копирования
            var             filePrepareTwoIndex = 0;
            Action <String> onCheckFilesFn      = (f) =>
            {
                TimeSpan ts = stopWatch.Elapsed; //? а точно ли в этом потоке замер времени останалвивать?
                DGUI.BeginInvoke(() =>
                {
                    status.Message = String.Format("Подготовка (шаг 2).. {0} ({1:00}:{2:00}:{3:00}) -> {4}", ++filePrepareTwoIndex, ts.Hours, ts.Minutes, ts.Seconds, f);
                });
            };
            var files = dirUtils.SearchFiles(dirs, onCheckFilesFn);

            totalFiles = files.Count;

            //+ 3. ищем среди имеющихся по назначению уже точно такие-же (если нет таких файлов или новые, то отдаем в работу) - ради чего все и затеялось
            var dirFromStr = projectSettings.DirFrom;

            if (dirFromStr.EndsWith(Conventions.DirSubdirSymbol))
            {
                dirFromStr = dirFromStr.Remove(dirFromStr.Length - 1);
            }
            var fileIndex = 0;

            foreach (var file in files)
            {
                TimeSpan ts = stopWatch.Elapsed; //? а точно ли в этом потоке замер времени останалвивать?
                DGUI.BeginInvoke(() =>
                {
                    status.Message = String.Format("Подготовка (шаг 3).. {0}/{1} ({2:00}:{3:00}:{4:00})", ++fileIndex, totalFiles, ts.Hours, ts.Minutes, ts.Seconds);
                });
                if (String.IsNullOrWhiteSpace(file))
                {
                    continue;
                }
                if (!file.StartsWith(dirFromStr))
                {
                    continue;                               //- странно
                }
                //- приводим к пути назначению
                var fileOut = String.Format("{0}\\{1}", projectSettings.DirTo, file.Remove(0, dirFromStr.Length));
                fileOut = fileOut.Replace("\\\\", "\\"); //? to regexp (учесть не только двойные слэши, но и множественные?)
                // NOTE: метод "infoModel.AddFile()" может не лучший по оптимизации для TreeView
                // NOTE: возможно, для TreeView делать разовую обновку быстрее, чем на каждом файле
                //- если новый, то точно копируем
                if (!dirUtils.ExistsFile(fileOut))
                {
                    DGUI.BeginInvoke(() =>
                    {
                        infoModel.AddFile(file, fileOut, true, DirTreeViewItemModelStatus.Normal, String.Empty);
                    });
                }
                //- если уже есть такой, то смотрим своим алгоритмом - вся суть приложения
                else
                {
                    var isFileInWork = false;
                    try
                    {
                        isFileInWork = IsFileForReplaceAlgo(file, fileOut, projectSettings, dirUtils);
                    }
                    catch (Exception ex)
                    {
                        // некоторая ошибка при сравнении файлов (возможно, не смогли сверить контент)
                        DGUI.BeginInvoke(() =>
                        {
                            infoModel.Errors.Add(ex.Message);
                            infoModel.AddFile(file, fileOut, false, DirTreeViewItemModelStatus.Error, ex.Message);
                        });
                    }

                    if (isFileInWork)
                    {
                        DGUI.BeginInvoke(() =>
                        {
                            infoModel.AddFile(file, fileOut, false, DirTreeViewItemModelStatus.Normal, String.Empty);
                        });
                    }
                }
            }
            stopWatch.Stop();

            //+ end (summary)
            DGUI.BeginInvoke(() =>
            {
                infoModel.TotalFilesFrom  = totalFiles;
                infoModel.CanWork         = infoModel.Items.Any(); // files.Any(); // TODO: в идеале проверить не отмененные файлы и директории
                infoModel.CanPrepare      = true;
                infoModel.ErrorsFilesFrom = infoModel.Errors.Count();
                if (infoModel.ErrorsFilesFrom > 0)
                {
                    status.IsError = true;
                    status.Message = String.Format("Подготовка завершена с ошибками (ошибок: {0})", infoModel.ErrorsFilesFrom);
                }
                else
                {
                    status.Message = "Подготовка завершена";
                }
            });
        }