From 485be063d23df7e066fe824530f9d5c36079130a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=BE=D0=BA=D0=BE=D1=81=20=D0=90=D1=80=D1=82=D0=B5?= =?UTF-8?q?=D0=BC=20=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B5=D0=B2=D0=B8?= =?UTF-8?q?=D1=87?= Date: Tue, 7 Jul 2026 10:34:49 +0700 Subject: [PATCH] docs: update README and CONFIG for #43 #47 - README: add YAML config section, --by-activity, bare format --output, output without extension, period.precision - CONFIG: document period.last_used, period.precision (date/datetime), output path resolution rules, resolve_output_path() behavior --- README.md | 118 +++++++++++++++++++++++++++++++++++-------------- docs/CONFIG.md | 95 +++++++++++++++++++++++++++------------ 2 files changed, 150 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 4df25e9..7790c4e 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,13 @@ CLI-инструмент для генерации отчётов по зада - Авторизация через Redmine API token или логин/пароль. - Группировка задач по проекту и версии. - Перевод статусов задач на русский язык. +- Разбивка по типам активности (`--by-activity`). - Вывод в консоль (таблица / компактный вид). - Экспорт в ODT, CSV, Markdown, HTML, JSON и Excel (.xlsx). - Excel-отчёт с merge-ячейками по проекту/версии, итогами, автошириной, автофильтром и закреплённой шапкой. - Сводка по времени (`--summary`). +- YAML-конфиг (`~/.config/redmine-reporter/config.yml`): шаблон имени файла, путь по умолчанию, период, SMTP. +- Умное разрешение `--output`: bare-формат (`xlsx`) → путь по шаблону, без расширения → автодописывание. - Понятные сообщения об ошибках Redmine API (401/403/5xx, таймаут, сеть). - Загрузка альтернативного `.env` через `--config`. @@ -38,28 +41,70 @@ pip install -e ".[dev]" ## Настройка -Создайте файл `.env` в корне проекта. Он не должен попадать в git. +Источники конфигурации (от высшего приоритета к низшему): -Рекомендуемый вариант авторизации: +``` +CLI-флаги > переменные окружения > .env > YAML-конфиг > кодовые дефолты +``` + +### YAML-конфиг (основной способ) + +```bash +# Сгенерировать YAML из текущего .env +redmine-reporter --init-config + +# Редактировать под себя +vim ~/.config/redmine-reporter/config.yml +``` + +Структура: + +```yaml +redmine: + url: https://red.eltex.loc + api_key: ${REDMINE_API_KEY} + author: "Кокос А.А." + verify_ssl: true + +period: + precision: date # date | datetime + default_from: "2026-06-01" + default_to: "2026-06-30" + dynamic: false + # last_used заполняется --commit (см. docs/CONFIG.md) + +output: + dir: ~/reports + filename: "{author}_{from}_{to}.{ext}" + default_format: xlsx + +email: + smtp: + host: smtp.example.com + port: 587 + user: bot@example.com + password: ${SMTP_PASSWORD} + tls: true + from: bot@example.com + to: + - boss@example.com + subject: "Отчёт {author} за {period}" +``` + +Шаблон `output.filename` поддерживает `{author}`, `{from}`, `{to}`, `{date}` (DD_MM_YYYY), `{ext}`. + +Подробнее: [docs/CONFIG.md](docs/CONFIG.md). + +### `.env` (legacy) ```ini REDMINE_URL=https://red.eltex.loc/ REDMINE_API_KEY=ваш_api_token REDMINE_AUTHOR=Иванов Иван Иванович - DEFAULT_FROM_DATE=2026-01-01 DEFAULT_TO_DATE=2026-01-31 ``` -Резервный вариант: - -```ini -REDMINE_URL=https://red.eltex.loc/ -REDMINE_USER=ваш.логин -REDMINE_PASSWORD=ваш_пароль -REDMINE_AUTHOR=Иванов Иван Иванович -``` - Переменные окружения: | Переменная | Обязательность | Описание | @@ -68,7 +113,7 @@ REDMINE_AUTHOR=Иванов Иван Иванович | `REDMINE_API_KEY` | Да, если нет логина и пароля | Redmine API token. | | `REDMINE_USER` | Да, если нет токена | Логин Redmine. | | `REDMINE_PASSWORD` | Да, если нет токена | Пароль Redmine. | -| `REDMINE_AUTHOR` | Нет | Имя автора для ODT-отчёта. | +| `REDMINE_AUTHOR` | Нет | Имя автора для отчёта. | | `DEFAULT_FROM_DATE` | Нет | Начальная дата периода по умолчанию (`YYYY-MM-DD`). | | `DEFAULT_TO_DATE` | Нет | Конечная дата периода по умолчанию (`YYYY-MM-DD`). | | `REDMINE_VERIFY` | Нет | TLS-проверка: `true` / `false` / путь к CA bundle. | @@ -85,13 +130,13 @@ source .venv/bin/activate redmine-reporter ``` -Отчёт за произвольный период: +Произвольный период: ```bash redmine-reporter --date 2026-02-01--2026-02-28 ``` -Отчёт по другому пользователю: +Другой пользователь: ```bash redmine-reporter --user-id 42 @@ -99,51 +144,54 @@ redmine-reporter --user-login ivanov redmine-reporter --user-name "Иванов И.И." ``` -`--user-name` требует точного совпадения; если найдено несколько пользователей, CLI сообщает об ошибке и просит использовать `--user-id`. - -Переопределить URL/API-ключ из `.env`: +Переопределить URL / API-ключ: ```bash redmine-reporter --url https://red.example.com --api-key ваш_токен ``` -Альтернативный конфигурационный файл: +Альтернативный `.env`: ```bash redmine-reporter --config /path/to/.env ``` -Компактный вывод: +Компактный / отладочный вывод: ```bash redmine-reporter --compact -``` - -Отладочный вывод: - -```bash redmine-reporter --debug ``` -Экспорт: +Экспорт с явным путём: ```bash -redmine-reporter --output report.odt -redmine-reporter --output report.csv -redmine-reporter --output report.md -redmine-reporter --output report.html -redmine-reporter --output report.json redmine-reporter --output report.xlsx +redmine-reporter --output /path/to/report.odt ``` -Отчёт без затраченного времени (работает для всех форматов): +Экспорт — только формат (путь и имя берутся из YAML-шаблона): + +```bash +redmine-reporter --output xlsx # → output.dir/отчёт_01_07_2026.xlsx +redmine-reporter --output odt # → output.dir/отчёт_01_07_2026.odt +``` + +Экспорт — путь без расширения (дописывается `default_format` из конфига): + +```bash +redmine-reporter --output /tmp/report # → /tmp/report.xlsx (если default_format: xlsx) +``` + +Без времени / с разбивкой по активностям: ```bash redmine-reporter --no-time -redmine-reporter --no-time --output report.xlsx +redmine-reporter --by-activity +redmine-reporter --by-activity --summary ``` -Сводка по времени: +Сводка: ```bash redmine-reporter --summary @@ -175,5 +223,7 @@ mypy redmine_reporter ## Безопасность - Не коммитьте `.env`, API token, пароль или логин. +- YAML-конфиг имеет права `0600`, директория — `0700`. +- Рекомендуется хранить секреты через `${VAR}`, а не plaintext. - Используйте аккаунт с минимальными правами, достаточными для чтения time entries и задач. - Инструмент работает только в режиме чтения и не изменяет данные в Redmine. diff --git a/docs/CONFIG.md b/docs/CONFIG.md index 515843a..5eabde8 100644 --- a/docs/CONFIG.md +++ b/docs/CONFIG.md @@ -24,21 +24,24 @@ CLI-флаги > переменные окружения > .env > YAML > ```yaml redmine: - url: https://red.eltex.loc # URL инстанса Redmine - api_key: ${REDMINE_API_KEY} # API-ключ (или plaintext) - author: "Кокос А.А." # Имя автора для отчёта - verify_ssl: true # Проверка SSL-сертификата + url: https://red.eltex.loc + api_key: ${REDMINE_API_KEY} + author: "Кокос А.А." + verify_ssl: true period: - precision: date # date | datetime - default_from: "2026-06-01" # Начало периода по умолчанию - default_to: "2026-06-30" # Конец периода по умолчанию - dynamic: false # Автоматически сдвигать период + precision: date + default_from: "2026-06-01" + default_to: "2026-06-30" + dynamic: false + last_used: + from: "2026-06-30T09:00:00" + to: "2026-06-30T12:00:00" output: - dir: ~/reports # Директория для отчётов - filename: "{author}_{from}_{to}.{ext}" # Шаблон имени файла - default_format: xlsx # Формат по умолчанию + dir: ~/reports + filename: "{author}_{from}_{to}.{ext}" + default_format: xlsx email: smtp: @@ -50,24 +53,49 @@ email: from: bot@example.com to: - boss@example.com + cc: [] + bcc: [] subject: "Отчёт {author} за {period}" + body_text: "Во вложении отчёт." + attach: true ``` -### Шаблон имени файла +### `period.precision` — точность периода -Поле `output.filename` поддерживает подстановки: +Определяет, как вычисляется следующий период после фиксации: -| Плейсхолдер | Описание | Пример | -|-------------|-------------------------------|------------------------| -| `{author}` | Имя автора (пробелы → `_`) | `Кокос_А.А.` | -| `{from}` | Начало периода, `YYYY-MM-DD` | `2026-06-01` | -| `{to}` | Конец периода, `YYYY-MM-DD` | `2026-06-30` | -| `{date}` | Конец периода, `DD_MM_YYYY` | `30_06_2026` | -| `{ext}` | Расширение файла без точки | `xlsx` | +- `date` (по умолчанию) — период с точностью до дня. Следующий запуск (после `--commit`, #44) начинается со следующего дня. +- `datetime` — период с точностью до секунды. При повторном запуске time entries с `created_on` и `updated_on` ранее `last_used.to` исключаются (AND-логика: запись исключается только если **оба** поля раньше cutoff). Это предотвращает дублирование при отправке отчёта внутри рабочего дня. + +`last_used.from` / `last_used.to` записываются автоматически при `--commit`. Вручную редактировать не требуется. + +### `output` — путь и имя файла по умолчанию + +Секция управляет тем, куда и с каким именем сохраняется отчёт, когда `--output` не содержит полного пути. + +**Правила разрешения `--output`:** + +| Аргумент `--output` | Поведение | +|---|---| +| `/полный/путь/report.xlsx` | Используется как есть, конфиг игнорируется | +| `xlsx` (bare format: `xlsx`, `odt`, `csv`, `md`, `html`, `json`) | Путь = `output.dir` + `output.filename`, расширение = bare format | +| `/tmp/report` (путь без расширения) | Дописывается `.default_format` → `/tmp/report.xlsx` | + +**Шаблон имени файла:** + +`output.filename` поддерживает подстановки: + +| Плейсхолдер | Описание | Пример | +|---|---|---| +| `{author}` | Имя автора (пробелы → `_`) | `Кокос_А.А.` | +| `{from}` | Начало периода, `YYYY-MM-DD` | `2026-06-01` | +| `{to}` | Конец периода, `YYYY-MM-DD` | `2026-06-30` | +| `{date}` | Конец периода, `DD_MM_YYYY` | `30_06_2026` | +| `{ext}` | Расширение файла без точки | `xlsx` | Неизвестные плейсхолдеры остаются в имени как есть. -Примеры шаблонов: +Примеры: ```yaml # По умолчанию @@ -96,7 +124,17 @@ email: Это безопаснее, чем хранить секреты plaintext в YAML. Однако plaintext-секреты **не запрещены** — если вписать `api_key: "abc123"` напрямую, система примет. -Права `0600` — единственная защита. +Права `0600` — основная защита. + +## Разрешение выходного пути + +Функция `resolve_output_path()` определяет итоговый путь к файлу: + +1. `--output` не указан → консольный вывод. +2. `--output xlsx` (bare format) → путь формируется как `output.dir / output.filename` с подстановкой `{ext}` = bare format и дат из периода. +3. `--output /path/report` (без расширения) → дописывается `.output.default_format`. +4. `--output /path/report.csv` (с расширением) → используется как есть. +5. `--output /path/report.xyz` (неизвестное расширение) → используется как есть, форматтер выбирается по расширению. ## Миграция с `.env` на YAML @@ -109,7 +147,7 @@ redmine-reporter --init-config # 2. Проверяем, что создалось cat ~/.config/redmine-reporter/config.yml -# 3. Редактируем под себя (шаблон имени, почту, etc.) +# 3. Редактируем под себя (шаблон имени, период, etc.) vim ~/.config/redmine-reporter/config.yml ``` @@ -123,11 +161,11 @@ vim ~/.config/redmine-reporter/config.yml ### Флаги миграции -| Флаг | Назначение | -|-----------------------|-------------------------------------------------| -| `--init-config` | Создать YAML и выйти | -| `--init-config --force` | Перезаписать существующий YAML | -| `--config-path PATH` | Сохранить YAML по указанному пути (по умолчанию `~/.config/redmine-reporter/config.yml`) | +| Флаг | Назначение | +|---|---| +| `--init-config` | Создать YAML и выйти | +| `--init-config --force` | Перезаписать существующий YAML | +| `--config-path PATH` | Сохранить YAML по указанному пути (по умолчанию `~/.config/redmine-reporter/config.yml`) | ### Проверка после миграции @@ -160,7 +198,6 @@ YAML работает как базовый слой для всего, что ### Откат ```bash -# Удалить YAML-конфиг — система вернётся на .env rm ~/.config/redmine-reporter/config.yml ```