]> code.delx.au - notipod/blobdiff - notipod_gui.py
Version 1.7
[notipod] / notipod_gui.py
index 39d911ffcc1c62457b54a22f562e079b84241e9a..85d2f159400e57eafca02dee407ac9308de92bb7 100644 (file)
@@ -3,6 +3,9 @@
 # Licensed for distribution under the GPL version 2, check COPYING for details
 
 import logging
+import os
+import sys
+import traceback
 
 import objc
 from Foundation import *
@@ -112,13 +115,21 @@ class FolderModel(NSObject):
 
 class NotiPodController(NSObject):
        window = objc.IBOutlet()
-       playlistModel = objc.IBOutlet()
-       folderModel = objc.IBOutlet()
+
        loadingSheet = objc.IBOutlet()
        loadingLabel = objc.IBOutlet()
+       loadingIndicator = objc.IBOutlet()
+
+       previewWindow = objc.IBOutlet()
+       previewText = objc.IBOutlet()
+
+       playlistModel = objc.IBOutlet()
+       folderModel = objc.IBOutlet()
+
 
        def awakeFromNib(self):
                self.runningGenerator = False
+               self.previewWindow.setReleasedWhenClosed_(False)
 
        # Delegate methods
        def applicationWillFinishLaunching_(self, _):
@@ -128,7 +139,9 @@ class NotiPodController(NSObject):
                self.library = libnotipod.ITunesLibrary.alloc().init()
                def finish():
                        self.playlistModel.setPlaylists(self.library.get_playlists())
-               self.runGenerator(lambda: self.library.load_(None), finish)
+               def fail():
+                       sys.exit(0)
+               self.runGenerator(lambda: self.library.load_(None), finish, fail)
 
        def applicationWillTerminate_(self, _):
                self.prefs().synchronize()
@@ -138,42 +151,90 @@ class NotiPodController(NSObject):
 
 
        # Utility methods
-       def runGenerator(self, func, finish):
+       def runGenerator(self, func, finish, fail):
                assert not self.runningGenerator
                self.runningGenerator = True
+               self.loadingIndicator.startAnimation_(self)
                NSApp.beginSheet_modalForWindow_modalDelegate_didEndSelector_contextInfo_(self.loadingSheet, self.window, None, None, None)
-               arg = (func(), finish)
+               arg = (func(), finish, fail)
                self.performSelectorInBackground_withObject_(self.runGeneratorThread, arg)
 
-       def runGeneratorThread(self, (gen, finish)):
+       def runGeneratorThread(self, (gen, finish, fail)):
                pool = NSAutoreleasePool.alloc().init()
-               for msg in gen:
-                       if not self.runningGenerator:
-                               break
-                       self.loadingLabel.performSelectorOnMainThread_withObject_waitUntilDone_(
-                               self.loadingLabel.setStringValue_, msg, True)
+               try:
+                       for msg in gen:
+                               if not self.runningGenerator:
+                                       break
+                               self.loadingLabel.performSelectorOnMainThread_withObject_waitUntilDone_(
+                                       self.loadingLabel.setStringValue_, msg, True)
+               except Exception, e:
+                       NSRunAlertPanel("Error!", str(e), "Ok", None, None)
+                       traceback.print_exc()
+                       finish = fail
                self.performSelectorOnMainThread_withObject_waitUntilDone_(
                        self.stopGenerator, finish, True)
                self.runningGenerator = False
-               del pool
 
        def stopGenerator(self, finish):
                self.runningGenerator = False
                NSApp.endSheet_(self.loadingSheet)
                self.loadingSheet.orderOut_(self)
-               finish()
+               self.loadingIndicator.stopAnimation_(self)
+               if finish:
+                       finish()
 
        @objc.IBAction
        def doCancel_(self, sender):
                self.runningGenerator = False
 
+       def doPreviewThread(self):
+               yield "Calculating changes..."
+
+               folder = self.folders()[0]
+               if not os.path.isdir(folder.encode("utf-8")):
+                       NSRunAlertPanel("Error!", "Destination " + folder + " does not exist, try mounting it first?", "Ok", None, None)
+                       return
+
+               all_tracks = []
+               for playlist_id in self.playlists():
+                       playlist = self.library.get_playlist_pid(playlist_id)
+                       if playlist is not None:
+                               all_tracks.extend(playlist.tracks)
+
+               gen = libnotipod.sync(
+                       dry_run=True,
+                       source=self.library.folder,
+                       dest=folder, 
+                       files_to_copy=all_tracks
+               )
+               self.previewResult = "\n".join(gen)
+
+       @objc.IBAction
+       def doPreview_(self, sender):
+               self.previewResult = ""
+               self.previewWindow.orderOut_(self)
+
+               def finish():
+                       self.previewText.textStorage().mutableString().setString_(self.previewResult)
+                       self.previewWindow.center()
+                       self.previewWindow.makeKeyAndOrderFront_(self)
+
+               self.runGenerator(self.doPreviewThread, finish, None)
+
        @objc.IBAction
        def doSync_(self, sender):
                folder = self.folders()[0]
-               playlists = [self.library.get_playlist_pid(pid) for pid in self.playlists()]
+               if not os.path.isdir(folder.encode("utf-8")):
+                       NSRunAlertPanel("Error!", "Destination " + folder + " does not exist, try mounting it first?", "Ok", None, None)
+                       return
 
                all_tracks = []
-               for playlist in playlists:
+               for playlist_id in self.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)
                        libnotipod.export_m3u(dry_run=False, dest=folder, path_prefix="",
                                        playlist_name=playlist.name, files=playlist.tracks)
@@ -189,7 +250,8 @@ class NotiPodController(NSObject):
                                        files_to_copy=all_tracks
                                )
                        ,
-                       finish
+                       finish,
+                       None
                )