Support generate audio report by months

This commit is contained in:
2024-09-16 22:56:09 +08:00
parent 613f52218b
commit c0d8d4a56e
2 changed files with 61 additions and 2 deletions

View File

@@ -9,7 +9,13 @@ from .audio import (
from .cache import IdRelativeCache from .cache import IdRelativeCache
from .config import Config from .config import Config
from .db import PlaybackReportingDb, LibraryDb, JellyfinDb from .db import PlaybackReportingDb, LibraryDb, JellyfinDb
from .utils import gen_year_range, parse_datetime from .utils import (
YearMonth,
gen_month_range,
gen_year_range,
parse_datetime,
parse_year_month,
)
p = ArgumentParser(prog="jellyfinstats") p = ArgumentParser(prog="jellyfinstats")
@@ -32,6 +38,12 @@ audio_year.add_argument('year', action='extend', nargs='*', help=_("Generate yea
audio_year.add_argument('-s', '--start', help=_("The start year of range of years."), type=int) # noqa: E501 audio_year.add_argument('-s', '--start', help=_("The start year of range of years."), type=int) # noqa: E501
audio_year.add_argument('-e', '--end', help=_("The end year of range of years."), type=int) # noqa: E501 audio_year.add_argument('-e', '--end', help=_("The end year of range of years."), type=int) # noqa: E501
audio_year.add_argument('--utc', action='store_true', help=_("Use UTC time."), default=False) # noqa: E501 audio_year.add_argument('--utc', action='store_true', help=_("Use UTC time."), default=False) # noqa: E501
audio_month = audios.add_parser("month", help=_("Month report"))
audio_month.add_argument('month', action='extend', nargs='*', help=_("Generate month report for specify months."), default=[], type=parse_year_month) # noqa: E501
audio_month.add_argument('-s', '--start', help=_("The start month of range of months."), type=parse_year_month) # noqa: E501
audio_month.add_argument('-e', '--end', help=_("The end month of range of months."), type=parse_year_month) # noqa: E501
audio_month.add_argument('--utc', action='store_true', help=_("Use UTC time."), default=False) # noqa: E501
audio_month.add_argument('-y', '--year', action='append', help=_("Generate month report for specify years."), default=[], type=int) # noqa: E501
arg = p.parse_args() arg = p.parse_args()
if arg.action == 'a': if arg.action == 'a':
arg.action = 'audio' arg.action = 'audio'
@@ -75,3 +87,26 @@ with PlaybackReportingDb(cfg.playback_reporting_db) as pdb:
time = gen_year_range(year, arg.utc) time = gen_year_range(year, arg.utc)
toutput = join(output, str(year)) toutput = join(output, str(year))
generate_audio_report(pdb, re[0], re[1], re[2], toutput, userid, max(time[0], minTime.timestamp()), min(time[1], maxTime.timestamp())) # noqa: E501 generate_audio_report(pdb, re[0], re[1], re[2], toutput, userid, max(time[0], minTime.timestamp()), min(time[1], maxTime.timestamp())) # noqa: E501
elif arg.type == 'month':
minTime = parse_datetime(minDate)
minMonth = YearMonth(minTime.year, minTime.month)
maxTime = parse_datetime(maxDate)
maxMonth = YearMonth(maxTime.year, maxTime.month)
month = minMonth
while month <= maxMonth:
if arg.year and month.year not in arg.year:
month = YearMonth(month.year + 1, 1)
continue
if arg.month and month not in arg.month:
month += 1
continue
if arg.start is not None and month < arg.start:
month += 1
continue
if arg.end is not None and month > arg.end:
month += 1
continue
time = gen_month_range(month, arg.utc)
toutput = join(output, str(month.year), str(month.month).rjust(2, '0')) # noqa: E501
generate_audio_report(pdb, re[0], re[1], re[2], toutput, userid, max(time[0], minTime.timestamp()), min(time[1], maxTime.timestamp())) # noqa: E501
month += 1

View File

@@ -1,4 +1,5 @@
from math import ceil, floor from math import ceil, floor
from collections import namedtuple
from datetime import datetime, timezone from datetime import datetime, timezone
from re import compile from re import compile
from typing import Tuple from typing import Tuple
@@ -7,6 +8,7 @@ from .config import Config
DATETIME_RE = compile(r'(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2}).(\d{0,6})') # noqa: E501 DATETIME_RE = compile(r'(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2}).(\d{0,6})') # noqa: E501
YEARMONTH_RE = compile(r'^(\d{4})[-/]?(\d{2})$')
def ask_choice(cfg: Config, choices: list, prompt=_("Please choose: "), def ask_choice(cfg: Config, choices: list, prompt=_("Please choose: "),
@@ -111,4 +113,26 @@ def format_duration(duration: float | None) -> str:
def gen_year_range(year: int, utc: bool = False) -> Tuple[float, float]: def gen_year_range(year: int, utc: bool = False) -> Tuple[float, float]:
tz = timezone.utc if utc else None tz = timezone.utc if utc else None
return (datetime(year, 1, 1, tzinfo=tz).timestamp(), datetime(year, 12, 31, 23, 59, 59, 999999, tzinfo=tz).timestamp()) # noqa: E501 return (datetime(year, 1, 1, tzinfo=tz).timestamp(), datetime(year, 12, 31, 23, 59, 59, 999999, tz).timestamp()) # noqa: E501
YearMonth = namedtuple('YearMonth', ['year', 'month'])
YearMonth.__add__ = lambda a, b: YearMonth(floor((a.year * 12 + a.month + b - 1) / 12), (a.year * 12 + a.month + b - 1) % 12 + 1) # noqa: E501
YearMonth.__iadd__ = lambda a, b: YearMonth(floor((a.year * 12 + a.month + b - 1) / 12), (a.year * 12 + a.month + b - 1) % 12 + 1) # noqa: E501
def parse_year_month(time: str) -> YearMonth:
re = YEARMONTH_RE.match(time)
if re is None:
raise ValueError("Invalid year month: " + time)
month = int(re[2])
if month < 1 or month > 12:
raise ValueError(f"Invalid month: {month}")
return YearMonth(int(re[1]), month)
def gen_month_range(month: YearMonth,
utc: bool = False) -> Tuple[float, float]:
tz = timezone.utc if utc else None
n = month + 1
return (datetime(month.year, month.month, 1, tzinfo=tz).timestamp(), datetime(n.year, n.month, 1, tzinfo=tz).timestamp() - 1e-6) # noqa: E501