Files
redmine-reporter/docs/USER_GUIDE.md
Кокос Артем Николаевич f00c6705ba feat: filter Wishlist from --my-tasks; document the mode (#71)
Tasks in the "Wishlist" bucket version are now excluded from the list
and summary entirely (no due date, noise backlog); exact case match,
tasks without a version are unaffected. Document --my-tasks in README
and the user guide (sorting, summary metrics, OSC 8 links, stream
separation); all examples use synthetic data. Declare ruff
known-first-party in pyproject so the lint result is CWD-independent.
2026-10-28 15:53:50 +07:00

26 KiB
Raw Permalink Blame History

Руководство пользователя redmine-reporter

Оглавление

Установка

Требуется Python >= 3.10.

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 .

Проверка:

redmine-reporter --version

Перед каждым запуском активируйте окружение: source .venv/bin/activate.

Первоначальная настройка

  1. Убедитесь, что в текущей директории есть .env с REDMINE_URL и REDMINE_API_KEY (или задайте эти переменные в окружении).
  2. Сгенерируйте YAML-конфиг:
redmine-reporter --init-config

Результат: файл ~/.config/redmine-reporter/config.yml (права 0600, директория 0700) со всеми секциями и закомментированным примером report.status_translation. Секреты, заданные в окружении, записываются как ${VAR}.

  1. Если файл уже существует — ошибка; для перезаписи добавьте --force:
redmine-reporter --init-config --force
  1. Нестандартное расположение конфига:
redmine-reporter --init-config --config-path /etc/redmine-reporter/config.yml

--config-path задаёт путь и для загрузки YAML, и для записи при --init-config и --commit.

  1. Откройте файл и заполните минимум: 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.

Выбор периода

Окно отчёта — диапазон дат from..to. Конец (to) всегда сегодняшняя дата, если диапазон не задан явно через --date.

Приоритет начала окна (от высшего к низшему):

  1. --date — явный диапазон (полностью переопределяет окно).
  2. FROM_DATE (env) — начало; конец — сегодня.
  3. period.from (YAML) — начало; конец — сегодня.
  4. Ничего не задано — текущий месяц: с 1-го числа по сегодня.

Форматы --date:

# Даты
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 + текущий месяц.

Отчёт за другого пользователя

Без флагов отчёт строится за текущего пользователя.

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...».

Список открытых задач

--my-tasks -- отдельный режим: вместо отчёта по затраченному времени выводит открытые задачи, назначенные на вас, по всем проектам. Отчётное окно периода к режиму не применяется.

redmine-reporter --my-tasks                       # задачи владельца API-ключа
redmine-reporter --my-tasks --user-id 42          # чужой список по ID
redmine-reporter --my-tasks --user-login ivanov   # по логину

Правила:

  • --user-id / --user-login / --user-name выбирают, чей список показать; по умолчанию -- владелец API-ключа. Разрешение пользователей то же, что для отчёта (см. Отчёт за другого пользователя).
  • --url, --api-key, --config, --config-path, --verbose, --debug работают как обычно.
  • Совмещение с отчётными флагами (--date, --output, --compact, --summary, --no-time, --by-activity, --commit, --send) -- ошибка «--my-tasks cannot be used with report-generating flags.», exit 1.
  • Задачи в версии Wishlist исключаются из режима целиком: не попадают ни в таблицу, ни в сводку.

Сортировка -- от срочного к менее срочному:

  1. Приоритет P1..P5: меньший номер срочнее; неизвестное имя приоритета получает низший ранг.
  2. Внутри приоритетной группы -- срок версии (due date) по возрастанию.
  3. Задачи без версии или без срока -- в конец своей приоритетной группы.
  4. При прочих равных -- по возрастанию ID.

Таблица печатается в stdout, сводка -- в stderr перед таблицей. При перенаправлении (redmine-reporter --my-tasks > tasks.txt) в файл попадает только таблица.

Колонки таблицы: ID | Тема | Статус | Приор. | Версия | Срок. Пример (синтетические данные, ID в терминале кликабелен):

  ID  Тема                              Статус          Приор.    Версия    Срок
----  --------------------------------  --------------  --------  --------  --------------
 101  Критический дефект сборки образа  В работе        P1        v2.4.0    2026-10-15 (!)
 102  Обновить документацию API         Новая           P2        v2.5.0    2026-12-01
 103  Ревью pull request                Обратная связь  P3        -         -
  • ID -- гиперссылка (OSC 8) на страницу задачи <url>/issues/<id>: в терминалах с поддержкой кликабельна, без поддержки остаётся обычным номером.
  • Срок -- дата релиза целевой версии; просроченный (раньше сегодняшней даты) помечается (!).
  • Пустые «Версия» и «Срок» -- прочерк -.
  • Статусы переводятся на русский тем же словарём, что и в отчётах: встроенный словарь + report.status_translation (см. Перевод статусов).

Сводка (пример с синтетическими данными):

Открытых: 3 | просроченных: 1 | без версии: 1 | без срока: 0 | потрачено: 12.5h | оценка: 8h (по 2 из 3)
  • «просроченных» -- задачи со сроком версии раньше сегодняшней даты.
  • «без версии» -- задачи без целевой версии; «без срока» -- задачи с версией, но без известной даты релиза.
  • «потрачено» -- сумма полей spent_hours задач списка.
  • «оценка» -- сумма полей estimated_hours; «(по N из M)» -- у скольких задач из списка есть оценка. Если оценок нет ни у одной задачи, блок «оценка» не выводится.

Сроки версий дозагружаются отдельным запросом на каждую уникальную версию списка. Недоступная версия -- предупреждение в stderr и пустой срок у её задач, вывод не прерывается.

Пустой список (в том числе когда все открытые задачи попали в исключаемую версию Wishlist): «ℹ️ Открытых задач нет.» (stderr), exit 0.

Экспорт в файл

Флаг --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 (устанавливается по умолчанию) — иначе отдельная ошибка.

Примеры:

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 дополнительно пропадают строки итогов по версиям/проектам/всего.

redmine-reporter --output report.xlsx --no-time

YAML-настройка report.no_time действует только в автоматических режимах (--commit, --send). При ручном --output работает только CLI-флаг.

--by-activity

Разбивка затраченного времени по типам активности. В JSON-отчёте добавляется поле activities.

redmine-reporter --by-activity

--summary

Печатает сводку в stderr (после отчёта):

  • total — суммарное время;
  • project:* — время по каждому проекту;
  • activity:* — время по каждой активности (только при одновременном --by-activity).

Версии в сводку не входят.

redmine-reporter --by-activity --summary

--compact

Компактный текстовый вывод в консоль вместо таблицы:

redmine-reporter --compact

Перевод статусов

Статусы задач переводятся встроенным словарём; секция report.status_translation переопределяет или дополняет переводы. Подробно: CONFIG.md.

Отправка по email

Требуется секция email в YAML-конфиге (см. CONFIG.md).

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 начинается с граничного дня последнего отчёта.

Типичный цикл:

# 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 после сохранения файла; при подтверждении и успехе сдвинуть начало периода.
--my-tasks Вместо отчёта вывести открытые задачи, назначенные на вас (или на пользователя из --user-id/--user-login/--user-name): таблица с сортировкой по срочности + сводка в stderr. Несовместим с --date, --output, --compact, --summary, --no-time, --by-activity, --commit, --send. Подробнее: Список открытых задач.

Устранение неполадок

Ошибка Причина Решение
«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.
«--my-tasks cannot be used with report-generating flags.» (exit 1) --my-tasks совмещён с отчётными флагами (--date, --output, --compact, --summary, --no-time, --by-activity, --commit, --send) Запускайте режим отдельно: список задач и отчёт -- разные команды (см. Список открытых задач).
«Неизвестный формат файла: '.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).
«Ошибка аутентификации 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 отключена Включите проверку или используйте только в доверенной сети.
«⚠️ Could not load version ...: Due date will be empty for its issues.» в режиме --my-tasks Версия из списка задач недоступна (нет прав, удалена, сбой сети) Некритично: срок этой версии останется пустым; проверьте права доступа к проекту версии.
Не виден traceback при ошибке Traceback показывается только с --verbose/--debug Повторите запуск с --debug.

API-ключ в текстах ошибок маскируется (***).

См. также

  • README.md — обзор, быстрый старт, форматы вывода.
  • CONFIG.md — полный референс конфигурации (YAML, env, приоритеты, безопасность).