This commit is contained in:
Кокос Артем Николаевич
2026-02-05 15:31:31 +07:00
parent d7e927e6eb
commit 06cd57e2c4
14 changed files with 102 additions and 87 deletions

View File

@@ -8,15 +8,17 @@ class TableFormatter(Formatter):
"""Форматтер для вывода красивой таблицы в консоль."""
def format(self, rows: List[ReportRow]) -> str:
table_rows = [['Проект', 'Версия', 'Задача', 'Статус', 'Затрачено']]
table_rows = [["Проект", "Версия", "Задача", "Статус", "Затрачено"]]
for r in rows:
table_rows.append([
r['display_project'],
r['display_version'],
f"{r['issue_id']}. {r['subject']}",
r['status_ru'],
r['time_text']
])
table_rows.append(
[
r["display_project"],
r["display_version"],
f"{r['issue_id']}. {r['subject']}",
r["status_ru"],
r["time_text"],
]
)
return tabulate(table_rows, headers="firstrow", tablefmt="fancy_grid")
def save(self, rows: List[ReportRow], output_path: str) -> None:
@@ -24,6 +26,7 @@ class TableFormatter(Formatter):
# Это делается в CLI.
raise NotImplementedError("TableFormatter не поддерживает сохранение в файл.")
class CompactFormatter(Formatter):
"""Форматтер для компактного вывода в консоль."""

View File

@@ -16,14 +16,16 @@ class CSVFormatter(Formatter):
writer = csv.writer(output, dialect="excel")
writer.writerow(["Project", "Version", "Issue ID", "Subject", "Status", "Spent Time"])
for r in rows:
writer.writerow([
r["project"],
r["version"],
r["issue_id"],
r["subject"],
r["status_ru"],
r["time_text"]
])
writer.writerow(
[
r["project"],
r["version"],
r["issue_id"],
r["subject"],
r["status_ru"],
r["time_text"],
]
)
return output.getvalue()
def save(self, rows: List[ReportRow], output_path: str) -> None:

View File

@@ -6,7 +6,6 @@ from .markdown import MarkdownFormatter
from .odt import ODTFormatter
from .html import HTMLFormatter
# Словарь для сопоставления расширений файлов с классами форматтеров
FORMATTER_MAP: Dict[str, Type[Formatter]] = {
".odt": ODTFormatter,

View File

@@ -12,7 +12,7 @@ class MarkdownFormatter(Formatter):
def format(self, rows: List[ReportRow]) -> str:
lines = [
"| Проект | Версия | Задача | Статус | Затрачено |",
"|--------|--------|--------|--------|-----------|"
"|--------|--------|--------|--------|-----------|",
]
for r in rows:
task_cell = f"{r['issue_id']}. {r['subject']}"

View File

@@ -26,7 +26,11 @@ class ODTFormatter(Formatter):
Форматирует данные в объект OpenDocument.
"""
with resources.files("redmine_reporter").joinpath("templates", "template.odt").open("rb") as f:
with (
resources.files("redmine_reporter")
.joinpath("templates", "template.odt")
.open("rb") as f
):
doc = load(f)
para_style_name = "Standard"
@@ -56,7 +60,13 @@ class ODTFormatter(Formatter):
# Заголовки
header_row = TableRow()
for text in ["Наименование Проекта", "Номер версии*", "Задача", "Статус Готовность*", "Затрачено за отчетный период"]:
for text in [
"Наименование Проекта",
"Номер версии*",
"Задача",
"Статус Готовность*",
"Затрачено за отчетный период",
]:
cell = TableCell(stylename=cell_style_name)
cell.addElement(P(stylename=para_style_name, text=text))
header_row.addElement(cell)
@@ -77,7 +87,9 @@ class ODTFormatter(Formatter):
# Данные с двухуровневой группировкой и объединением ячеек
for project, versions in projects.items():
total_project_rows = sum(len(rows_for_version) for rows_for_version in versions.values())
total_project_rows = sum(
len(rows_for_version) for rows_for_version in versions.values()
)
first_version_in_project = True
for version, rows_for_version in versions.items():
@@ -137,7 +149,7 @@ class ODTFormatter(Formatter):
"«Задача» - Номер по Redmine и формулировка.",
"«Статус» - Актуальное состояние задачи на момент отчета. Статусы: закрыто, в работе, ожидание, решена.",
"«Готовность» Опциональное поле в процентах.",
"«Затрачено за отчетный период» - в днях или часах."
"«Затрачено за отчетный период» - в днях или часах.",
]:
doc.text.addElement(P(stylename=para_style_name, text=line))