Урок: Сортировка фотографий
В этом уроке мы разберем приложение, которое сортирует фотографии по папкам Год/Месяц. Например, если мы скинули фотографии с телефона на диск и хотим их разобрать по датам создания.
Подготовка
Наш сортировщик фотографий это консольное приложение, которое на вход будет получать папку с фотографиями и папку куда надо размещать отсортированные фотографии. Эти два параметра будут считываться из командной строки.
Параметры командной строки можно получить из глобальной переменной АргументыКоманднойСтроки
, однако, мы воспользуемся готовой библиотекой cli
, которая позволяет легко и быстро создавать консольные приложения, получающие параметры из аргументов командной строки. Эта библиотека автоматически формирует справку по параметрам, парсит входящие аргументы, проверяет их корректность.
Установим эту библиотеку:
opm install cli
Также, нам потребуется библиотека работы с файловой системой fs
и библиотека отображения прогресса работы progbar
opm install fs
opm install progbar
Создадим файл скрипта sorter.os
и откроем его в VS Code.
Создание точки входа
Любой модуль 1Скрипт, также, как в 1С начинается с нижней части файла. Мы разместим там вызов единственной функции, которая выполняет всю работу и вызов этой функции обернем в попытку, чтобы обработать исключения, которые могут возникнуть в процессе работы.
#Использовать cli
#Использовать fs
#Использовать progbar
Попытка
ВыполнитьПриложение();
Исключение
Сообщить(ОписаниеОшибки());
ЗавершитьРаботу(1); // Вернем код ошибки операционной системе
КонецПопытки;
Создание обработчика
Теперь, нам нужно будет создать экспортную процедуру ВыполнитьКоманду
. Эта процедура будет вызвана библиотекой cli в случае, если указаны корректные параметры командной строки. В этой процедуре мы впоследствии разместим полезную нагрузку.
Процедуры по правилам синтаксиса должны располагаться над блоком инициализации и после секции импортов и переменных.
#Использовать cli
#Использовать fs
#Использовать progbar
Процедура ВыполнитьПриложение()
// Точка входа
КонецПроцедуры
Процедура ВыполнитьКоманду(Знач Команда) Экспорт
// Полезная нагрузка
Сообщить("Выполнено");
КонецПроцедуры
Попытка
ВыполнитьПриложение();
Исключение
Сообщить(ОписаниеОшибки());
ЗавершитьРаботу(1); // Вернем код ошибки операционной системе
КонецПопытки;
Настройка парсера аргументов
Заготовка приложения готова, но оно ничего не делает. Для того, чтобы оно научилось получать аргументы из командной строки, необходимо настроить библиотеку CLI на задуманные нами аргументы (2 строки с путями). Эта настройку нужно разместить в процедуре ВыполнитьПриложение
.
Процедура ВыполнитьПриложение()
// Создадим описатель приложения. Класс "КонсольноеПриложение" предоставлен библиотекой CLI
Приложение = Новый КонсольноеПриложение("Sorter", "Помощник генерации приложения на основании шаблона cli");
Приложение.Версия("v version", "1.0.0");
// Расскажем парсеру, что нам надо на вход принять 2 строковых параметра.
// Для каждого параметра зададим имя и строку справки,
// которую будет видеть пользователь.
Приложение.Аргумент("INPUT", "", "Путь входного каталога").ТСтрока();
Приложение.Аргумент("OUTPUT", "", "Путь выходного каталога").ТСтрока();
// Укажем сами себя в качестве обработчика командной строки
// (для этого нам и была нужна экспортная процедура ВыполнитьКоманду)
Приложение.УстановитьОсновноеДействие(ЭтотОбъект);
// Стартуем консольное приложение
Приложение.Запустить(АргументыКоманднойСтроки);
КонецПроцедуры
Проверка
Давайте запустим наше приложение без аргументов и посмотрим, что получается:
oscript sorter.os
Приложение: Sorter
Помощник генерации приложения на основании шаблона cli
Строка запуска: Sorter [ОПЦИИ] INPUT OUTPUT
Аргументы:
INPUT Путь входного каталога
OUTPUT Путь выходного каталога
Опции:
-v, --version показать версию и выйти
Библиотека CLI определила, что мы не передали ни одного параметра командной строки, значит, это ошибка, поэтому она автоматичски сформировала справку о том, как надо запускать наше приложение и вывела справку на экран.
Теперь, попробуем указать два аргумента командной строки и посмотрим, что получится:
oscript sorter.os arg1 arg2
Выполнено
По наличию строки "Выполнено" видим, что отработала процедура ВыполнитьКоманду
, которая содержит полезную нагрузку приложения.
Полезная нагрузка
Займемся, наконец, непосредственно сортировкой фотографий. Возьмем все файлы, которые найдем во входном каталоге и составим таблицу значений по месяцам создания файлов. Для отображения прогресса сортировки также подготовим переменную ПрогрессБар
, которую предоставляет библиотека progbar
.
Процедура ВыполнитьКоманду(Знач Команда) Экспорт
ИсходныйПуть = Команда.ЗначениеАргумента("INPUT");
ВыходнойПуть = Команда.ЗначениеАргумента("OUTPUT");
ПрогрессБар = Новый ПрогрессБар();
ВсеФайлы = НайтиФайлы(ИсходныйПуть, ПолучитьМаскуВсеФайлы(), Ложь);
Таблица = Новый ТаблицаЗначений();
Таблица.Колонки.Добавить("Ключ", Новый ОписаниеТипов("Дата"));
Таблица.Колонки.Добавить("Год");
Таблица.Колонки.Добавить("ГодМесяц");
Таблица.Колонки.Добавить("Файл");
Сообщить("Сортирую файлы");
ШагиПрогресса = Новый Соответствие();
Для Каждого Файл Из ВсеФайлы Цикл
ДатаФайла = Файл.ПолучитьВремяИзменения();
СтрФайл = Таблица.Добавить();
СтрФайл.Год = Формат(ДатаФайла, "ДФ='гггг'");
СтрФайл.ГодМесяц = Формат(ДатаФайла, "ДФ='MMММ гггг'");
СтрФайл.Ключ = НачалоМесяца(ДатаФайла);
СтрФайл.Файл = Файл;
ШагиПрогресса.Вставить(СтрФайл.ГодМесяц);
КонецЦикла;
Таблица.Сортировать("Ключ");
КонецПроцедуры
Теперь, для каждого месяца выполним перемещение файла в каталог Год/МесяцГода
// Инициализация прогрессбара общим числом шагов
ПрогрессБар.Начать(ШагиПрогресса.Количество());
Попытка
ТекущийКлюч = Неопределено;
Для Каждого СтрФайл Из Таблица Цикл
Если СтрФайл.Ключ <> ТекущийКлюч Тогда
// Можно переходить к очередному месяцу
ПрогрессБар.СделатьШаг(,, СтрФайл.ГодМесяц);
ТекущийКлюч = СтрФайл.Ключ; // Запомним текущий месяц
КонецЕсли;
// Сформируем конечный путь для файлов данного месяца
ЦелевойКаталог = ОбъединитьПути(ВыходнойПуть, СтрФайл.Год, СтрФайл.ГодМесяц);
// Метод библиотеки ФС обеспечит существование каталога (создаст его, если не было)
ФС.ОбеспечитьКаталог(ЦелевойКаталог);
// Выполняем перемещение
ПереместитьФайл(СтрФайл.Файл.ПолноеИмя, ОбъединитьПути(ЦелевойКаталог, СтрФайл.Файл.Имя));
КонецЦикла;
Исключение
ПрогрессБар.Завершить();
ВызватьИсключение;
КонецПопытки;
ПрогрессБар.Завершить();
Проверка результата
Подготовим каталог с фотографиями и пустой каталог, в который надо поместить отсортированные фотографии. Запустим наш сортер
oscript sorter.os C:/input_dir D:/output_dir
После завершения работы все файлы будут размещены в папке D:/output_dir по каталогам <Год>, внутри которого будут папки <Месяц года>