# Руководство пользователя redmine-reporter ## Оглавление - [Установка](#установка) - [Первоначальная настройка](#первоначальная-настройка) - [Выбор периода](#выбор-периода) - [Отчёт за другого пользователя](#отчёт-за-другого-пользователя) - [Экспорт в файл](#экспорт-в-файл) - [Содержимое отчёта](#содержимое-отчёта) - [Отправка по email](#отправка-по-email) - [Скользящее окно периода](#скользящее-окно-периода) - [Справочник флагов](#справочник-флагов) - [Устранение неполадок](#устранение-неполадок) - [См. также](#см-также) ## Установка Требуется Python >= 3.10. ```bash git clone https://git.akokos.ru/artem.kokos/redmine-reporter.git cd redmine-reporter python3 -m venv .venv source .venv/bin/activate pip install --upgrade pip pip install . ``` Проверка: ```bash redmine-reporter --version ``` Перед каждым запуском активируйте окружение: `source .venv/bin/activate`. ## Первоначальная настройка 1. Убедитесь, что в текущей директории есть `.env` с `REDMINE_URL` и `REDMINE_API_KEY` (или задайте эти переменные в окружении). 2. Сгенерируйте YAML-конфиг: ```bash redmine-reporter --init-config ``` Результат: файл `~/.config/redmine-reporter/config.yml` (права `0600`, директория `0700`) со всеми секциями и закомментированным примером `report.status_translation`. Секреты, заданные в окружении, записываются как `${VAR}`. 3. Если файл уже существует — ошибка; для перезаписи добавьте `--force`: ```bash redmine-reporter --init-config --force ``` 4. Нестандартное расположение конфига: ```bash redmine-reporter --init-config --config-path /etc/redmine-reporter/config.yml ``` `--config-path` задаёт путь и для загрузки YAML, и для записи при `--init-config` и `--commit`. 5. Откройте файл и заполните минимум: `redmine.url`, `redmine.api_key`, `redmine.author`. `--init-config` несовместим с флагами отчёта (`--date`, `--output`, `--compact`, `--summary`, `--user-id`/`--user-login`/`--user-name`, `--no-time`, `--by-activity`, `--send`) — указывайте его отдельно. Полный референс всех секций и переменных: [CONFIG.md](CONFIG.md). ## Выбор периода Окно отчёта — диапазон дат `from..to`. Конец (`to`) всегда сегодняшняя дата, если диапазон не задан явно через `--date`. Приоритет начала окна (от высшего к низшему): 1. `--date` — явный диапазон (полностью переопределяет окно). 2. `FROM_DATE` (env) — начало; конец — сегодня. 3. `period.from` (YAML) — начало; конец — сегодня. 4. Ничего не задано — текущий месяц: с 1-го числа по сегодня. Форматы `--date`: ```bash # Даты redmine-reporter --date 2026-06-01--2026-06-30 # Дата-время (границы флорятся до полных дней) redmine-reporter --date 2026-06-01T09:00:00--2026-06-01T18:00:00 ``` Границы с временем округляются до дат — отчёт строится за полные дни диапазона. Границы можно смешивать (дата + дата-время). Начало позже конца (`start > end`) — ошибка. Краевые случаи: - `from` позже сегодняшней даты — окно «сегодня--сегодня». - `from` некорректна (не `YYYY-MM-DD`) — warning + текущий месяц. ## Отчёт за другого пользователя Без флагов отчёт строится за текущего пользователя. ```bash redmine-reporter --user-id 42 redmine-reporter --user-login ivanov redmine-reporter --user-name "Иванов Иван Иванович" ``` Правила: - Флаги `--user-id`, `--user-login`, `--user-name` взаимоисключающие: укажите только один, иначе ошибка. - Все три принимают одно значение. Число или строка из цифр → поиск по ID. Иначе — точное регистрозависимое совпадение логина. - Если по логину совпадений нет — поиск по имени. Одно совпадение → пользователь найден. - Несколько совпадений по имени → ошибка «Multiple users match...» со списком логинов (при дублях логина — ID). - Ноль совпадений → ошибка «User '...' not found...». ## Экспорт в файл Флаг `--output` определяется по четырём правилам: | Аргумент | Результат | | --- | --- | | `--output xlsx` (bare-формат: `xlsx`, `odt`, `csv`, `md`, `html`, `json`, регистронезависимо) | Путь = `output.dir` + шаблон `output.filename` из YAML, расширение = указанный формат | | `--output /tmp/report` (путь без расширения) | Дописывается `.` + `output.default_format` → `/tmp/report.xlsx` | | `--output /tmp/report.csv` (путь с любым расширением) | Используется как есть | | `--output /tmp/report.xyz` (неизвестное расширение) | Ошибка «Неизвестный формат файла: '.xyz'. Поддерживаются: .odt, .csv, .md, .html, .json, .xlsx», exit 1 | Формат `.odt` требует установленного пакета `odfpy` (устанавливается по умолчанию) — иначе отдельная ошибка. Примеры: ```bash redmine-reporter --output xlsx # по шаблону в output.dir redmine-reporter --output 2026-06-report # → 2026-06-report.xlsx (если default_format: xlsx) redmine-reporter --output reports/june.csv # как есть ``` Плейсхолдеры `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` | Неизвестные плейсхолдеры остаются в имени как есть. Нюансы с путями: - `~` в явном `--output` раскрывает шелл, а не программа: `redmine-reporter --output ~/report.xlsx` работает, а в кавычках (`"~/report.xlsx"`) — нет. - `expanduser` применяется только к `output.dir` из YAML. ## Содержимое отчёта ### `--no-time` Убирает затраченное время из отчёта. Физически удаляет колонку времени только CSV. XLSX, HTML, ODT, Markdown, JSON и консольный вывод оставляют пустые колонки/поля; в XLSX дополнительно пропадают строки итогов по версиям/проектам/всего. ```bash redmine-reporter --output report.xlsx --no-time ``` YAML-настройка `report.no_time` действует только в автоматических режимах (`--commit`, `--send`). При ручном `--output` работает только CLI-флаг. ### `--by-activity` Разбивка затраченного времени по типам активности. В JSON-отчёте добавляется поле `activities`. ```bash redmine-reporter --by-activity ``` ### `--summary` Печатает сводку в stderr (после отчёта): - `total` — суммарное время; - `project:*` — время по каждому проекту; - `activity:*` — время по каждой активности (только при одновременном `--by-activity`). Версии в сводку не входят. ```bash redmine-reporter --by-activity --summary ``` ### `--compact` Компактный текстовый вывод в консоль вместо таблицы: ```bash redmine-reporter --compact ``` ### Перевод статусов Статусы задач переводятся встроенным словарём; секция `report.status_translation` переопределяет или дополняет переводы. Подробно: [CONFIG.md](CONFIG.md). ## Отправка по email Требуется секция `email` в YAML-конфиге (см. [CONFIG.md](CONFIG.md)). ```bash 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 --send --commit ``` Факты: - Файл отчёта сохраняется на диск ДО отправки: при ошибке SMTP файл остаётся на месте. - Перед отправкой запрашивается подтверждение «Отправить? [y/N]»; ответ «y»/«yes» продолжает, иначе отправка отменяется (без сдвига периода, если не задан явный `--commit`). - При успешной отправке начало периода сдвигается (см. [Скользящее окно периода](#скользящее-окно-периода)); при отмене (если не задан явный `--commit`) или ошибке SMTP — без сдвига. - Секция `email` отсутствует или `smtp.host` пуст → ошибка «Email не настроен. Добавьте секцию 'email' в конфиг...», exit 1. - `email.html: true` → письмо `multipart/alternative`: plain-text + HTML-таблица отчёта в теле. - Файл прикрепляется при `attach: true`; MIME-тип определяется по расширению, неизвестное → `application/octet-stream`. - Получатели `bcc` указываются только в envelope (не видны в заголовках письма). - STARTTLS применяется только при `smtp.tls: true`; аутентификация на SMTP-сервере — только если задан `smtp.user`. - Таймаут соединения с SMTP — 30 секунд. Точные тексты ошибок: - «Ошибка аутентификации SMTP. Проверьте логин и пароль.» - «Таймаут соединения с SMTP-сервером.» - «Ошибка отправки письма: ...» - «Не удалось подключиться к SMTP-серверу host:port» ## Скользящее окно периода После успешного `--commit` (файл сохранён) или реальной отправки `--send` (подтверждение «y» + успех) окно отчёта сдвигается вперёд: в конфиг пишется `period.from = <конец окна>`. Следующий запуск без `--date` начинается с граничного дня последнего отчёта. Типичный цикл: ```bash # 1. Отчёт за июнь 2026: сохранить, отправить, сдвинуть начало на 30 июня redmine-reporter --date 2026-06-01--2026-06-30 --send --commit # 2. Следующий запуск без --date берёт окно с 30 июня по сегодня redmine-reporter --send --commit ``` Граничный день: начало следующего окна совпадает с днём коммита, поэтому этот день перечитывается. Записи дня коммита, уже попавшие в прошлый отчёт, повторятся (дедупликации по `created_on`/`updated_on` нет — это осознанное следствие), зато поздние записи, добавленные в Redmine в этот день после отправки, не теряются. Повторный запуск `--commit`/`--send` в тот же день даёт окно «сегодня--сегодня», которое повторно включает уже отправленные записи этого дня. Важно: `--commit`/`--send` перезаписывают только `period.from`; остальные ключи YAML сохраняются, но пользовательские комментарии теряются (перезапись через `yaml.dump`). ## Справочник флагов | Флаг | Описание | | --- | --- | | `--date` | Явный диапазон: границы — дата `YYYY-MM-DD` или datetime `YYYY-MM-DDTHH:MM:SS`. Время отбрасывается (полные дни), границы можно смешивать; `start > end` — ошибка. | | `--compact` | Компактный текстовый вывод в консоль вместо таблицы. | | `--output` | Путь к файлу (`.odt`/`.csv`/`.md`/`.html`/`.json`/`.xlsx`) или bare-формат — тогда путь берётся из YAML-шаблона; без флага — вывод в консоль (stdout). | | `--author` | Переопределить имя автора отчёта. | | `--no-time` | Не включать затраченное время в отчёт. | | `--url` | Переопределить URL Redmine. | | `--api-key` | Переопределить API-ключ Redmine. | | `--config` | Путь к альтернативному `.env`-файлу. | | `--verbose` | Подробный вывод; показывает traceback при ошибках. | | `--debug` | Отладочный вывод; показывает traceback при ошибках. | | `--version` | Показать версию и выйти. | | `--summary` | Сводка по времени в stderr: `total`, `project:*`, `activity:*` (версии не печатаются). | | `--user-id` | Отчёт за пользователя по ID. | | `--user-login` | Отчёт за пользователя по логину (точное регистрозависимое совпадение). | | `--user-name` | Отчёт за пользователя по имени. | | `--by-activity` | Разбивка времени по типам активности (в JSON — поле `activities`). | | `--init-config` | Сгенерировать YAML-конфиг из текущего `.env`/окружения и выйти. | | `--force` | Перезаписать существующий YAML-конфиг (только с `--init-config`). | | `--config-path` | Путь к YAML-конфигу: загрузка, запись `--init-config` и `--commit`. По умолчанию `~/.config/redmine-reporter/config.yml`. | | `--commit` | Сохранить отчёт в файл и сдвинуть начало периода (`period.from` = конец окна) в YAML. | | `--send` | Отправить отчёт по email после сохранения файла; при подтверждении и успехе сдвинуть начало периода. | ## Устранение неполадок | Ошибка | Причина | Решение | | --- | --- | --- | | «REDMINE_URL must use HTTPS...» (exit 1) | URL Redmine не по HTTPS | Укажите `https://` в `redmine.url` / `REDMINE_URL` / `--url`. | | «Authentication failed: invalid API key, login or password. Check REDMINE_API_KEY / REDMINE_USER / REDMINE_PASSWORD.» | Неверный или отсутствующий API-ключ, логин или пароль | Проверьте `redmine.api_key` / `--api-key` (или `REDMINE_USER` / `REDMINE_PASSWORD`). | | «User '...' not found...» | Пользователь не найден ни по ID, ни по логину, ни по имени | Проверьте написание; логин сравнивается точно с учётом регистра. | | «Multiple users match...» | По имени найдено несколько пользователей (или несколько дублей логина) | Используйте `--user-login` с логином из списка или уточните числовой ID для `--user-id`. | | Указано несколько `--user-*` | Флаги взаимоисключающие | Оставьте только один из `--user-id` / `--user-login` / `--user-name`. | | «Неизвестный формат файла: '.xyz'. Поддерживаются: .odt, .csv, .md, .html, .json, .xlsx» (exit 1) | `--output` с неизвестным расширением | Используйте одно из поддерживаемых расширений. | | Ошибка про `odfpy` при `.odt` | Пакет `odfpy` не установлен | `pip install odfpy` или выберите другой формат. | | «Email не настроен. Добавьте секцию 'email' в конфиг...» (exit 1) | `--send` без секции `email` в YAML или с пустым `smtp.host` | Добавьте секцию `email` (см. [CONFIG.md](CONFIG.md)). | | «Ошибка аутентификации SMTP. Проверьте логин и пароль.» | Неверные `smtp.user`/`smtp.password` | Проверьте логин и пароль в конфиге. | | «Таймаут соединения с SMTP-сервером.» | Сервер не ответил за 30 секунд | Проверьте сеть, `smtp.host` и `smtp.port`. | | «Не удалось подключиться к SMTP-серверу host:port» | Нет соединения с SMTP | Проверьте `smtp.host`, `smtp.port` и доступность сервера. | | «Ошибка отправки письма: ...» | Прочая ошибка SMTP | Смотрите детали после двоеточия; файл отчёта уже сохранён на диске. | | Предупреждение о правах конфига при старте | Права `config.yml` шире `0600` | `chmod 600 ~/.config/redmine-reporter/config.yml`. | | Предупреждение о MITM при старте | `verify_ssl: false` / `REDMINE_VERIFY=false` — проверка TLS отключена | Включите проверку или используйте только в доверенной сети. | | Не виден traceback при ошибке | Traceback показывается только с `--verbose`/`--debug` | Повторите запуск с `--debug`. | API-ключ в текстах ошибок маскируется (`***`). ## См. также - [README.md](../README.md) — обзор, быстрый старт, форматы вывода. - [CONFIG.md](CONFIG.md) — полный референс конфигурации (YAML, env, приоритеты, безопасность).