X-Git-Url: https://code.delx.au/notipod/blobdiff_plain/0807f0abbd2f0c91c43ff97b088cacf34acf6f7c..940330ce5a487a919446ee62f920646c2e38fee5:/notipod_gui.py diff --git a/notipod_gui.py b/notipod_gui.py index 283a547..11c6880 100644 --- a/notipod_gui.py +++ b/notipod_gui.py @@ -5,6 +5,7 @@ import logging import os import sys +import time import traceback import uuid @@ -122,6 +123,10 @@ class NotiPodController(NSObject): loadingLabel = objc.IBOutlet() loadingIndicator = objc.IBOutlet() + advancedSheet = objc.IBOutlet() + advancedSyncFolder = objc.IBOutlet() + advancedPathPrefix = objc.IBOutlet() + previewWindow = objc.IBOutlet() previewText = objc.IBOutlet() @@ -145,7 +150,7 @@ class NotiPodController(NSObject): self.folderModel.loadFolders_(folders) self.library = libnotipod.ITunesLibrary.alloc().init() - self.loadLibrary() + self.loadLibrary_(self) def applicationWillTerminate_(self, _): self.prefs().synchronize() @@ -155,24 +160,10 @@ class NotiPodController(NSObject): def windowDidBecomeKey_(self, _): if self.library.needs_reload(): - print "needs reload!" - self.loadLibrary() - else: - print "no reloading this time" + self.loadLibrary_(self) # Utility methods - def loadLibrary(self): - if self.runningGenerator: - return - - def finish(): - self.playlistModel.setPlaylists(self.library.get_playlists()) - def fail(): - NSRunAlertPanel("Error!", "Unable to load iTunes library! Exiting...", "Ok", None, None) - sys.exit(0) - self.runGenerator(lambda: self.library.load_(None), finish, fail) - def runGenerator(self, func, finish, fail): assert not self.runningGenerator self.runningGenerator = True @@ -183,12 +174,15 @@ class NotiPodController(NSObject): def runGeneratorThread(self, (gen, finish, fail)): pool = NSAutoreleasePool.alloc().init() + last_time = 0 try: for msg in gen: if not self.runningGenerator: break - self.loadingLabel.performSelectorOnMainThread_withObject_waitUntilDone_( - self.loadingLabel.setStringValue_, msg, True) + now = time.time() + if now - last_time > 0.1: + self.loadingLabel.performSelectorOnMainThread_withObject_waitUntilDone_( + self.loadingLabel.setStringValue_, msg, True) except Exception, e: NSRunAlertPanel("Error!", str(e), "Ok", None, None) traceback.print_exc() @@ -205,26 +199,64 @@ class NotiPodController(NSObject): if finish: finish() + + @objc.IBAction + def loadLibrary_(self, sender): + if self.runningGenerator: + return + + def finish(): + self.playlistModel.setPlaylists(self.library.get_playlists()) + def fail(): + NSRunAlertPanel("Error!", "Unable to load iTunes library! Exiting...", "Ok", None, None) + os._exit(0) + self.runGenerator(lambda: self.library.load_(None), finish, fail) + + @objc.IBAction + def showAdvancedOptions_(self, sender): + if self.runningGenerator: + return + target = self.getCurrentTarget() + self.advancedSyncFolder.setStringValue_(target["folder"]) + self.advancedPathPrefix.setStringValue_(target["path_prefix"]) + NSApp.beginSheet_modalForWindow_modalDelegate_didEndSelector_contextInfo_(self.advancedSheet, self.window, None, None, None) + + @objc.IBAction + def finishAdvancedOptions_(self, sender): + target = self.getCurrentTarget() + target["folder"] = self.advancedSyncFolder.stringValue() + target["path_prefix"] = self.advancedPathPrefix.stringValue() + self._savePrefs() + NSApp.endSheet_(self.advancedSheet) + self.advancedSheet.orderOut_(self) + @objc.IBAction def doCancel_(self, sender): self.runningGenerator = False - def getDestFolder(self): + def getCheckTarget(self): target = self.getCurrentTarget() if not target: NSRunAlertPanel("Error!", "You must choose a folder first!", "Ok", None, None) return folder = target["folder"] + if not os.path.isdir(folder.encode("utf-8")): NSRunAlertPanel("Error!", "Destination " + folder + " does not exist, try mounting it first?", "Ok", None, None) return - return folder + + folder_contents = [f for f in os.listdir(folder) if not f.startswith(".")] + if len(folder_contents) > 0 and "-Playlists-" not in folder_contents: + NSRunAlertPanel("Error!", "Refusing to clobber files in non-empty folder: " + folder, "Ok", None, None) + return + + return target def doPreviewThread(self): yield "Calculating changes..." - folder = self.getDestFolder() - if not folder: + target = self.getCheckTarget() + if not target: return all_tracks = set() @@ -235,12 +267,14 @@ class NotiPodController(NSObject): all_filenames = [] for trackID in all_tracks: - all_filenames.append(self.library.get_track_filename(trackID)) + f = self.library.get_track_filename(trackID) + if f: + all_filenames.append(f) gen = libnotipod.sync( dry_run=True, source=self.library.folder, - dest=folder, + dest=target["folder"], files_to_copy=all_filenames, ) self.previewResult = "\n".join(gen) @@ -259,8 +293,8 @@ class NotiPodController(NSObject): @objc.IBAction def doSync_(self, sender): - folder = self.getDestFolder() - if not folder: + target = self.getCheckTarget() + if not target: return all_tracks = set() @@ -276,21 +310,33 @@ class NotiPodController(NSObject): all_filenames = [] for trackID in all_tracks: - all_filenames.append(self.library.get_track_filename(trackID)) + f = self.library.get_track_filename(trackID) + if f: + all_filenames.append(f) all_playlists.update(self.library.get_track_playlists(trackID)) + libnotipod.delete_playlists(dry_run=False, dest=target["folder"]) + 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 trackID not in all_tracks: + continue + f = self.library.get_track_filename(trackID) + if f: + tracks.append(f) 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=tracks) + libnotipod.export_m3u( + dry_run=False, + dest=target["folder"], + path_prefix=target["path_prefix"], + playlist_name=playlist.name, + files=tracks + ) def finish(): NSRunAlertPanel("Complete!", "Synchronisation is complete", "Ok", None, None) @@ -299,7 +345,7 @@ class NotiPodController(NSObject): libnotipod.sync( dry_run=False, source=self.library.folder, - dest=folder, + dest=target["folder"], files_to_copy=all_filenames, ) , @@ -332,7 +378,8 @@ class NotiPodController(NSObject): target = {} target["folder"] = f target["playlists"] = list(playlists) - target["uuid"] = uuid.uuid1().get_hex() + target["uuid"] = uuid.uuid4().get_hex() + target["path_prefix"] = "../" if first: first = False self.setCurrentTarget_(target["uuid"]) @@ -391,7 +438,8 @@ class NotiPodController(NSObject): target = {} target["folder"] = folder target["playlists"] = self.playlists() - target["uuid"] = uuid.uuid1().get_hex() + target["uuid"] = uuid.uuid4().get_hex() + target["path_prefix"] = "../" self.targets.insertObject_atIndex_(target, 0) self.setCurrentTarget_(target["uuid"])