# Руководство пользователя redmine-reporter ## Оглавление - [Установка](#установка) - [Первоначальная настройка](#первоначальная-настройка) - [Выбор периода](#выбор-периода) - [Отчёт за другого пользователя](#отчёт-за-другого-пользователя) - [Экспорт в файл](#экспорт-в-файл) - [Содержимое отчёта](#содержимое-отчёта) - [Отправка по email](#отправка-по-email) - [Ежемесячный цикл с --commit](#ежемесячный-цикл-с---commit) - [Справочник флагов](#справочник-флагов) - [Устранение неполадок](#устранение-неполадок) - [См. также](#см-также) ## Установка Требуется 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). ## Выбор периода Источник периода выбирается по приоритету (от высшего к низшему): 1. `--date` — явный диапазон. 2. `DEFAULT_FROM_DATE` (env/.env) — конец: `DEFAULT_TO_DATE` или сегодня. `DEFAULT_TO_DATE` без `DEFAULT_FROM_DATE` игнорируется. 3. `period.dynamic: true` + `period.last_used` в YAML — следующий период после `last_used`: - последний период — полный календарный месяц → следующий полный месяц; - произвольный диапазон → та же длительность, начиная со дня после `last_used.to`; - при `precision: datetime` → та же длительность, сдвинутая на 1 секунду после `last_used.to`. 4. `period.default_from` в YAML — конец: `default_to` или сегодня. `default_to` без `default_from` игнорируется. 5. Ничего не задано → текущий месяц: с 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 ``` Смешанная точность (дата + дата-время в одном диапазоне) и диапазон, где начало позже конца, отвергаются с ошибкой. ## Отчёт за другого пользователя Без флагов отчёт строится за текущего пользователя. ```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 файл остаётся на месте. - Секция `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 `--commit` сохраняет отчёт в файл (по `--output` или по шаблону `output.dir`/`output.filename`) и записывает `period.last_used` в YAML-конфиг. Что пишется: - `precision: datetime` → `last_used.from` = `last_used.to` = текущий момент UTC. - `precision: date` → фактические `from`/`to` использованного периода. - `dynamic: true` → `default_from`/`default_to` не меняются. - `dynamic: false` → дополнительно перезаписываются `default_from`/`default_to`. Типичный цикл: ```bash # 1. Отчёт за июнь 2026: сохранить файл, зафиксировать период redmine-reporter --date 2026-06-01--2026-06-30 --send --commit # 2. Следующий запуск без --date возьмёт июль 2026 автоматически # (при dynamic: true и полном месяце) redmine-reporter --send --commit ``` Защита от дублей при `precision: datetime`: - Если в YAML есть `last_used.to` (cutoff), time entry сохраняется в отчёт, только если `created_on` И `updated_on` оба >= cutoff; если хотя бы одно поле раньше cutoff — запись исключается. - Записи, у которых оба поля (`created_on`, `updated_on`) отсутствуют, сохраняются; если задано только одно поле, решает оно. - Фильтр применяется всегда при `precision: datetime`, в том числе при явном `--date`. Важно: `--commit` перезаписывает YAML через `yaml.dump` — пользовательские комментарии в файле теряются. ## Справочник флагов | Флаг | Описание | | --- | --- | | `--date` | Диапазон периода: `YYYY-MM-DD--YYYY-MM-DD` или `YYYY-MM-DDTHH:MM:SS--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.last_used`) в 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, приоритеты, безопасность).