Browse Source

symuid.sync: added optional param `play_count_added_cb`

Fabian Peter Hammerle 1 month ago
parent
commit
da9671ffee
3 changed files with 43 additions and 13 deletions
  1. 6 0
      symuid/__init__.py
  2. 10 13
      symuid/sync.py
  3. 27 0
      tests/test_sync.py

+ 6 - 0
symuid/__init__.py

@@ -55,6 +55,12 @@ class Track:
             return _tag_interface.Ogg(mutagen_file)
         raise NotImplementedError((track_path, type(mutagen_file)))
 
+    def __eq__(self, other: 'Track') -> bool:
+        return self.path == other.path
+
+    def __hash__(self) -> int:
+        return hash(self.path)
+
     @property
     def path(self):
         return self._iface.track_path

+ 10 - 13
symuid/sync.py

@@ -26,18 +26,19 @@ class _SyncPosition:
         self._tracks.add(track)
         self._play_counts.update(track.get_play_counts())
 
-    @property
-    def play_counts(self) -> typing.Set[symuid.PlayCount]:
-        return self._play_counts
-
-    @property
-    def tracks(self) -> typing.Set[symuid.Track]:
-        return self._tracks
+    def sync(self, play_count_added_cb=None) -> None:
+        for track in self._tracks:
+            track_play_counts = set(track.get_play_counts())
+            for play_count in self._play_counts:
+                if play_count not in track_play_counts:
+                    track.register_play_count(
+                        play_count, tag_set_cb=play_count_added_cb)
 
     def __repr__(self) -> str:
         return repr(vars(self))
 
-def sync(path, path_ignore_regex, show_ignored=False):
+def sync(path, path_ignore_regex, show_ignored=False,
+         play_count_added_cb=None):
     sync_positions = collections.defaultdict(_SyncPosition)
     for track in symuid.Track.walk(
             root_path=path,
@@ -52,11 +53,7 @@ def sync(path, path_ignore_regex, show_ignored=False):
                 track.get_uuid()))
         sync_positions[track.get_uuid()].add_track(track)
     for sync_position in sync_positions.values():
-        for track in sync_position.tracks:
-            track_play_counts = set(track.get_play_counts())
-            for play_count in sync_position.play_counts:
-                if play_count not in track_play_counts:
-                    track.register_play_count(play_count)
+        sync_position.sync(play_count_added_cb=play_count_added_cb)
 
 
 def _init_argparser():

+ 27 - 0
tests/test_sync.py

@@ -106,3 +106,30 @@ def test_sync_play_count(tmpdir, tracks_dir_path):
     assert len(play_counts_b) == 1
     assert {pc.register_dt.timestamp() for pc in play_counts_b} \
         == pytest.approx({3})
+
+
+def test_sync_play_count_callback(tmpdir, tracks_dir_path):
+    shutil.copyfile(
+        src=os.path.join(tracks_dir_path, 'id3v2.4-empty.mp3'),
+        dst=tmpdir.join('a1.mp3'),
+    )
+    shutil.copyfile(
+        src=os.path.join(tracks_dir_path, 'ogg-vorbis-empty.ogg'),
+        dst=tmpdir.join('a2.ogg'),
+    )
+    uuid_a = generate_uuid4_bytes()
+    track_a1 = Track(tmpdir.join('a1.mp3'))
+    track_a1.assign_uuid(uuid_a)
+    track_a2 = Track(tmpdir.join('a2.ogg'))
+    track_a2.assign_uuid(uuid_a)
+    track_a1.register_play_count(PlayCount(
+        player='cmus',
+        library_id='lib1',
+        register_dt=unix_epoch_time_to_datetime_utc(0),
+        count=21,
+    ))
+    play_count_added_cb = unittest.mock.MagicMock()
+    sync(tmpdir, path_ignore_regex=DUMMY_PATH_IGNORE_REGEX,
+         play_count_added_cb=play_count_added_cb)
+    # TODO fix None
+    play_count_added_cb.assert_called_once_with(track_a2, None)