Импорт папок cо вложенными папками и файлами

Рассмотрим случай, когда необходимо добавить каталог (папку, директорию) с подкаталогами и файлами из операционной системы в хранилище документов ELMA. Реализуем этот функционал с помощью процесса.

При запуске процесса необходимо указать входные параметры:

Самый простой способ реализации алгоритма при добавлении папок – использовать рекурсию и реализовать всё в одном сценарии. Но этот вариант нам не подходит, т.к. может сработать ограничение - 10 минутный таймаут при выполнении сценария. Для этого делим логику процесса на 3 отдельных сценария: инициализация, добавление папки и добавление файлов из текущей папки.

В инициализации получаем список всех папок, содержащихся в указанной папке «Папка откуда» и создаём корневую папку и документы типа Файл, в версиях которых сохраняем файлы. Затем перебором создаём папки и файлы из них, отслеживая возможные ошибки с помощью специальной задачи.

Количество папок не ограничено (кроме размера свободного места в папке на сервере ELMA, где хранятся файлы).

Вы можете доработать процесс и добавить следующий функционал самостоятельно:

  • возможность указывать маску, по которой будут фильтроваться файлы;
  • возможность указывать и добавлять вложенные каталоги.

Или доработать любую логику при добавлении папок в систему ELMA: расфасовать по разным папкам, типам документов и т.п..

Сам процесс может быть импортирован из приложенного файла.

Текст сценария:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

using EleWise.ELMA.API;
using EleWise.ELMA.Documents.Models;
using EleWise.ELMA.Files;
using EleWise.ELMA.Logging;
using EleWise.ELMA.Model.Common;
using EleWise.ELMA.Model.Entities;
using EleWise.ELMA.Model.Entities.ProcessContext;
using EleWise.ELMA.Model.Managers;
using EleWise.ELMA.Model.Services;
using EleWise.ELMA.Model.Types.Settings;
using EleWise.ELMA.Runtime.Managers;
using EleWise.ELMA.Services;
using Context = EleWise.ELMA.Model.Entities.ProcessContext.P_ImportPapok;

 

namespace EleWise.ELMA.Model.Scripts
{
    
    /// <summary>
    /// Модуль сценариев процесса "Импорт папок"
    /// </summary>
    public partial class P_ImportPapok_Scripts : EleWise.ELMA.Workflow.Scripts.ProcessScriptBase<Context>
    {
        // Класс для хранения соответствия полного пути к папке и папки в Элма
        private class FolderMap
        {
            public string FullName;
            public Folder ElmaFolder;
        }
        static String[] allfiles = null; // массив путей к каталогам
        
  
        static List<FolderMap> folderMap = new List<FolderMap>(); // список соответствий
        public void Init(Context context)
        {
            // получить список папок
            allfiles =  System.IO.Directory.GetDirectories(context.PapkaOtkuda, "*",System.IO.SearchOption.AllDirectories);
            context.Kol = allfiles.Count();
             context.Current = 0;
            context.CurrentElmaFolder = context.PapkaKuda;
            CreateFolderAtom(context, context.CurrentElmaFolder, context.PapkaOtkuda); // перенос корневого каталога
            CreateFilesAtom(context, context.PapkaOtkuda); // перенос файлов из корневого каталога
        }
        // метод создаёт папку в Элма
        public void CreateFolder(Context context)
        {
            // поиск родительской папки
            Folder folder = GetCurrentFolderElma(context, allfiles[(int)context.Current]);
            Logger.Log.Error(folder.Name);
            // создание каталога в Элме
            CreateFolderAtom(context, folder, allfiles[(int)context.Current]);
        }
        // перенос файлов в Элму из текущего каталога
        public void CreateFiles(Context context)
        {
            CreateFilesAtom(context, allfiles[(int)context.Current]);
            context.Current++;  
        }
        // Создание файлов в Элме из текущего каталога
        public void CreateFilesAtom(Context context, string pathToFiles)
        {
            DirectoryInfo di = new DirectoryInfo(pathToFiles+"\\");            
            foreach (var element in di.GetFiles("*",SearchOption.TopDirectoryOnly)) {
                Logger.Log.Error(element.Name);
                CreateFileAtom(context, context.CurrentElmaFolder, element.FullName);
            }            

        }
        
        // возвращает родительскую папку в Элме для указанного FullFolderName
        public Folder GetCurrentFolderElma(Context context, string FullFolderName)
        {
            Folder folder = context.PapkaKuda;
            string path = Path.GetDirectoryName(FullFolderName);
            foreach (var element in folderMap) {
                if (element.FullName == path)
                    return PublicAPI.Docflow.Folder.Load(element.ElmaFolder.Id);
            }
            return folder;
        }
        // Создание папки в Элме
        public void CreateFolderAtom(Context context, Folder folderParent, string folderSystem)
        {
            Logger.Log.Error(folderSystem);
                       
            string lastFolderName = Path.GetFileName( folderSystem );
               Logger.Log.Error(lastFolderName);
               Folder folder =  PublicAPI.Docflow.Folder.CreateFolder(folderParent,lastFolderName,true,false);
             folder.Save();
             context.CurrentElmaFolder = PublicAPI.Docflow.Folder.Load(folder.Id);
            FolderMap fm = new FolderMap();
            fm.FullName = folderSystem;
            fm.ElmaFolder = context.CurrentElmaFolder;
            folderMap.Add(fm);
            Logger.Log.Error(context.Current.ToString()+":"+fm.FullName + "+++" + fm.ElmaFolder.Name);
        }
        
        public void CreateFileAtom(Context context, Folder folderParent, string filename)
        {
            // создание системного файла в Элме
            context.File = InterfaceActivator.Create<BinaryFile>();
            context.File.Name = Path.GetFileName(filename);
            context.File.CreateDate = DateTime.Now;
            context.File.InitializeContentFilePath();
            System.IO.File.Copy(filename, context.File.ContentFilePath); // копирование файла из операционной системы
            Locator.GetServiceNotNull<IFileManager>().SaveFile(context.File); // сохранить файл в Элма
            // создание документа типа File в Элма
            var doc = PublicAPI.Docflow.Types.File.Create(context.File, folderParent, context.File.Name );
            doc.Save();
        }    

    }

}

 

Прикрепленные файлы