]> code.delx.au - notipod/commitdiff
Allow reverse-mapping of tracks so more playlists can be exported
authorJames Bunton <jamesbunton@delx.net.au>
Sun, 12 Feb 2012 09:44:19 +0000 (20:44 +1100)
committerJames Bunton <jamesbunton@delx.net.au>
Sun, 12 Feb 2012 09:44:19 +0000 (20:44 +1100)
libnotipod.py
notipod_cli.py
notipod_gui.py

index 76b7fb002a361cddd5fa27134c9d69c30c4ca15d..bc0b1eebd77f8759d375f6b850374593775e0a3c 100644 (file)
@@ -2,6 +2,7 @@
 # Copyright 2009 James Bunton <jamesbunton@fastmail.fm>
 # Licensed for distribution under the GPL version 2, check COPYING for details
 
+import collections
 import logging
 import os
 import shutil
@@ -50,6 +51,8 @@ class ITunesLibrary(NSObject):
                pl_tracks = plist["Tracks"]
                pl_lookup = {}
                self.playlists = []
+               self.track2playlist = collections.defaultdict(set)
+               self.track2filename = {}
                for pl_playlist in plist["Playlists"]:
                        playlist = self.make_playlist(pl_playlist, pl_tracks, pl_lookup)
                        if not playlist:
@@ -95,17 +98,22 @@ class ITunesLibrary(NSObject):
                        parent = pl_lookup[parent_pid]
                except KeyError:
                        pass
+
                tracks = []
                for item in pl_playlist.get("Playlist Items", []):
                        trackID = item["Track ID"]
-                       filename = str(pl_tracks[str(trackID)]["Location"])
-                       filename = self.loc2name(filename)
-                       filename = filename.decode("utf-8")
-                       if not filename.startswith(self.folder):
-                               logging.warn("Skipping: " + filename)
-                               continue
-                       filename = strip_prefix(filename, self.folder)
-                       tracks.append(filename)
+                       self.track2playlist[trackID].add(pid)
+                       tracks.append(trackID)
+                       if trackID not in self.track2filename:
+                               filename = str(pl_tracks[str(trackID)]["Location"])
+                               filename = self.loc2name(filename)
+                               filename = filename.decode("utf-8")
+                               if not filename.startswith(self.folder):
+                                       logging.warn("Skipping: " + filename)
+                                       continue
+                               filename = strip_prefix(filename, self.folder)
+                               self.track2filename[trackID] = filename
+
                playlist = Playlist.alloc().init()
                playlist.set(name, pid, ptype, tracks, parent)
                return playlist
@@ -126,6 +134,12 @@ class ITunesLibrary(NSObject):
                        if playlist.pid == pid:
                                return playlist
 
+       def get_track_filename(self, trackID):
+               return self.track2filename.get(trackID, None)
+
+       def get_track_playlists(self, trackID):
+               return self.track2playlist.get(trackID, [])
+
        def get_playlists(self):
                return self.playlists
 
index 5ded3f09c91ae9c154dbf06885ba697c23c75120..32270f2a41cd926525bdd906d8a6e3c8dc2605c3 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 
-VERSION = "1.9"
+VERSION = "1.10"
 
 import logging
 import optparse
@@ -63,15 +63,16 @@ def main():
                        sys.exit(1)
 
        logging.info("Loading playlists")
-       all_tracks = []
+       all_filenames = []
        for playlist in opts.playlists:
                tracks = library.get_playlist_name(playlist).tracks
-               all_tracks.extend(tracks)
+               filenames = [library.get_track_filename(trackID) for trackID in tracks]
+               all_filenames.extend(filenames)
                libnotipod.export_m3u(opts.dry_run, opts.dest,
-                       opts.path_prefix, playlist, tracks)
+                       opts.path_prefix, playlist, filenames)
 
        logging.info("Synchronising")
-       gen = libnotipod.sync(opts.dry_run, library.folder, opts.dest, all_tracks)
+       gen = libnotipod.sync(opts.dry_run, library.folder, opts.dest, all_filenames)
        for msg in gen:
                logging.debug(msg)
 
index 54cf425f216fb0fb1df2350434b6c38e13ab9b80..f469b48f96922b09405cfd0545eb5348a480a5b6 100644 (file)
@@ -204,17 +204,21 @@ class NotiPodController(NSObject):
                if not folder:
                        return
 
-               all_tracks = []
+               all_tracks = set()
                for playlist_id in self.playlists():
                        playlist = self.library.get_playlist_pid(playlist_id)
                        if playlist is not None:
-                               all_tracks.extend(playlist.tracks)
+                               all_tracks.update(set(playlist.tracks))
+
+               all_filenames = []
+               for trackID in all_tracks:
+                       all_filenames.append(self.library.get_track_filename(trackID))
 
                gen = libnotipod.sync(
                        dry_run=True,
                        source=self.library.folder,
                        dest=folder, 
-                       files_to_copy=all_tracks
+                       files_to_copy=all_filenames,
                )
                self.previewResult = "\n".join(gen)
 
@@ -236,16 +240,34 @@ class NotiPodController(NSObject):
                if not folder:
                        return
 
-               all_tracks = []
-               for playlist_id in self.playlists():
+               all_tracks = set()
+               orig_playlists = set(self.playlists())
+               all_playlists = orig_playlists.copy()
+               for playlist_id in all_playlists:
                        playlist = self.library.get_playlist_pid(playlist_id)
                        if playlist is None:
                                print "Forgetting unknown playlist:", playlist_id
                                self.setPlaylist_selected_(playlist_id, False)
                                continue
-                       all_tracks.extend(playlist.tracks)
+                       all_tracks.update(set(playlist.tracks))
+
+               all_filenames = []
+               for trackID in all_tracks:
+                       all_filenames.append(self.library.get_track_filename(trackID))
+                       all_playlists.update(self.library.get_track_playlists(trackID))
+
+               for playlist_id in all_playlists:
+                       playlist = self.library.get_playlist_pid(playlist_id)
+                       if playlist is None:
+                               continue
+                       tracks = []
+                       for trackID in playlist.tracks:
+                               if trackID in all_tracks:
+                                       tracks.append(self.library.get_track_filename(trackID))
+                       if playlist_id not in orig_playlists and len(tracks) < 10:
+                               continue
                        libnotipod.export_m3u(dry_run=False, dest=folder, path_prefix="",
-                                       playlist_name=playlist.name, files=playlist.tracks)
+                                       playlist_name=playlist.name, files=tracks)
 
                def finish():
                        NSRunAlertPanel("Complete!", "Synchronisation is complete", "Ok", None, None)
@@ -255,7 +277,7 @@ class NotiPodController(NSObject):
                                        dry_run=False,
                                        source=self.library.folder,
                                        dest=folder, 
-                                       files_to_copy=all_tracks
+                                       files_to_copy=all_filenames,
                                )
                        ,
                        finish,