Config: Report author name
This commit is contained in:
@@ -2,9 +2,11 @@ import sys
|
||||
import argparse
|
||||
from typing import List, Optional
|
||||
from redminelib.resources import Issue
|
||||
|
||||
from .config import Config
|
||||
from .client import fetch_issues_with_spent_time
|
||||
from .formatter import format_compact, format_table
|
||||
from .formatter_odt import format_odt
|
||||
|
||||
|
||||
def parse_date_range(date_arg: str) -> tuple[str, str]:
|
||||
@@ -36,6 +38,11 @@ def main(argv: Optional[List[str]] = None) -> int:
|
||||
"--output",
|
||||
help="Path to output .odt file (e.g., report.odt). If omitted, prints to stdout."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--author",
|
||||
default="",
|
||||
help="Override author name from .env (REDMINE_AUTHOR)"
|
||||
)
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
try:
|
||||
@@ -67,8 +74,8 @@ def main(argv: Optional[List[str]] = None) -> int:
|
||||
print("❌ Output file must end with .odt", file=sys.stderr)
|
||||
return 1
|
||||
try:
|
||||
from .formatter_odt import format_odt
|
||||
doc = format_odt(issue_hours)
|
||||
author = Config.get_author(args.author)
|
||||
doc = format_odt(issue_hours, author=author, from_date=from_date, to_date=to_date)
|
||||
doc.save(args.output)
|
||||
print(f"✅ Report saved to {args.output}")
|
||||
except ImportError:
|
||||
|
||||
@@ -9,9 +9,19 @@ class Config:
|
||||
REDMINE_URL = os.getenv("REDMINE_URL", "").rstrip("/")
|
||||
REDMINE_USER = os.getenv("REDMINE_USER")
|
||||
REDMINE_PASSWORD = os.getenv("REDMINE_PASSWORD")
|
||||
REDMINE_AUTHOR = os.getenv("REDMINE_AUTHOR")
|
||||
DEFAULT_FROM_DATE = os.getenv("DEFAULT_FROM_DATE")
|
||||
DEFAULT_TO_DATE = os.getenv("DEFAULT_TO_DATE")
|
||||
|
||||
@classmethod
|
||||
def get_author(cls, cli_author: str = "") -> str:
|
||||
"""Возвращает автора: из CLI если задан, иначе из .env, иначе — заглушку."""
|
||||
if cli_author:
|
||||
return cli_author
|
||||
if cls.REDMINE_AUTHOR:
|
||||
return cls.REDMINE_AUTHOR
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
def get_default_date_range(cls) -> str:
|
||||
if cls.DEFAULT_FROM_DATE and cls.DEFAULT_TO_DATE:
|
||||
|
||||
@@ -6,9 +6,15 @@ from odf.text import P
|
||||
from odf.table import Table, TableColumn, TableRow, TableCell
|
||||
|
||||
from .formatter import get_version, hours_to_human, STATUS_TRANSLATION
|
||||
from .utils import get_month_name_from_range
|
||||
|
||||
|
||||
def format_odt(issue_hours: List[Tuple[Issue, float]]) -> "OpenDocument":
|
||||
def format_odt(
|
||||
issue_hours: List[Tuple[Issue, float]],
|
||||
author: str = "",
|
||||
from_date: str = "",
|
||||
to_date: str = ""
|
||||
) -> "OpenDocument":
|
||||
template_path = "template.odt"
|
||||
if not os.path.exists(template_path):
|
||||
raise FileNotFoundError("Шаблон template.odt не найден...")
|
||||
@@ -17,7 +23,8 @@ def format_odt(issue_hours: List[Tuple[Issue, float]]) -> "OpenDocument":
|
||||
para_style_name = "Standard"
|
||||
|
||||
# Заголовок
|
||||
header_text = "Кокос Артём Николаевич. Отчет за месяц Июль."
|
||||
month_name = get_month_name_from_range(from_date, to_date)
|
||||
header_text = f"{author}. Отчет за месяц {month_name}."
|
||||
header_paragraph = P(stylename=para_style_name, text=header_text)
|
||||
doc.text.addElement(header_paragraph)
|
||||
|
||||
|
||||
@@ -1,2 +1,27 @@
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
def get_month_name_from_range(from_date: str, to_date: str) -> str:
|
||||
"""Определяет название месяца по диапазону дат.
|
||||
Если from == to — возвращает месяц этой даты.
|
||||
Если диапазон охватывает несколько месяцев — возвращает 'период'.
|
||||
"""
|
||||
|
||||
try:
|
||||
start = datetime.strptime(from_date, "%Y-%m-%d")
|
||||
end = datetime.strptime(to_date, "%Y-%m-%d")
|
||||
except ValueError:
|
||||
return "период"
|
||||
|
||||
if start.year == end.year and start.month == end.month:
|
||||
months = [
|
||||
"", "Январь", "Февраль", "Март", "Апрель", "Май", "Июнь",
|
||||
"Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"
|
||||
]
|
||||
return months[start.month]
|
||||
else:
|
||||
return "период"
|
||||
|
||||
|
||||
def get_version(issue) -> str:
|
||||
return str(getattr(issue, 'fixed_version', '<N/A>'))
|
||||
|
||||
Reference in New Issue
Block a user