Add fix incorrect play duration
This commit is contained in:
@@ -1,7 +1,11 @@
|
|||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from os.path import join
|
from os.path import join
|
||||||
from . import _
|
from . import _
|
||||||
from .audio import prepare_audio_map, generate_audio_report
|
from .audio import (
|
||||||
|
prepare_audio_map,
|
||||||
|
generate_audio_report,
|
||||||
|
fix_audio_report_library,
|
||||||
|
)
|
||||||
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
|
||||||
@@ -15,9 +19,12 @@ p.add_argument("--jellyfin-data-dir", help=_("The path to jellyfin data director
|
|||||||
p.add_argument("--output-dir", help=_("The directory for output files."))
|
p.add_argument("--output-dir", help=_("The directory for output files."))
|
||||||
p.add_argument("--ask-page-size", help=_("Specify maximum items to display in one page."), type=int) # noqa: E501
|
p.add_argument("--ask-page-size", help=_("Specify maximum items to display in one page."), type=int) # noqa: E501
|
||||||
p.add_argument("--jellyfin-db", help=_("The path to jellyfin.db"))
|
p.add_argument("--jellyfin-db", help=_("The path to jellyfin.db"))
|
||||||
|
p.add_argument("--fix", help=_("Fix incorrect play duration."), action='store_true', default=False) # noqa: E501
|
||||||
arg = p.parse_intermixed_args()
|
arg = p.parse_intermixed_args()
|
||||||
cfg = Config(arg.config, arg)
|
cfg = Config(arg.config, arg)
|
||||||
with PlaybackReportingDb(cfg.playback_reporting_db) as pdb:
|
with PlaybackReportingDb(cfg.playback_reporting_db) as pdb:
|
||||||
|
if arg.fix:
|
||||||
|
fix_audio_report_library(pdb)
|
||||||
with LibraryDb(cfg.library_db) as ldb:
|
with LibraryDb(cfg.library_db) as ldb:
|
||||||
with IdRelativeCache(cfg.output_dir) as icache:
|
with IdRelativeCache(cfg.output_dir) as icache:
|
||||||
with JellyfinDb(cfg.jellyfin_db) as jdb:
|
with JellyfinDb(cfg.jellyfin_db) as jdb:
|
||||||
@@ -30,4 +37,5 @@ with PlaybackReportingDb(cfg.playback_reporting_db) as pdb:
|
|||||||
output = join(cfg.output_dir, 'audio', username)
|
output = join(cfg.output_dir, 'audio', username)
|
||||||
maxDate = u['MaxDate']
|
maxDate = u['MaxDate']
|
||||||
minDate = u['MinDate']
|
minDate = u['MinDate']
|
||||||
generate_audio_report(pdb, re[0], re[1], re[2], output, userid)
|
generate_audio_report(
|
||||||
|
pdb, re[0], re[1], re[2], output, userid)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from datetime import datetime
|
|||||||
from re import compile
|
from re import compile
|
||||||
from os import makedirs
|
from os import makedirs
|
||||||
from os.path import join
|
from os.path import join
|
||||||
from math import floor
|
from math import ceil, floor
|
||||||
|
|
||||||
|
|
||||||
ITEMNAME_PATTERN = compile(r'(?P<album_artist>.*) - (?P<track>.*) \((?P<album>.*)\)') # noqa: E501
|
ITEMNAME_PATTERN = compile(r'(?P<album_artist>.*) - (?P<track>.*) \((?P<album>.*)\)') # noqa: E501
|
||||||
@@ -405,3 +405,31 @@ def generate_audio_report(pdb: PlaybackReportingDb, itemMap, rowMap, albumMap,
|
|||||||
for artist in alArtCountMap:
|
for artist in alArtCountMap:
|
||||||
count = alArtCountMap[artist]
|
count = alArtCountMap[artist]
|
||||||
alAr.write(artist, count['count'], count['play_count'], format_duration(count['duration']), count['duration']) # noqa: E501
|
alAr.write(artist, count['count'], count['play_count'], format_duration(count['duration']), count['duration']) # noqa: E501
|
||||||
|
|
||||||
|
|
||||||
|
def fix_audio_report_library(pdb: PlaybackReportingDb):
|
||||||
|
clients = pdb.get_client_devices()
|
||||||
|
for client in clients:
|
||||||
|
clientName = client['ClientName']
|
||||||
|
deviceName = client['DeviceName']
|
||||||
|
prev = None
|
||||||
|
offset = 0
|
||||||
|
data = pdb.get_activitys(offset, itemType='Audio',
|
||||||
|
clientName=clientName,
|
||||||
|
deviceName=deviceName)
|
||||||
|
while len(data) > 0:
|
||||||
|
for i in data:
|
||||||
|
if prev is None:
|
||||||
|
prev = i
|
||||||
|
continue
|
||||||
|
delta = ceil(parse_time(
|
||||||
|
i['DateCreated']) - parse_time(prev['DateCreated']))
|
||||||
|
dur = prev['PlayDuration']
|
||||||
|
if delta < dur - 1:
|
||||||
|
print(f'Change song(id={prev["rowid"]}) play duration from {dur} to {delta}') # noqa: E501
|
||||||
|
pdb.update_playduration(prev["rowid"], delta)
|
||||||
|
prev = i
|
||||||
|
offset += len(data)
|
||||||
|
data = pdb.get_activitys(offset, itemType='Audio',
|
||||||
|
clientName=clientName,
|
||||||
|
deviceName=deviceName)
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ class PlaybackReportingDb:
|
|||||||
|
|
||||||
def get_activitys(self, offset: int = 0, limit: int = 100,
|
def get_activitys(self, offset: int = 0, limit: int = 100,
|
||||||
itemType: str = None, userId: str = None,
|
itemType: str = None, userId: str = None,
|
||||||
startTime: float = None, endTime: float = None):
|
startTime: float = None, endTime: float = None,
|
||||||
|
clientName: str = None, deviceName: str = None):
|
||||||
where_sqls = []
|
where_sqls = []
|
||||||
where_sql = ''
|
where_sql = ''
|
||||||
args = []
|
args = []
|
||||||
@@ -37,6 +38,12 @@ class PlaybackReportingDb:
|
|||||||
if endTime is not None:
|
if endTime is not None:
|
||||||
where_sqls.append('DateCreated <= ?')
|
where_sqls.append('DateCreated <= ?')
|
||||||
args.append(format_time(endTime))
|
args.append(format_time(endTime))
|
||||||
|
if clientName is not None:
|
||||||
|
where_sqls.append("ClientName = ?")
|
||||||
|
args.append(clientName)
|
||||||
|
if deviceName is not None:
|
||||||
|
where_sqls.append("DeviceName = ?")
|
||||||
|
args.append(deviceName)
|
||||||
if len(where_sqls):
|
if len(where_sqls):
|
||||||
where_sql = ' WHERE ' + " AND ".join(where_sqls)
|
where_sql = ' WHERE ' + " AND ".join(where_sqls)
|
||||||
args.append(limit)
|
args.append(limit)
|
||||||
@@ -45,6 +52,11 @@ class PlaybackReportingDb:
|
|||||||
cur.row_factory = sqlite3.Row
|
cur.row_factory = sqlite3.Row
|
||||||
return [dict(i) for i in cur.fetchall()]
|
return [dict(i) for i in cur.fetchall()]
|
||||||
|
|
||||||
|
def get_client_devices(self):
|
||||||
|
cur = self._db.execute("SELECT ClientName, DeviceName FROM PlaybackActivity GROUP BY ClientName, DeviceName;") # noqa: E501
|
||||||
|
cur.row_factory = sqlite3.Row
|
||||||
|
return [dict(i) for i in cur.fetchall()]
|
||||||
|
|
||||||
def get_users(self, itemType: str = None):
|
def get_users(self, itemType: str = None):
|
||||||
where_sql = ''
|
where_sql = ''
|
||||||
args = []
|
args = []
|
||||||
@@ -55,6 +67,9 @@ class PlaybackReportingDb:
|
|||||||
cur.row_factory = sqlite3.Row
|
cur.row_factory = sqlite3.Row
|
||||||
return [dict(i) for i in cur.fetchall()]
|
return [dict(i) for i in cur.fetchall()]
|
||||||
|
|
||||||
|
def update_playduration(self, rowid: int, duration: int):
|
||||||
|
self._db.execute("UPDATE PlaybackActivity SET PlayDuration = ? WHERE rowid = ?;", [duration, rowid]) # noqa: E501
|
||||||
|
|
||||||
|
|
||||||
class LibraryDb:
|
class LibraryDb:
|
||||||
def __init__(self, fn: str):
|
def __init__(self, fn: str):
|
||||||
|
|||||||
Reference in New Issue
Block a user