2 # PostTunesAppDelegate.py
5 # Created by Joseph Spiros on 3/5/09.
6 # Copyright iThink Software 2009. All rights reserved.
10 from urllib import urlencode
11 from urllib2 import urlopen, URLError
12 from base64 import b64encode
13 from PyObjCTools import AppHelper
14 from Foundation import *
16 from ScriptingBridge import *
18 class PostTunesAppDelegate(NSObject):
19 preferencesWindow = objc.IBOutlet()
20 warnFailure = objc.ivar(u"warnFailure")
21 lastPersistentID = objc.ivar(u"lastPersistentID")
22 handlerURL = objc.ivar(u"handlerURL")
23 secretKey = objc.ivar(u"secretKey")
26 self = super(PostTunesAppDelegate, self).init()
29 self.warnFailure = True
30 self.lastPersistentID = None
31 self.handlerURL = None
35 def awakeFromNib(self):
36 self.handlerURL = NSUserDefaults.standardUserDefaults().stringForKey_("handlerURL")
37 self.secretKey = NSUserDefaults.standardUserDefaults().stringForKey_("secretKey")
38 if not self.handlerURL:
39 self.runConfigurationAlert_title_description_(None, "In order for PostTunes to post tracks, you must set a Handler URL. The optional Secret Key may be used by the script at the Handler URL to validate your posts.")
42 def runConfigurationAlert_title_description_(self, title, description):
44 title = "PostTunes Configuration"
45 alert = NSAlert.alertWithMessageText_defaultButton_alternateButton_otherButton_informativeTextWithFormat_(title, "OK", "Quit PostTunes", None, description)
46 alert.setAccessoryView_(self.preferencesWindow.contentView().retain())
47 alert.setAlertStyle_(NSCriticalAlertStyle)
48 alertReturn = alert.runModal()
49 if alertReturn == NSAlertDefaultReturn:
50 self.handlerURL = NSUserDefaults.standardUserDefaults().stringForKey_("handlerURL")
51 if not self.handlerURL:
52 self.runConfigurationAlert_title_description_("PostTunes Handler URL Missing", "You must set a Handler URL for PostTunes to function.")
53 elif alertReturn == NSAlertAlternateReturn:
54 AppHelper.stopEventLoop()
56 def observeNote(self):
57 NSDistributedNotificationCenter.defaultCenter().addObserver_selector_name_object_(self, "gotNotification:", "com.apple.iTunes.playerInfo", None)
59 def gotNotification_(self, notification):
60 self.handlerURL = NSUserDefaults.standardUserDefaults().stringForKey_("handlerURL")
61 self.secretKey = NSUserDefaults.standardUserDefaults().stringForKey_("secretKey")
63 noteInfo = notification.userInfo()
64 playerState = noteInfo["Player State"]
65 if "PersistentID" in noteInfo:
66 persistentID = noteInfo["PersistentID"]
67 if (persistentID != self.lastPersistentID) and ("Name" in noteInfo):
68 if playerState == "Playing":
70 # started playing a new track
71 # get the applescript track and make sure it's the same (compare name)
72 iTunes = SBApplication.applicationWithBundleIdentifier_("com.apple.iTunes")
73 iTunesTrack = iTunes.currentTrack()
74 if iTunesTrack.name() == noteInfo["Name"]:
75 self.trackChanged_iTunesTrack_(noteInfo, iTunesTrack)
76 self.lastPersistentID = persistentID
78 self.runConfigurationAlert_title_description_("PostTunes Handler URL Missing", "PostTunes was unable to post a track due to the Handler URL being missing. You must set a Handler URL for PostTunes to function.")
81 self.lastPersistentID = None
84 def trackChanged_iTunesTrack_(self, noteInfo, iTunesTrack):
85 trackData = {"title": noteInfo["Name"]}
87 trackData["key"] = self.secretKey
88 if "Artist" in noteInfo:
89 trackData["artist"] = noteInfo["Artist"]
90 if "Album" in noteInfo:
91 trackData["album"] = noteInfo["Album"]
92 if "Store URL" in noteInfo:
93 trackData["url"] = noteInfo["Store URL"]
94 iTunesArtworks = iTunesTrack.artworks()
95 if len(iTunesArtworks) >= 1:
96 artwork = iTunesArtworks[0]
97 artworkTIFF = artwork.data().TIFFRepresentation()
98 artworkPNG = NSBitmapImageRep.imageRepWithData_(artworkTIFF).representationUsingType_properties_(NSPNGFileType, None)
99 trackData["artpng"] = b64encode(artworkPNG.bytes())
101 urlopen(self.handlerURL, urlencode(trackData))
103 description = (u"PostTunes encountered an error when attempting to post the track \"%s\" to your Handler URL." % trackData["title"])
104 NSLog(u"%s Handler URL: %s" % (description, self.handlerURL))
106 alert = NSAlert.alertWithMessageText_defaultButton_alternateButton_otherButton_informativeTextWithFormat_("PostTunes Could Not Post Track", "OK", "Configure PostTunes", "Quit PostTunes", description)
107 alert.setAlertStyle_(NSCriticalAlertStyle)
108 alert.setShowsSuppressionButton_(True)
109 alertReturn = alert.runModal()
110 if alert.suppressionButton().state() == NSOnState:
111 self.warnFailure = False
112 if alertReturn == NSAlertAlternateReturn:
113 self.runConfigurationAlert_title_description_(None, (u"%s Please confirm your Handler URL." % description))
114 elif alertReturn == NSAlertOtherReturn:
115 AppHelper.stopEventLoop()