github.com/nvkalinin/business-calendar@v1.0.2-0.20220515154925-e7df8a3d0c34/README.md (about)

     1  # Производственный календарь РФ
     2  
     3  Небольшой сервис, который парсит производственный календарь
     4  сайтов Консультант или SuperJob и предоставляет REST API.
     5  
     6  Запуск:
     7  
     8  ```shell
     9  docker run --name cal -p 80:80 -d ghcr.io/nvkalinin/business-calendar server
    10  ```
    11  
    12  Запросы к календарю:
    13  
    14  ```shell
    15  curl localhost/api/cal/2022
    16  curl localhost/api/cal/2022/05
    17  curl localhost/api/cal/2022/05/01
    18  ```
    19  
    20  Пример ответа на запрос к конкретной дате:
    21  
    22  ```json
    23  {
    24      "weekDay": "sun",
    25      "working": false,
    26      "type":    "holiday",
    27      "desc":    "Праздник Весны и Труда"
    28  }
    29  ```
    30  
    31  Для доступа по протоколу HTTPS нужно настроить обратный прокси-сервер.
    32  
    33  ## Источники календарей
    34  
    35  Через REST API доступны календари только за те годы, для которых
    36  была запущена синхронизация (описано далее). Если синхронизацию не
    37  запускали, то сервис возвращает ответ `404 Not Found` для всего года.
    38  
    39  Синхронизация одного года включает слияние данных из трех источников:
    40  
    41  * **Generic** — генерирует календарь, в котором пн-пт являются
    42    рабочими, сб-вс — выходными; источник используется всегда как
    43    основа календаря и отключить его нельзя.
    44  * **Consultant** или **SuperJob** — опциональный парсер внешнего
    45    календаря.
    46  * **Override** — опциональный YAML-файл с локальными переопределениями
    47    календаря.
    48  
    49  ### Парсеры
    50  
    51  Доступно два парсера: Консультант и SuperJob.
    52  
    53  Настроить парсер можно через аргумент командной строки
    54  `--source.parser=consultant|superjob|none`. То же самое можно
    55  сделать через переменную окружения `SOURCE_PARSER`.
    56  
    57  Оба парсера делают одно и то же, но есть различия в данных, которые
    58  они поставляют:
    59  
    60  * Консультант отмечает нерабочие дни, SuperJob — нет;
    61  * Консультант отмечает праздники с учетом переносов (пример: 
    62    1 мая — выходной, 2 и 3 мая — праздники), SuperJob — нет
    63    (пример: 1 мая — праздник, 2 и 3 мая — выходные);
    64  * SuperJob заполняет названия праздников (поле `desc`),
    65    Консультант — нет.
    66  
    67  Возможны и другие различия.
    68  
    69  Оба парсера предоставляют данные с 2014 года.
    70  
    71  ### Переопределения
    72  
    73  С помощью аргумента командной строки `--source.override=file.yml`
    74  или переменной окружения `SOURCE_OVERRIDE` можно указать путь
    75  к YAML-файлу с переопределениями календаря.
    76  
    77  Пример, файла:
    78  
    79  ```yaml
    80  2022:
    81      11:
    82          # Мечты КПРФ :-)
    83          4: {type: normal, working: true, desc: ''}
    84          7: {type: holiday, working: false, desc: 'День Великой Октябрьской социалистической революции'}
    85  ```
    86  
    87  Для каждого дня можно указать следующие параметры:
    88  
    89  * `weekDay` — день недели (указать можно, но практического смысла
    90    нет, так как значение берется из источника Generic), перечисление:
    91    * `mon`, `tue`, `wed`, `thu`, `fri`, `sat`, `sun`;
    92  * `working` (`bool`) — рабочий день или нет;
    93  * `type` — тип дня, перечисление:
    94    * `normal` — обычный рабочий день,
    95    * `weekend` — обычный выходной день,
    96    * `preHoliday` — предпраздничный день,
    97    * `holiday` — праздничный день,
    98    * `noWork` — нерабочий день;
    99  * `desc` (`string`) — текстовое описание дня.
   100  
   101  Обязательным, фактически, является только `working`. Если этот параметр
   102  не указан, то подразумевается значение `false`.
   103  
   104  ## Синхронизация календарей
   105  
   106  Прежде чем календари станут доступны через REST API, нужно запустить
   107  синхронизацию для каждого года, который нужен. Есть несколько
   108  способов это сделать.
   109  
   110  ### Синхронизация при запуске сервиса
   111  
   112  По-умолчанию, при запуске сервиса запускается синхронизация
   113  текущего и следующего года.
   114  
   115  Это можно изменить с помощью аргумента командной строки:
   116  
   117  ```shell
   118  cal server \
   119      --sync-on-start=2022 \
   120      --sync-on-start=current \
   121      --sync-on-start=next
   122  ```
   123  
   124  Чтобы отключить синхронизацию при запуске:
   125  
   126  ```shell
   127  cal server --sync-on-start=none
   128  ```
   129  
   130  Можно использовать переменную окружения `SYNC_ON_START`, значения
   131  нужно указывать через запятую.
   132  
   133  ### Периодическая синхронизация
   134  
   135  Сервис может ежедневно выполнять синхронизацию в указанное время:
   136  
   137  ```shell
   138  cal server --sync-at=hh:mm[:ss]
   139  ```
   140  
   141  То же самое можно настроить через переменную окружения `SYNC_AT`.
   142  
   143  Часовой пояс можно указать через переменную окружения `TZ`.
   144  
   145  Если требуется синхронизация по другому расписанию, используйте
   146  свой планировщик и команду, описанную далее.
   147  
   148  ### Команда синхронизации
   149  
   150  Команду можно выполнить двумя способами.
   151  
   152  Через CLI:
   153  
   154  ```shell
   155  docker exec -it <container> cal sync -y2022 -y2023
   156  ```
   157  
   158  Через REST API:
   159  
   160  ```shell
   161  curl -u 'admin:<passwd>' 'localhost/api/admin/sync?y=2022&y=2023'
   162  ```
   163  
   164  Пароль можно задать при запуске сервера (описано далее).
   165  
   166  ## Хранилище календарей
   167  
   168  В ходе синхронизации, после слияния данных всех источников получившийся
   169  календарь записывается в хранилище. REST API возвращает данные только
   170  из хранилища.
   171  
   172  Указать тип хранилища можно с помощью аргумента командной строки
   173  `--store.engine=bolt|memory`, либо переменной окружения `STORE_ENGINE`.
   174  
   175  По-умолчанию используется Bolt.
   176  
   177  ### Bolt
   178  
   179  Все данные хранятся в файле.
   180  
   181  Рекомендуется монтировать каталог в контейнер.
   182  
   183  Указать путь к файлу БД можно с помощью аргумента командной строки
   184  `--store.bolt.file=/data/cal.bolt`, либо через переменную окружения
   185  `STORE_BOLT_FILE`.
   186  
   187  Для данного типа хранилища доступно резервное копирование данных.
   188  
   189  Резервное копирование через CLI:
   190  
   191  ```shell
   192  docker exec -it <container> cal backup
   193  ```
   194  
   195  По-умолчанию бекап сохраняется в файл `cal_YYYY-MM-DD.bolt.gz`.
   196  Можно указать `-o <path>` для сохранения по другому пути, либо
   197  `-o -` для вывода резервной копии в stdout.
   198  
   199  Резервное копирование через REST API:
   200  
   201  ```shell
   202  curl -u 'admin:<passwd>' 'localhost/api/admin/backup'
   203  ```
   204  
   205  ### Memory
   206  
   207  Данные хранятся в оперативной памяти. В отличие от Bolt, после
   208  перезапуска сервера придется заново выполнить синхронизацию всех
   209  календарей.
   210  
   211  ## Настройки веб-сервера
   212  
   213  ### Хост и порт
   214  
   215  Хост и порт, на котором веб-сервер принимает соединения можно указать
   216  с помощью аргумента командной строки `--web.listen=host:port`, либо
   217  через переменную окружения `WEB_LISTEN`.
   218  
   219  ### Rate Limiter
   220  
   221  Можно ограничить количество запросов с одного IP-адреса за период
   222  времени.
   223  
   224  Если используется обратный прокси, убедитесь, что он корректно
   225  заполняет заголовок `X-Forwarded-For`.
   226  
   227  Аргументы командной строки:
   228  
   229  * `--web.ratelim.reqs` — Количество запросов с одного IP. 
   230    Если 0 — rate limiter отключен.
   231  * `--web.ratelim.window` — Интервал времени, за который
   232    разрешено указанное кол-во запросов, например: `10s`, `1m`.
   233  
   234  Можно также использовать переменные окружения:
   235  * 
   236  * `WEB_RATE_LIM_REQS`
   237  * `WEB_RATE_LIM_WINDOW`
   238  
   239  По-умолчанию, включено ограничение 100 запросов в секунду.
   240  
   241  ## Пароль админа
   242  
   243  Доступ к `/api/admin` должен быть защищен паролем, если доступ
   244  к сервису будет разрешен кому-либо, кроме других ваших сервисов.
   245  
   246  Задать пароль можно через аргумент командной строки
   247  `--web.admin-passwd=<passwd>` или переменную окружения
   248  `WEB_ADMIN_PASSWD`.
   249  
   250  По-умолчанию задан пустой пароль.
   251  
   252  ## Другие параметры
   253  
   254  Полный список параметров можно получить с помощью команды:
   255  
   256  ```shell
   257  docker exec <container> cal server --help
   258  ```