Небольшой сервис, который парсит производственный календарь сайтов Консультант или SuperJob и предоставляет REST API.
Запуск:
docker run --name cal -p 80:80 -d ghcr.io/nvkalinin/business-calendar server
Запросы к календарю:
curl localhost/api/cal/2022
curl localhost/api/cal/2022/05
curl localhost/api/cal/2022/05/01
Пример ответа на запрос к конкретной дате:
{
"weekDay": "sun",
"working": false,
"type": "holiday",
"desc": "Праздник Весны и Труда"
}
Для доступа по протоколу HTTPS нужно настроить обратный прокси-сервер.
Через REST API доступны календари только за те годы, для которых
была запущена синхронизация (описано далее). Если синхронизацию не
запускали, то сервис возвращает ответ 404 Not Found
для всего года.
Синхронизация одного года включает слияние данных из трех источников:
- Generic — генерирует календарь, в котором пн-пт являются рабочими, сб-вс — выходными; источник используется всегда как основа календаря и отключить его нельзя.
- Consultant или SuperJob — опциональный парсер внешнего календаря.
- Override — опциональный YAML-файл с локальными переопределениями календаря.
Доступно два парсера: Консультант и SuperJob.
Настроить парсер можно через аргумент командной строки
--source.parser=consultant|superjob|none
. То же самое можно
сделать через переменную окружения SOURCE_PARSER
.
Оба парсера делают одно и то же, но есть различия в данных, которые они поставляют:
- Консультант отмечает нерабочие дни, SuperJob — нет;
- Консультант отмечает праздники с учетом переносов (пример: 1 мая — выходной, 2 и 3 мая — праздники), SuperJob — нет (пример: 1 мая — праздник, 2 и 3 мая — выходные);
- SuperJob заполняет названия праздников (поле
desc
), Консультант — нет.
Возможны и другие различия.
Оба парсера предоставляют данные с 2014 года.
С помощью аргумента командной строки --source.override=file.yml
или переменной окружения SOURCE_OVERRIDE
можно указать путь
к YAML-файлу с переопределениями календаря.
Пример, файла:
2022:
11:
# Мечты КПРФ :-)
4: {type: normal, working: true, desc: ''}
7: {type: holiday, working: false, desc: 'День Великой Октябрьской социалистической революции'}
Для каждого дня можно указать следующие параметры:
weekDay
— день недели (указать можно, но практического смысла нет, так как значение берется из источника Generic), перечисление:mon
,tue
,wed
,thu
,fri
,sat
,sun
;
working
(bool
) — рабочий день или нет;type
— тип дня, перечисление:normal
— обычный рабочий день,weekend
— обычный выходной день,preHoliday
— предпраздничный день,holiday
— праздничный день,noWork
— нерабочий день;
desc
(string
) — текстовое описание дня.
Обязательным, фактически, является только working
. Если этот параметр
не указан, то подразумевается значение false
.
Прежде чем календари станут доступны через REST API, нужно запустить синхронизацию для каждого года, который нужен. Есть несколько способов это сделать.
По-умолчанию, при запуске сервиса запускается синхронизация текущего и следующего года.
Это можно изменить с помощью аргумента командной строки:
cal server \
--sync-on-start=2022 \
--sync-on-start=current \
--sync-on-start=next
Чтобы отключить синхронизацию при запуске:
cal server --sync-on-start=none
Можно использовать переменную окружения SYNC_ON_START
, значения
нужно указывать через запятую.
Сервис может ежедневно выполнять синхронизацию в указанное время:
cal server --sync-at=hh:mm[:ss]
То же самое можно настроить через переменную окружения SYNC_AT
.
Часовой пояс можно указать через переменную окружения TZ
.
Если требуется синхронизация по другому расписанию, используйте свой планировщик и команду, описанную далее.
Команду можно выполнить двумя способами.
Через CLI:
docker exec -it <container> cal sync -y2022 -y2023
Через REST API:
curl -u 'admin:<passwd>' 'localhost/api/admin/sync?y=2022&y=2023'
Пароль можно задать при запуске сервера (описано далее).
В ходе синхронизации, после слияния данных всех источников получившийся календарь записывается в хранилище. REST API возвращает данные только из хранилища.
Указать тип хранилища можно с помощью аргумента командной строки
--store.engine=bolt|memory
, либо переменной окружения STORE_ENGINE
.
По-умолчанию используется Bolt.
Все данные хранятся в файле.
Рекомендуется монтировать каталог в контейнер.
Указать путь к файлу БД можно с помощью аргумента командной строки
--store.bolt.file=/data/cal.bolt
, либо через переменную окружения
STORE_BOLT_FILE
.
Для данного типа хранилища доступно резервное копирование данных.
Резервное копирование через CLI:
docker exec -it <container> cal backup
По-умолчанию бекап сохраняется в файл cal_YYYY-MM-DD.bolt.gz
.
Можно указать -o <path>
для сохранения по другому пути, либо
-o -
для вывода резервной копии в stdout.
Резервное копирование через REST API:
curl -u 'admin:<passwd>' 'localhost/api/admin/backup'
Данные хранятся в оперативной памяти. В отличие от Bolt, после перезапуска сервера придется заново выполнить синхронизацию всех календарей.
Хост и порт, на котором веб-сервер принимает соединения можно указать
с помощью аргумента командной строки --web.listen=host:port
, либо
через переменную окружения WEB_LISTEN
.
Можно ограничить количество запросов с одного IP-адреса за период времени.
Если используется обратный прокси, убедитесь, что он корректно
заполняет заголовок X-Forwarded-For
.
Аргументы командной строки:
--web.ratelim.reqs
— Количество запросов с одного IP. Если 0 — rate limiter отключен.--web.ratelim.window
— Интервал времени, за который разрешено указанное кол-во запросов, например:10s
,1m
.
Можно также использовать переменные окружения: *
WEB_RATE_LIM_REQS
WEB_RATE_LIM_WINDOW
По-умолчанию, включено ограничение 100 запросов в секунду.
Доступ к /api/admin
должен быть защищен паролем, если доступ
к сервису будет разрешен кому-либо, кроме других ваших сервисов.
Задать пароль можно через аргумент командной строки
--web.admin-passwd=<passwd>
или переменную окружения
WEB_ADMIN_PASSWD
.
По-умолчанию задан пустой пароль.
Полный список параметров можно получить с помощью команды:
docker exec <container> cal server --help