Support generate audio report by months
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user