|
@@ -1,15 +1,14 @@
|
|
|
-# -*- coding: utf-8 -*-
|
|
|
-
|
|
|
import datetime as dt
|
|
|
-import mutagen
|
|
|
import os
|
|
|
import re
|
|
|
|
|
|
+import mutagen
|
|
|
+
|
|
|
import symuid.tag_interface
|
|
|
|
|
|
|
|
|
-def _timestamp_to_utc_dt(ts):
|
|
|
- return dt.datetime.utcfromtimestamp(ts) \
|
|
|
+def _timestamp_to_utc_dt(ts_sec):
|
|
|
+ return dt.datetime.utcfromtimestamp(ts_sec) \
|
|
|
.replace(tzinfo=dt.timezone.utc)
|
|
|
|
|
|
|
|
@@ -29,6 +28,7 @@ class PlayCount:
|
|
|
self.count = count
|
|
|
|
|
|
def __eq__(self, other):
|
|
|
+ # pylint: disable=unidiomatic-typecheck
|
|
|
return type(self) == type(other) and vars(self) == vars(other)
|
|
|
|
|
|
def __hash__(self):
|
|
@@ -37,7 +37,7 @@ class PlayCount:
|
|
|
|
|
|
def __repr__(self):
|
|
|
return 'PlayCount({})'.format(', '.join(
|
|
|
- '{}={!r}'.format(k, v) for k, v in vars(self).items(),
|
|
|
+ '{}={!r}'.format(k, v) for k, v in vars(self).items()
|
|
|
))
|
|
|
|
|
|
|
|
@@ -46,11 +46,10 @@ class Track:
|
|
|
PATH_DEFAULT_IGNORE_REGEX = r'\.(itdb|itc2|itl|jpg|midi?|plist|xml|zip)$'
|
|
|
|
|
|
def __init__(self, path):
|
|
|
- mutagen_file = mutagen.File(filename=path)
|
|
|
- # TODO support mp3 files without ID3 headers
|
|
|
+ mutagen_file = mutagen.File(path)
|
|
|
if mutagen_file is None:
|
|
|
raise NotImplementedError(path)
|
|
|
- elif isinstance(mutagen_file.tags, mutagen.id3.ID3):
|
|
|
+ if isinstance(mutagen_file.tags, mutagen.id3.ID3):
|
|
|
self._iface = symuid.tag_interface.ID3(mutagen_file)
|
|
|
elif isinstance(mutagen_file.tags, mutagen.mp4.MP4Tags):
|
|
|
self._iface = symuid.tag_interface.MP4(mutagen_file)
|
|
@@ -88,13 +87,13 @@ class Track:
|
|
|
label += ':' + library_id
|
|
|
elif library_id:
|
|
|
raise Exception((player, library_id))
|
|
|
- for k, c in self._iface.get_free_ints(label):
|
|
|
+ for k, count in self._iface.get_free_ints(label):
|
|
|
player, library_id, register_ts_dec = k.split(':')[2:]
|
|
|
yield PlayCount(
|
|
|
player=player,
|
|
|
library_id=library_id,
|
|
|
register_dt=_timestamp_to_utc_dt(int(register_ts_dec)),
|
|
|
- count=c,
|
|
|
+ count=count,
|
|
|
)
|
|
|
|
|
|
def _get_latest_play_counts(self, player=None, library_id=None):
|
|
@@ -113,26 +112,26 @@ class Track:
|
|
|
counts = self._get_latest_play_counts(player, library_id)
|
|
|
if len(counts) == 0:
|
|
|
return None
|
|
|
- else:
|
|
|
- assert len(counts) == 1, counts
|
|
|
- return counts[0]
|
|
|
+ assert len(counts) == 1, counts
|
|
|
+ return counts[0]
|
|
|
|
|
|
def get_play_count_sum(self, player=None, library_id=None):
|
|
|
return sum(c.count for c in self._get_latest_play_counts(player, library_id))
|
|
|
|
|
|
- def register_play_count(self, pc, tag_set_cb=None):
|
|
|
- assert isinstance(pc, PlayCount), pc
|
|
|
+ def register_play_count(self, play_count, tag_set_cb=None):
|
|
|
+ assert isinstance(play_count, PlayCount), play_count
|
|
|
tag_label = 'symuid:pcnt:{}:{}:{:.0f}'.format(
|
|
|
- pc.player, pc.library_id, pc.register_dt.timestamp(),
|
|
|
+ play_count.player, play_count.library_id,
|
|
|
+ play_count.register_dt.timestamp(),
|
|
|
)
|
|
|
current_count = self._iface.get_free_int(tag_label)
|
|
|
if current_count is None:
|
|
|
- new_tag = self._iface.set_free_int(tag_label, pc.count)
|
|
|
+ new_tag = self._iface.set_free_int(tag_label, play_count.count)
|
|
|
self._iface.save()
|
|
|
if tag_set_cb:
|
|
|
tag_set_cb(self, new_tag)
|
|
|
- elif current_count != pc.count:
|
|
|
- raise Exception((current_count, pc.count))
|
|
|
+ elif current_count != play_count.count:
|
|
|
+ raise Exception((current_count, play_count.count))
|
|
|
|
|
|
def increase_play_count(self, player, library_id, tag_set_cb=None):
|
|
|
current_pc = self.get_latest_play_count(player, library_id)
|
|
@@ -148,7 +147,7 @@ class Track:
|
|
|
|
|
|
@classmethod
|
|
|
def walk(cls, root_path, path_ignore_regex, ignored_cb=None, unsupported_cb=None):
|
|
|
- for dirpath, dirnames, filenames in os.walk(root_path):
|
|
|
+ for dirpath, _, filenames in os.walk(root_path):
|
|
|
for filename in filenames:
|
|
|
track_path = os.path.join(dirpath, filename)
|
|
|
if path_ignore_regex.search(track_path):
|
|
@@ -157,6 +156,6 @@ class Track:
|
|
|
else:
|
|
|
try:
|
|
|
yield cls(track_path)
|
|
|
- except NotImplementedError as e:
|
|
|
+ except NotImplementedError as exc:
|
|
|
if unsupported_cb is not None:
|
|
|
- unsupported_cb(track_path, e)
|
|
|
+ unsupported_cb(track_path, exc)
|