docs: update README, CONFIG and pyproject.toml for --send feature
- README: add --send flag to features, usage examples, full flag list; replace black/isort with ruff in dev section; add email config template variables docs - CONFIG: new email section with all fields documented, --send usage examples, error handling and flag compatibility table - pyproject.toml: remove unused black and isort from dev dependencies and their tool configs (project uses ruff for both lint and format)
This commit is contained in:
90
README.md
90
README.md
@@ -17,10 +17,11 @@ CLI-инструмент для генерации отчётов по зада
|
|||||||
- Экспорт в 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.
|
- YAML-конфиг (`~/.config/redmine-reporter/config.yml`): шаблон имени файла, путь по умолчанию, период, email.
|
||||||
- Умное разрешение `--output`: bare-формат (`xlsx`) → путь по шаблону, без расширения → автодописывание.
|
- Умное разрешение `--output`: bare-формат (`xlsx`) → путь по шаблону, без расширения → автодописывание.
|
||||||
- `--commit`: автосохранение отчёта в файл + фиксация периода в YAML-конфиге для следующего запуска.
|
- `--commit`: автосохранение отчёта в файл + фиксация периода в YAML-конфиге для следующего запуска.
|
||||||
- Понятные сообщения об ошибках Redmine API (401/403/5xx, таймаут, сеть).
|
- `--send`: отправка отчёта по email через SMTP сразу после генерации.
|
||||||
|
- Понятные сообщения об ошибках Redmine API, SMTP и файловой системы.
|
||||||
- Загрузка альтернативного `.env` через `--config`.
|
- Загрузка альтернативного `.env` через `--config`.
|
||||||
|
|
||||||
## Установка
|
## Установка
|
||||||
@@ -89,11 +90,17 @@ 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
|
||||||
```
|
```
|
||||||
|
|
||||||
Шаблон `output.filename` поддерживает `{author}`, `{from}`, `{to}`, `{date}` (DD_MM_YYYY), `{ext}`.
|
Шаблон `output.filename` поддерживает `{author}`, `{from}`, `{to}`, `{date}` (DD_MM_YYYY), `{ext}`.
|
||||||
|
|
||||||
|
Шаблоны `email.subject` и `email.body_text` поддерживают `{author}`, `{period}` (строка диапазона, например `2026-06-01--2026-06-30`).
|
||||||
|
|
||||||
Подробнее: [docs/CONFIG.md](docs/CONFIG.md).
|
Подробнее: [docs/CONFIG.md](docs/CONFIG.md).
|
||||||
|
|
||||||
### `.env` (legacy)
|
### `.env` (legacy)
|
||||||
@@ -125,6 +132,8 @@ DEFAULT_TO_DATE=2026-01-31
|
|||||||
source .venv/bin/activate
|
source .venv/bin/activate
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Основные сценарии
|
||||||
|
|
||||||
Отчёт за период по умолчанию:
|
Отчёт за период по умолчанию:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -164,41 +173,46 @@ redmine-reporter --compact
|
|||||||
redmine-reporter --debug
|
redmine-reporter --debug
|
||||||
```
|
```
|
||||||
|
|
||||||
Экспорт с явным путём:
|
### Экспорт в файл
|
||||||
|
|
||||||
|
Явный путь:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
redmine-reporter --output report.xlsx
|
redmine-reporter --output report.xlsx
|
||||||
redmine-reporter --output /path/to/report.odt
|
redmine-reporter --output /path/to/report.odt
|
||||||
```
|
```
|
||||||
|
|
||||||
Экспорт — только формат (путь и имя берутся из YAML-шаблона):
|
Только формат (путь и имя берутся из YAML-шаблона):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
redmine-reporter --output xlsx # → output.dir/отчёт_01_07_2026.xlsx
|
redmine-reporter --output xlsx # → output.dir/отчёт_01_07_2026.xlsx
|
||||||
redmine-reporter --output odt # → output.dir/отчёт_01_07_2026.odt
|
redmine-reporter --output odt # → output.dir/отчёт_01_07_2026.odt
|
||||||
```
|
```
|
||||||
|
|
||||||
Экспорт — путь без расширения (дописывается `default_format` из конфига):
|
Путь без расширения (дописывается `default_format` из конфига):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
redmine-reporter --output /tmp/report # → /tmp/report.xlsx (если default_format: xlsx)
|
redmine-reporter --output /tmp/report # → /tmp/report.xlsx (если default_format: xlsx)
|
||||||
```
|
```
|
||||||
|
|
||||||
Без времени / с разбивкой по активностям:
|
### Отправка по email (`--send`)
|
||||||
|
|
||||||
|
Отправить отчёт на email, указанный в YAML-конфиге (секция `email`):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
redmine-reporter --no-time
|
# Сохранить по шаблону и отправить
|
||||||
redmine-reporter --by-activity
|
redmine-reporter --date 2026-06-01--2026-06-30 --send
|
||||||
redmine-reporter --by-activity --summary
|
|
||||||
|
# С явным путём
|
||||||
|
redmine-reporter --date 2026-06-01--2026-06-30 --output ~/report.xlsx --send
|
||||||
|
|
||||||
|
# Вместе с фиксацией периода
|
||||||
|
redmine-reporter --date 2026-06-01--2026-06-30 --send --commit
|
||||||
```
|
```
|
||||||
|
|
||||||
Сводка:
|
Если секция `email` не настроена — ошибка с пояснением. При ошибке SMTP файл отчёта остаётся на диске, данные не теряются. Поддерживаются `to`, `cc`, `bcc`, TLS, отключение вложения (`attach: false`).
|
||||||
|
|
||||||
```bash
|
### Фиксация периода (`--commit`)
|
||||||
redmine-reporter --summary
|
|
||||||
```
|
|
||||||
|
|
||||||
Фиксация периода (`--commit`):
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Сгенерировать, сохранить в файл по шаблону, запомнить период
|
# Сгенерировать, сохранить в файл по шаблону, запомнить период
|
||||||
@@ -215,6 +229,22 @@ redmine-reporter
|
|||||||
redmine-reporter --commit
|
redmine-reporter --commit
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Сводка и опции
|
||||||
|
|
||||||
|
Без времени / с разбивкой по активностям:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
redmine-reporter --no-time
|
||||||
|
redmine-reporter --by-activity
|
||||||
|
redmine-reporter --by-activity --summary
|
||||||
|
```
|
||||||
|
|
||||||
|
Сводка:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
redmine-reporter --summary
|
||||||
|
```
|
||||||
|
|
||||||
## Форматы вывода
|
## Форматы вывода
|
||||||
|
|
||||||
| Формат | Особенности |
|
| Формат | Особенности |
|
||||||
@@ -226,6 +256,33 @@ redmine-reporter --commit
|
|||||||
| **JSON** | Массив объектов: `project`, `version`, `issue_id`, `subject`, `status`, `time`. |
|
| **JSON** | Массив объектов: `project`, `version`, `issue_id`, `subject`, `status`, `time`. |
|
||||||
| **Excel (.xlsx)** | Merge cells, колонки `Hours`/`Spent Time`, итоги, автоширина, автофильтр, freeze panes. |
|
| **Excel (.xlsx)** | Merge cells, колонки `Hours`/`Spent Time`, итоги, автоширина, автофильтр, freeze panes. |
|
||||||
|
|
||||||
|
## Полный список флагов
|
||||||
|
|
||||||
|
```
|
||||||
|
--date DATE Диапазон дат: YYYY-MM-DD--YYYY-MM-DD
|
||||||
|
--compact Компактный текстовый вывод вместо таблицы
|
||||||
|
--output PATH/FMT Путь к файлу (.odt/.csv/.md/.html/.json/.xlsx)
|
||||||
|
или bare-формат (xlsx/odt/...) — путь из конфига
|
||||||
|
--author NAME Переопределить имя автора
|
||||||
|
--no-time Не включать затраченное время в таблицу
|
||||||
|
--url URL Переопределить Redmine URL
|
||||||
|
--api-key KEY Переопределить Redmine API key
|
||||||
|
--config PATH Путь к альтернативному .env-файлу
|
||||||
|
--verbose Подробный вывод
|
||||||
|
--debug Отладочный вывод
|
||||||
|
--version Показать версию и выйти
|
||||||
|
--summary Вывести сводку по времени в stderr
|
||||||
|
--user-id ID Redmine ID пользователя для отчёта
|
||||||
|
--user-login LOGIN Логин пользователя Redmine
|
||||||
|
--user-name NAME Полное имя пользователя Redmine
|
||||||
|
--by-activity Разбить время по типам активности
|
||||||
|
--init-config Сгенерировать YAML-конфиг и выйти
|
||||||
|
--force Перезаписать существующий конфиг (с --init-config)
|
||||||
|
--config-path PATH Путь к YAML-конфигу (по умолчанию ~/.config/redmine-reporter/config.yml)
|
||||||
|
--commit Сохранить отчёт в файл и зафиксировать период в конфиге
|
||||||
|
--send Отправить отчёт по email после сохранения
|
||||||
|
```
|
||||||
|
|
||||||
## Разработка
|
## Разработка
|
||||||
|
|
||||||
Проверки перед коммитом:
|
Проверки перед коммитом:
|
||||||
@@ -233,8 +290,7 @@ redmine-reporter --commit
|
|||||||
```bash
|
```bash
|
||||||
pytest
|
pytest
|
||||||
ruff check redmine_reporter tests
|
ruff check redmine_reporter tests
|
||||||
black --check redmine_reporter tests
|
ruff format --check redmine_reporter tests
|
||||||
isort --check-only redmine_reporter tests
|
|
||||||
mypy redmine_reporter
|
mypy redmine_reporter
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
113
docs/CONFIG.md
113
docs/CONFIG.md
@@ -103,6 +103,119 @@ redmine-reporter --date 2026-06-15--2026-06-20 --commit
|
|||||||
redmine-reporter --commit
|
redmine-reporter --commit
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### `email` — настройка отправки по почте
|
||||||
|
|
||||||
|
Секция `email` используется флагом `--send`. Если секция не настроена или `smtp.host`
|
||||||
|
пуст, `--send` завершится с ошибкой «Email не настроен».
|
||||||
|
|
||||||
|
**Все поля:**
|
||||||
|
|
||||||
|
| Поле | Тип | По умолчанию | Описание |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `smtp.host` | строка | `""` | Адрес SMTP-сервера |
|
||||||
|
| `smtp.port` | число | `587` | Порт SMTP |
|
||||||
|
| `smtp.user` | строка | `""` | Логин для аутентификации |
|
||||||
|
| `smtp.password` | строка | `""` | Пароль (рекомендуется `${SMTP_PASSWORD}`) |
|
||||||
|
| `smtp.tls` | bool | `true` | Использовать STARTTLS |
|
||||||
|
| `from` | строка | `""` | Адрес отправителя |
|
||||||
|
| `to` | список | `[]` | Основные получатели |
|
||||||
|
| `cc` | список | `[]` | Копия |
|
||||||
|
| `bcc` | список | `[]` | Скрытая копия (не отображается в заголовках письма) |
|
||||||
|
| `subject` | строка | `"Отчёт {author} за {period}"` | Тема письма |
|
||||||
|
| `body_text` | строка | `"Во вложении отчёт."` | Текст письма (plain text) |
|
||||||
|
| `attach` | bool | `true` | Прикреплять файл отчёта. Если `false` — только текст |
|
||||||
|
|
||||||
|
**Подстановки в `subject` и `body_text`:**
|
||||||
|
|
||||||
|
| Плейсхолдер | Описание | Пример |
|
||||||
|
|---|---|---|
|
||||||
|
| `{author}` | Имя автора из конфига или `--author` | `Кокос А.А.` |
|
||||||
|
| `{period}` | Строка диапазона дат | `2026-06-01--2026-06-30` |
|
||||||
|
|
||||||
|
**MIME-тип вложения** определяется по расширению файла:
|
||||||
|
|
||||||
|
| Расширение | MIME-тип |
|
||||||
|
|---|---|
|
||||||
|
| `.xlsx` | `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` |
|
||||||
|
| `.odt` | `application/vnd.oasis.opendocument.text` |
|
||||||
|
| `.csv` | `text/csv` |
|
||||||
|
| `.html` | `text/html` |
|
||||||
|
| `.json` | `application/json` |
|
||||||
|
| `.md` | `text/markdown` |
|
||||||
|
|
||||||
|
Неизвестное расширение → `application/octet-stream`.
|
||||||
|
|
||||||
|
**Пример конфигурации:**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
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
|
||||||
|
- team-lead@example.com
|
||||||
|
cc:
|
||||||
|
- manager@example.com
|
||||||
|
bcc: []
|
||||||
|
subject: "Отчёт {author} за {period}"
|
||||||
|
body_text: "Во вложении отчёт за период {period}."
|
||||||
|
attach: true
|
||||||
|
```
|
||||||
|
|
||||||
|
### `--send` — отправка отчёта по email
|
||||||
|
|
||||||
|
Флаг `--send` отправляет сгенерированный отчёт через SMTP сразу после сохранения
|
||||||
|
в файл. Требует настроенную секцию `email` в YAML-конфиге.
|
||||||
|
|
||||||
|
**Что делает:**
|
||||||
|
|
||||||
|
1. Генерирует отчёт как обычно.
|
||||||
|
2. Сохраняет отчёт в файл:
|
||||||
|
- Если указан `--output` — по явному пути.
|
||||||
|
- Если `--output` не указан — по шаблону из `output.dir` / `output.filename`.
|
||||||
|
3. Формирует MIME-письмо: тема, текст, вложение (с корректным MIME-типом).
|
||||||
|
4. Отправляет через SMTP с TLS (таймаут 30 секунд).
|
||||||
|
|
||||||
|
**Файл отчёта сохраняется до попытки отправки** — при ошибке SMTP файл остаётся
|
||||||
|
на диске, данные не теряются.
|
||||||
|
|
||||||
|
**Ошибки SMTP:**
|
||||||
|
|
||||||
|
- Нет соединения → `"Не удалось подключиться к SMTP-серверу host:port"`
|
||||||
|
- Неверный логин/пароль → `"Ошибка аутентификации SMTP. Проверьте логин и пароль."`
|
||||||
|
- Таймаут → `"Таймаут соединения с SMTP-сервером."`
|
||||||
|
- Другая ошибка → `"Ошибка отправки письма: <детали>"`
|
||||||
|
|
||||||
|
Все ошибки выводятся в stderr, код возврата 1.
|
||||||
|
|
||||||
|
**Примеры:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Отправить отчёт за июнь (сохранится по шаблону output.filename)
|
||||||
|
redmine-reporter --date 2026-06-01--2026-06-30 --send
|
||||||
|
|
||||||
|
# С явным путём
|
||||||
|
redmine-reporter --date 2026-06-01--2026-06-30 --output ~/report.xlsx --send
|
||||||
|
|
||||||
|
# Отправить и зафиксировать период
|
||||||
|
redmine-reporter --date 2026-06-01--2026-06-30 --send --commit
|
||||||
|
```
|
||||||
|
|
||||||
|
**Совместимость с другими флагами:**
|
||||||
|
|
||||||
|
| Комбинация | Поведение |
|
||||||
|
|---|---|
|
||||||
|
| `--send` | Сохранить по шаблону → отправить |
|
||||||
|
| `--send --output X` | Сохранить в X → отправить |
|
||||||
|
| `--send --commit` | Сохранить → отправить → зафиксировать период |
|
||||||
|
| `--send` без `email` в конфиге | Ошибка, exit 1 |
|
||||||
|
| `--send` при ошибке SMTP | Файл сохранён, ошибка в stderr, exit 1 |
|
||||||
|
|
||||||
### `output` — путь и имя файла по умолчанию
|
### `output` — путь и имя файла по умолчанию
|
||||||
|
|
||||||
Секция управляет тем, куда и с каким именем сохраняется отчёт, когда `--output` не содержит полного пути.
|
Секция управляет тем, куда и с каким именем сохраняется отчёт, когда `--output` не содержит полного пути.
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ dependencies = [
|
|||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
dev = [
|
dev = [
|
||||||
"pytest>=7.0",
|
"pytest>=7.0",
|
||||||
"black>=23.0",
|
|
||||||
"isort>=5.12",
|
|
||||||
"mypy>=1.0",
|
"mypy>=1.0",
|
||||||
"ruff>=0.1.0",
|
"ruff>=0.1.0",
|
||||||
]
|
]
|
||||||
@@ -46,14 +44,6 @@ include = ["redmine_reporter*"]
|
|||||||
[tool.setuptools.package-data]
|
[tool.setuptools.package-data]
|
||||||
"redmine_reporter" = ["templates/template.odt"]
|
"redmine_reporter" = ["templates/template.odt"]
|
||||||
|
|
||||||
[tool.black]
|
|
||||||
line-length = 100
|
|
||||||
target-version = ['py39']
|
|
||||||
|
|
||||||
[tool.isort]
|
|
||||||
profile = "black"
|
|
||||||
multi_line_output = 3
|
|
||||||
|
|
||||||
[tool.mypy]
|
[tool.mypy]
|
||||||
warn_unused_configs = true
|
warn_unused_configs = true
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user