from abc import ABC, abstractmethod from typing import List from .models import IssueRecord from tabulate import tabulate STATUS_MAP = { 'Closed': 'Закрыто', 'Re-opened': 'В работе', 'New': 'В работе', 'Resolved': 'Решена', 'Pending': 'Ожидание', 'Feedback': 'В работе', 'In Progress': 'В работе', 'Rejected': 'Закрыто', 'Confirming': 'Ожидание', } def localize_status(status: str) -> str: return STATUS_MAP.get(status, status) class ReportFormatter(ABC): @abstractmethod def format(self, records: List[IssueRecord]) -> str: pass class SimpleFormatter(ReportFormatter): def format(self, records: List[IssueRecord]) -> str: if not records: return "No issues found." lines = [] prev_project = prev_version = None for r in records: proj = r.project if r.project != prev_project else "" ver = r.version if (r.project != prev_project or r.version != prev_version) else "" lines.append(f"{proj} | {ver} | {r.issue_id}. {r.subject} | {r.status}") prev_project, prev_version = r.project, r.version return "\n".join(lines) class TabulateFormatter(ReportFormatter): def format(self, records: List[IssueRecord]) -> str: if not records: return "No issues found." rows = [["Проект", "Версия", "Задача", "Статус", "Затрачено"]] prev_project = prev_version = None for r in records: proj = r.project if r.project != prev_project else "" ver = r.version if (r.project != prev_project or r.version != prev_version) else "" rows.append([ proj, ver, f"{r.issue_id}. {r.subject}", localize_status(r.status), "" # placeholder ]) prev_project, prev_version = r.project, r.version return tabulate(rows, headers="firstrow", tablefmt="fancy_grid")