From fd45d2bc20ac9ed64deba0ae046cdc96a4fa9bd7 Mon Sep 17 00:00:00 2001 From: James Bunton Date: Sun, 2 Jan 2011 21:56:22 +1100 Subject: [PATCH] Display progress --- English.lproj/NotiPod.xib | 156 ++++++++------------------------------ NotiPod.py | 54 +++++++++---- libsyncitunes.py | 23 +++--- syncitunes.py | 17 +++-- 4 files changed, 91 insertions(+), 159 deletions(-) diff --git a/English.lproj/NotiPod.xib b/English.lproj/NotiPod.xib index 16c523e..8d7bb0f 100644 --- a/English.lproj/NotiPod.xib +++ b/English.lproj/NotiPod.xib @@ -8,6 +8,7 @@ 461.00 YES + @@ -526,14 +527,14 @@ 7 2 - {{196, 436}, {204, 74}} + {{196, 436}, {342, 74}} 603979776 Window NSWindow {3.40282e+38, 3.40282e+38} - + 256 YES @@ -541,30 +542,31 @@ 1292 - {{18, 16}, {168, 20}} + {{18, 16}, {306, 20}} 16394 2.000000e+01 1.000000e+02 - + 268 - {{17, 44}, {111, 17}} + {{17, 44}, {308, 17}} YES - + 67239488 - 272630784 - Loading library... + 272631296 + Please wait... - + - {204, 74} + {342, 74} + {{0, 0}, {1024, 746}} {3.40282e+38, 3.40282e+38} @@ -575,51 +577,6 @@ FolderModel - - 15 - 2 - {{196, 429}, {279, 81}} - 603979776 - Synchronising - NSWindow - - - - 256 - - YES - - - 268 - {{17, 44}, {245, 17}} - - YES - - 68288064 - 272630784 - Synchronising.. This may take a while. - - - - - - - - - 1292 - - {{18, 16}, {243, 20}} - - 16394 - 2.000000e+01 - 1.000000e+02 - - - {279, 81} - - {{0, 0}, {1280, 778}} - {3.40282e+38, 3.40282e+38} - @@ -754,11 +711,11 @@ - synchronizingSheet + loadingLabel - + - 508 + 511 @@ -1026,7 +983,7 @@ YES - + @@ -1035,20 +992,6 @@ - - 431 - - - YES - - - - - - 432 - - - 436 @@ -1138,43 +1081,18 @@ - 503 - - - YES - - - - SynchronizingSheet - - - 504 - - - YES - - - - - - - 505 - + 509 + YES - + - - - - 506 - - + - 507 - - + 510 + + @@ -1240,8 +1158,6 @@ 428.editorWindowContentRectSynchronizationRect 429.IBPluginDependency 430.IBPluginDependency - 431.IBPluginDependency - 432.IBPluginDependency 436.IBPluginDependency 437.IBPluginDependency 438.IBPluginDependency @@ -1252,15 +1168,11 @@ 472.IBPluginDependency 477.IBPluginDependency 484.IBPluginDependency + 485.IBPluginDependency + 486.IBPluginDependency 490.IBPluginDependency - 503.IBEditorWindowLastContentRect - 503.IBPluginDependency - 503.IBWindowTemplateEditedContentRect - 503.NSWindowTemplate.visibleAtLaunch - 504.IBPluginDependency - 505.IBPluginDependency - 506.IBPluginDependency - 507.IBPluginDependency + 509.IBPluginDependency + 510.IBPluginDependency 56.IBPluginDependency 56.ImportedFromIB2 57.IBPluginDependency @@ -1323,8 +1235,8 @@ {{89, 581}, {211, 33}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{21, 626}, {204, 74}} - {{21, 626}, {204, 74}} + {{82, 574}, {342, 74}} + {{82, 574}, {342, 74}} {{196, 436}, {204, 74}} com.apple.InterfaceBuilder.CocoaPlugin @@ -1342,12 +1254,6 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{42, 607}, {279, 81}} - com.apple.InterfaceBuilder.CocoaPlugin - {{42, 607}, {279, 81}} - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1375,7 +1281,7 @@ - 508 + 511 @@ -1417,9 +1323,9 @@ YES folderModel + loadingLabel loadingSheet playlistModel - synchronizingSheet window diff --git a/NotiPod.py b/NotiPod.py index b844b34..f302f6f 100644 --- a/NotiPod.py +++ b/NotiPod.py @@ -104,19 +104,20 @@ class NotiPodAppDelegate(NSObject): playlistModel = objc.IBOutlet() folderModel = objc.IBOutlet() loadingSheet = objc.IBOutlet() - synchronizingSheet = objc.IBOutlet() + loadingLabel = objc.IBOutlet() + def awakeFromNib(self): + self.gen = None # Delegate methods def applicationWillFinishLaunching_(self, _): pass def applicationDidFinishLaunching_(self, _): - NSApp.beginSheet_modalForWindow_modalDelegate_didEndSelector_contextInfo_(self.loadingSheet, self.window, None, None, None) self.library = libsyncitunes.ITunesLibrary.alloc().init() - self.playlistModel.setPlaylists(self.library.get_playlists()) - NSApp.endSheet_(self.loadingSheet) - self.loadingSheet.orderOut_(self) + def finish(): + self.playlistModel.setPlaylists(self.library.get_playlists()) + self.runGenerator(lambda: self.library.load_(None), finish) def applicationWillTerminate_(self, _): self.prefs().synchronize() @@ -124,10 +125,29 @@ class NotiPodAppDelegate(NSObject): def applicationShouldTerminateAfterLastWindowClosed_(self, _): return True + + # Utility methods + def runGenerator(self, func, finish): + NSApp.beginSheet_modalForWindow_modalDelegate_didEndSelector_contextInfo_(self.loadingSheet, self.window, None, None, None) + self.gen = func() + self.finish = finish + self.runGeneratorNext() + + def runGeneratorNext(self): + try: + msg = self.gen.next() + self.loadingLabel.setStringValue_(msg) + self.performSelector_withObject_afterDelay_( + self.runGeneratorNext, None, 0) + except StopIteration: + self.gen = None + NSApp.endSheet_(self.loadingSheet) + self.loadingSheet.orderOut_(self) + self.finish() + self.finish = None + @objc.IBAction def doSync_(self, sender): - NSApp.beginSheet_modalForWindow_modalDelegate_didEndSelector_contextInfo_(self.synchronizingSheet, self.window, None, None, None) - folder = self.folders()[0] playlists = [self.library.get_playlist_pid(pid) for pid in self.playlists()] @@ -137,13 +157,19 @@ class NotiPodAppDelegate(NSObject): libsyncitunes.export_m3u(dry_run=False, dest=folder, path_prefix="", playlist_name=playlist.name, files=playlist.tracks) - libsyncitunes.sync(dry_run=False, - source=self.library.folder, dest=folder, files=all_tracks) - - NSApp.endSheet_(self.synchronizingSheet) - self.synchronizingSheet.orderOut_(self) - - NSRunAlertPanel("Complete!", "Synchronisation is complete", "Ok", None, None) + def finish(): + NSRunAlertPanel("Complete!", "Synchronisation is complete", "Ok", None, None) + self.runGenerator( + lambda: + libsyncitunes.sync( + dry_run=False, + source=self.library.folder, + dest=folder, + files=all_tracks + ) + , + finish + ) # Public accessors diff --git a/libsyncitunes.py b/libsyncitunes.py index 9573fe6..c8d330c 100644 --- a/libsyncitunes.py +++ b/libsyncitunes.py @@ -37,19 +37,19 @@ class Playlist(NSObject): parent.children.append(self) class ITunesLibrary(NSObject): - def init(self): - return self.initWithFilename_("~/Music/iTunes/iTunes Music Library.xml") - - def initWithFilename_(self, filename): + def load_(self, filename): + if filename is None: + filename = "~/Music/iTunes/iTunes Music Library.xml" filename = os.path.expanduser(filename) + yield "Reading library..." plist = read_plist(os.path.expanduser(filename)) self.folder = self.loc2name(plist["Music Folder"]) pl_tracks = plist["Tracks"] self.playlists = {} for pl_playlist in plist["Playlists"]: playlist = self.make_playlist(pl_playlist, pl_tracks) + yield "Read playlist: " + playlist.name self.playlists[playlist.pid] = playlist - return self def loc2name(self, location): return urllib.splithost(urllib.splittype(urllib.unquote(location))[1])[1] @@ -69,7 +69,6 @@ class ITunesLibrary(NSObject): filename = str(pl_tracks[str(trackID)]["Location"]) filename = self.loc2name(filename) filename = filename.decode("utf-8") -### filename = eval(repr(filename).lstrip("u")).decode("utf-8") if not filename.startswith(self.folder): logging.warn("Skipping: " + filename) continue @@ -189,23 +188,23 @@ def sync(dry_run, source, dest, files): continue if filename in files: - sourcestat = os.stat(join(source, filename)) + sourcestat = os.stat(join(source, filemap[filename])) deststat = os.stat(join(dest, filename)) same_time = abs(sourcestat.st_mtime - deststat.st_mtime) < 5 same_size = sourcestat.st_size == deststat.st_size if same_time and same_size: files.remove(filename) - logging.debug("keep: " + filename) + yield "Keep: " + filename else: - logging.debug("update: " + filename) + yield "Update: " + filename elif not filename.endswith(".m3u"): - logging.debug("delete: " + filename) + yield "Delete: " + filename if not dry_run: os.unlink(join(dest, filename)) if len(os.listdir(full_dirpath)) == 0: - logging.debug("rmdir: " + dirpath) + yield "Delete: " + dirpath if not dry_run: os.rmdir(full_dirpath) @@ -214,7 +213,7 @@ def sync(dry_run, source, dest, files): files = list(files) files.sort() for filename in files: - logging.debug("copy: " + filename) + yield "Copy: " + filename if not dry_run: mkdirhier(os.path.dirname(join(dest, filename))) shutil.copy2(join(source, filemap[filename]), join(dest, filename)) diff --git a/syncitunes.py b/syncitunes.py index fb9dba0..32ed08c 100755 --- a/syncitunes.py +++ b/syncitunes.py @@ -52,11 +52,10 @@ def main(): sys.exit(1) logging.info("Loading library") - library = libsyncitunes.ITunesLibrary.alloc() - if opts.itunes_library: - library = library.initWithFilename_(opts.itunes_library) - else: - library = library.init() + library = libsyncitunes.ITunesLibrary.alloc().init() + gen = library.load_(opts.itunes_library) + for msg in gen: + logging.debug(msg) for playlist in opts.playlists: if not library.has_playlist_name(playlist): @@ -68,11 +67,13 @@ def main(): for playlist in opts.playlists: tracks = library.get_playlist_name(playlist).tracks all_tracks.extend(tracks) - libsyncitunes.export_m3u(opts.dry_run, opts.dest, opts.path_prefix, - playlist, tracks) + libsyncitunes.export_m3u(opts.dry_run, opts.dest, + opts.path_prefix, playlist, tracks) logging.info("Synchronising") - libsyncitunes.sync(opts.dry_run, library.folder, opts.dest, all_tracks) + gen = libsyncitunes.sync(opts.dry_run, library.folder, opts.dest, all_tracks) + for msg in gen: + logging.debug(msg) if __name__ == "__main__": -- 2.39.2