- 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
This commit is contained in:
118
README.md
118
README.md
@@ -12,10 +12,13 @@ CLI-инструмент для генерации отчётов по зада
|
|||||||
- Авторизация через Redmine API token или логин/пароль.
|
- Авторизация через Redmine API token или логин/пароль.
|
||||||
- Группировка задач по проекту и версии.
|
- Группировка задач по проекту и версии.
|
||||||
- Перевод статусов задач на русский язык.
|
- Перевод статусов задач на русский язык.
|
||||||
|
- Разбивка по типам активности (`--by-activity`).
|
||||||
- Вывод в консоль (таблица / компактный вид).
|
- Вывод в консоль (таблица / компактный вид).
|
||||||
- Экспорт в ODT, CSV, Markdown, HTML, JSON и Excel (.xlsx).
|
- Экспорт в ODT, CSV, Markdown, HTML, JSON и Excel (.xlsx).
|
||||||
- Excel-отчёт с merge-ячейками по проекту/версии, итогами, автошириной, автофильтром и закреплённой шапкой.
|
- Excel-отчёт с merge-ячейками по проекту/версии, итогами, автошириной, автофильтром и закреплённой шапкой.
|
||||||
- Сводка по времени (`--summary`).
|
- Сводка по времени (`--summary`).
|
||||||
|
- YAML-конфиг (`~/.config/redmine-reporter/config.yml`): шаблон имени файла, путь по умолчанию, период, SMTP.
|
||||||
|
- Умное разрешение `--output`: bare-формат (`xlsx`) → путь по шаблону, без расширения → автодописывание.
|
||||||
- Понятные сообщения об ошибках Redmine API (401/403/5xx, таймаут, сеть).
|
- Понятные сообщения об ошибках Redmine API (401/403/5xx, таймаут, сеть).
|
||||||
- Загрузка альтернативного `.env` через `--config`.
|
- Загрузка альтернативного `.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
|
```ini
|
||||||
REDMINE_URL=https://red.eltex.loc/
|
REDMINE_URL=https://red.eltex.loc/
|
||||||
REDMINE_API_KEY=ваш_api_token
|
REDMINE_API_KEY=ваш_api_token
|
||||||
REDMINE_AUTHOR=Иванов Иван Иванович
|
REDMINE_AUTHOR=Иванов Иван Иванович
|
||||||
|
|
||||||
DEFAULT_FROM_DATE=2026-01-01
|
DEFAULT_FROM_DATE=2026-01-01
|
||||||
DEFAULT_TO_DATE=2026-01-31
|
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_API_KEY` | Да, если нет логина и пароля | Redmine API token. |
|
||||||
| `REDMINE_USER` | Да, если нет токена | Логин Redmine. |
|
| `REDMINE_USER` | Да, если нет токена | Логин Redmine. |
|
||||||
| `REDMINE_PASSWORD` | Да, если нет токена | Пароль Redmine. |
|
| `REDMINE_PASSWORD` | Да, если нет токена | Пароль Redmine. |
|
||||||
| `REDMINE_AUTHOR` | Нет | Имя автора для ODT-отчёта. |
|
| `REDMINE_AUTHOR` | Нет | Имя автора для отчёта. |
|
||||||
| `DEFAULT_FROM_DATE` | Нет | Начальная дата периода по умолчанию (`YYYY-MM-DD`). |
|
| `DEFAULT_FROM_DATE` | Нет | Начальная дата периода по умолчанию (`YYYY-MM-DD`). |
|
||||||
| `DEFAULT_TO_DATE` | Нет | Конечная дата периода по умолчанию (`YYYY-MM-DD`). |
|
| `DEFAULT_TO_DATE` | Нет | Конечная дата периода по умолчанию (`YYYY-MM-DD`). |
|
||||||
| `REDMINE_VERIFY` | Нет | TLS-проверка: `true` / `false` / путь к CA bundle. |
|
| `REDMINE_VERIFY` | Нет | TLS-проверка: `true` / `false` / путь к CA bundle. |
|
||||||
@@ -85,13 +130,13 @@ source .venv/bin/activate
|
|||||||
redmine-reporter
|
redmine-reporter
|
||||||
```
|
```
|
||||||
|
|
||||||
Отчёт за произвольный период:
|
Произвольный период:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
redmine-reporter --date 2026-02-01--2026-02-28
|
redmine-reporter --date 2026-02-01--2026-02-28
|
||||||
```
|
```
|
||||||
|
|
||||||
Отчёт по другому пользователю:
|
Другой пользователь:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
redmine-reporter --user-id 42
|
redmine-reporter --user-id 42
|
||||||
@@ -99,51 +144,54 @@ redmine-reporter --user-login ivanov
|
|||||||
redmine-reporter --user-name "Иванов И.И."
|
redmine-reporter --user-name "Иванов И.И."
|
||||||
```
|
```
|
||||||
|
|
||||||
`--user-name` требует точного совпадения; если найдено несколько пользователей, CLI сообщает об ошибке и просит использовать `--user-id`.
|
Переопределить URL / API-ключ:
|
||||||
|
|
||||||
Переопределить URL/API-ключ из `.env`:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
redmine-reporter --url https://red.example.com --api-key ваш_токен
|
redmine-reporter --url https://red.example.com --api-key ваш_токен
|
||||||
```
|
```
|
||||||
|
|
||||||
Альтернативный конфигурационный файл:
|
Альтернативный `.env`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
redmine-reporter --config /path/to/.env
|
redmine-reporter --config /path/to/.env
|
||||||
```
|
```
|
||||||
|
|
||||||
Компактный вывод:
|
Компактный / отладочный вывод:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
redmine-reporter --compact
|
redmine-reporter --compact
|
||||||
```
|
|
||||||
|
|
||||||
Отладочный вывод:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
redmine-reporter --debug
|
redmine-reporter --debug
|
||||||
```
|
```
|
||||||
|
|
||||||
Экспорт:
|
Экспорт с явным путём:
|
||||||
|
|
||||||
```bash
|
```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 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
|
```bash
|
||||||
redmine-reporter --no-time
|
redmine-reporter --no-time
|
||||||
redmine-reporter --no-time --output report.xlsx
|
redmine-reporter --by-activity
|
||||||
|
redmine-reporter --by-activity --summary
|
||||||
```
|
```
|
||||||
|
|
||||||
Сводка по времени:
|
Сводка:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
redmine-reporter --summary
|
redmine-reporter --summary
|
||||||
@@ -175,5 +223,7 @@ mypy redmine_reporter
|
|||||||
## Безопасность
|
## Безопасность
|
||||||
|
|
||||||
- Не коммитьте `.env`, API token, пароль или логин.
|
- Не коммитьте `.env`, API token, пароль или логин.
|
||||||
|
- YAML-конфиг имеет права `0600`, директория — `0700`.
|
||||||
|
- Рекомендуется хранить секреты через `${VAR}`, а не plaintext.
|
||||||
- Используйте аккаунт с минимальными правами, достаточными для чтения time entries и задач.
|
- Используйте аккаунт с минимальными правами, достаточными для чтения time entries и задач.
|
||||||
- Инструмент работает только в режиме чтения и не изменяет данные в Redmine.
|
- Инструмент работает только в режиме чтения и не изменяет данные в Redmine.
|
||||||
|
|||||||
@@ -24,21 +24,24 @@ CLI-флаги > переменные окружения > .env > YAML >
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
redmine:
|
redmine:
|
||||||
url: https://red.eltex.loc # URL инстанса Redmine
|
url: https://red.eltex.loc
|
||||||
api_key: ${REDMINE_API_KEY} # API-ключ (или plaintext)
|
api_key: ${REDMINE_API_KEY}
|
||||||
author: "Кокос А.А." # Имя автора для отчёта
|
author: "Кокос А.А."
|
||||||
verify_ssl: true # Проверка SSL-сертификата
|
verify_ssl: true
|
||||||
|
|
||||||
period:
|
period:
|
||||||
precision: date # date | datetime
|
precision: date
|
||||||
default_from: "2026-06-01" # Начало периода по умолчанию
|
default_from: "2026-06-01"
|
||||||
default_to: "2026-06-30" # Конец периода по умолчанию
|
default_to: "2026-06-30"
|
||||||
dynamic: false # Автоматически сдвигать период
|
dynamic: false
|
||||||
|
last_used:
|
||||||
|
from: "2026-06-30T09:00:00"
|
||||||
|
to: "2026-06-30T12:00:00"
|
||||||
|
|
||||||
output:
|
output:
|
||||||
dir: ~/reports # Директория для отчётов
|
dir: ~/reports
|
||||||
filename: "{author}_{from}_{to}.{ext}" # Шаблон имени файла
|
filename: "{author}_{from}_{to}.{ext}"
|
||||||
default_format: xlsx # Формат по умолчанию
|
default_format: xlsx
|
||||||
|
|
||||||
email:
|
email:
|
||||||
smtp:
|
smtp:
|
||||||
@@ -50,15 +53,40 @@ email:
|
|||||||
from: bot@example.com
|
from: bot@example.com
|
||||||
to:
|
to:
|
||||||
- boss@example.com
|
- boss@example.com
|
||||||
|
cc: []
|
||||||
|
bcc: []
|
||||||
subject: "Отчёт {author} за {period}"
|
subject: "Отчёт {author} за {period}"
|
||||||
|
body_text: "Во вложении отчёт."
|
||||||
|
attach: true
|
||||||
```
|
```
|
||||||
|
|
||||||
### Шаблон имени файла
|
### `period.precision` — точность периода
|
||||||
|
|
||||||
Поле `output.filename` поддерживает подстановки:
|
Определяет, как вычисляется следующий период после фиксации:
|
||||||
|
|
||||||
|
- `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}` | Имя автора (пробелы → `_`) | `Кокос_А.А.` |
|
| `{author}` | Имя автора (пробелы → `_`) | `Кокос_А.А.` |
|
||||||
| `{from}` | Начало периода, `YYYY-MM-DD` | `2026-06-01` |
|
| `{from}` | Начало периода, `YYYY-MM-DD` | `2026-06-01` |
|
||||||
| `{to}` | Конец периода, `YYYY-MM-DD` | `2026-06-30` |
|
| `{to}` | Конец периода, `YYYY-MM-DD` | `2026-06-30` |
|
||||||
@@ -67,7 +95,7 @@ email:
|
|||||||
|
|
||||||
Неизвестные плейсхолдеры остаются в имени как есть.
|
Неизвестные плейсхолдеры остаются в имени как есть.
|
||||||
|
|
||||||
Примеры шаблонов:
|
Примеры:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# По умолчанию
|
# По умолчанию
|
||||||
@@ -96,7 +124,17 @@ email:
|
|||||||
|
|
||||||
Это безопаснее, чем хранить секреты plaintext в YAML. Однако plaintext-секреты
|
Это безопаснее, чем хранить секреты plaintext в YAML. Однако plaintext-секреты
|
||||||
**не запрещены** — если вписать `api_key: "abc123"` напрямую, система примет.
|
**не запрещены** — если вписать `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
|
## Миграция с `.env` на YAML
|
||||||
|
|
||||||
@@ -109,7 +147,7 @@ redmine-reporter --init-config
|
|||||||
# 2. Проверяем, что создалось
|
# 2. Проверяем, что создалось
|
||||||
cat ~/.config/redmine-reporter/config.yml
|
cat ~/.config/redmine-reporter/config.yml
|
||||||
|
|
||||||
# 3. Редактируем под себя (шаблон имени, почту, etc.)
|
# 3. Редактируем под себя (шаблон имени, период, etc.)
|
||||||
vim ~/.config/redmine-reporter/config.yml
|
vim ~/.config/redmine-reporter/config.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -124,7 +162,7 @@ vim ~/.config/redmine-reporter/config.yml
|
|||||||
### Флаги миграции
|
### Флаги миграции
|
||||||
|
|
||||||
| Флаг | Назначение |
|
| Флаг | Назначение |
|
||||||
|-----------------------|-------------------------------------------------|
|
|---|---|
|
||||||
| `--init-config` | Создать YAML и выйти |
|
| `--init-config` | Создать YAML и выйти |
|
||||||
| `--init-config --force` | Перезаписать существующий YAML |
|
| `--init-config --force` | Перезаписать существующий YAML |
|
||||||
| `--config-path PATH` | Сохранить YAML по указанному пути (по умолчанию `~/.config/redmine-reporter/config.yml`) |
|
| `--config-path PATH` | Сохранить YAML по указанному пути (по умолчанию `~/.config/redmine-reporter/config.yml`) |
|
||||||
@@ -160,7 +198,6 @@ YAML работает как базовый слой для всего, что
|
|||||||
### Откат
|
### Откат
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Удалить YAML-конфиг — система вернётся на .env
|
|
||||||
rm ~/.config/redmine-reporter/config.yml
|
rm ~/.config/redmine-reporter/config.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user