#43 — Имя файла и пути по умолчанию: - resolve_output_path() в yaml_config.py: резолвит --output с учётом output.dir, filename_template, default_format из YAML-конфига - Bare format (xlsx/odt/...) → путь по шаблону - Без расширения → автодописывается default_format (.xlsx) - Config.get_output_dir/filename/default_format() #47 — datetime precision и дедупликация: - period.last_used.from/to в YAML-конфиге и AppConfig - period.precision: date|datetime - _compute_dedup_cutoff() в cli.py: при precision=datetime вычисляет cutoff из period.last_used.to - _parse_datetime() + AND-логика дедупликации в client.py: запись исключается если created_on И updated_on < cutoff - Пропуск issues без часов после дедупликации Closes #43 Closes #47
This commit is contained in:
@@ -40,6 +40,12 @@ class EmailConfig:
|
||||
attach: bool = True
|
||||
|
||||
|
||||
@dataclass
|
||||
class PeriodLastUsed:
|
||||
from_: str = ""
|
||||
to: str = ""
|
||||
|
||||
|
||||
@dataclass
|
||||
class AppConfig:
|
||||
redmine_url: str = ""
|
||||
@@ -50,6 +56,8 @@ class AppConfig:
|
||||
period_default_from: str = ""
|
||||
period_default_to: str = ""
|
||||
period_dynamic: bool = False
|
||||
period_last_used_from: str = ""
|
||||
period_last_used_to: str = ""
|
||||
output_dir: str = ""
|
||||
output_filename: str = "{author}_{from}_{to}.{ext}"
|
||||
output_default_format: str = "xlsx"
|
||||
@@ -93,6 +101,8 @@ class AppConfig:
|
||||
period_default_from=cls._resolve_str(raw, "period", "default_from"),
|
||||
period_default_to=cls._resolve_str(raw, "period", "default_to"),
|
||||
period_dynamic=cls._resolve_bool(raw, "period", "dynamic"),
|
||||
period_last_used_from=cls._resolve_str(raw, "period", "last_used", "from"),
|
||||
period_last_used_to=cls._resolve_str(raw, "period", "last_used", "to"),
|
||||
output_dir=cls._resolve_str(raw, "output", "dir"),
|
||||
output_filename=cls._resolve_str(raw, "output", "filename")
|
||||
or "{author}_{from}_{to}.{ext}",
|
||||
@@ -112,8 +122,14 @@ class AppConfig:
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _resolve_str(raw: dict, section: str, key: str) -> str:
|
||||
value = raw.get(section, {}).get(key, "")
|
||||
def _resolve_str(raw: dict, section: str, *keys: str) -> str:
|
||||
value = raw.get(section)
|
||||
for key in keys:
|
||||
if isinstance(value, dict):
|
||||
value = value.get(key)
|
||||
else:
|
||||
value = None
|
||||
break
|
||||
if isinstance(value, str):
|
||||
return resolve_env_vars(value)
|
||||
if value is None:
|
||||
@@ -291,6 +307,42 @@ class Config:
|
||||
return cls._app.redmine_author
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
def get_period_precision(cls) -> str:
|
||||
if cls._app:
|
||||
return cls._app.period_precision or "date"
|
||||
return "date"
|
||||
|
||||
@classmethod
|
||||
def get_last_used_from(cls) -> str:
|
||||
if cls._app:
|
||||
return cls._app.period_last_used_from
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
def get_last_used_to(cls) -> str:
|
||||
if cls._app:
|
||||
return cls._app.period_last_used_to
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
def get_output_dir(cls) -> str:
|
||||
if cls._app:
|
||||
return cls._app.output_dir
|
||||
return ""
|
||||
|
||||
@classmethod
|
||||
def get_output_filename(cls) -> str:
|
||||
if cls._app:
|
||||
return cls._app.output_filename or "{author}_{from}_{to}.{ext}"
|
||||
return "{author}_{from}_{to}.{ext}"
|
||||
|
||||
@classmethod
|
||||
def get_output_default_format(cls) -> str:
|
||||
if cls._app:
|
||||
return cls._app.output_default_format or "xlsx"
|
||||
return "xlsx"
|
||||
|
||||
@classmethod
|
||||
def get_default_date_range(cls) -> str:
|
||||
from_env = os.getenv("DEFAULT_FROM_DATE", "").strip()
|
||||
|
||||
Reference in New Issue
Block a user