1
import xbmc, xbmcgui
2
import os
3
4
try:
5
	from libpandora.pandora import Pandora
6
except AttributeError, e:
7
	xbmcgui.Dialog().ok( "PANDORA", \
8
						 "ERROR: Something is wrong with your encryption keys." )
9
	raise e
10
11
from pandagui import PandaGUI
12
from pandaplayer import PandaPlayer
13
14
__title__ = "Pandora"
15
16
scriptPath = os.getcwd().replace(';','')
17
18
class PandaException( Exception ):
19
	pass
20
21
class Panda:
22
23
	def __init__( self ):
24
		self.gui = None
25
		self.pandora = None
26
		self.playlist = []
27
		self.curStation = ""
28
		self.playing = False
29
		self.skip = False
30
		self.die = False
31
		self.settings = xbmc.Settings( path=scriptPath )
32
		
33
		fmt = self.settings.getSetting( "format" )
34
		self.pandora = Pandora( fmt )
35
		
36
		self.pandora.sync()
37
		
38
		while not self.auth():
39
			resp = xbmcgui.Dialog().yesno( "Pandora", \
40
					"Failed to authenticate listener.", \
41
					"Check username/password and try again.", \
42
					"Show Settings?" )
43
			if resp:
44
				self.settings.openSettings()
45
			else:
46
				self.quit()
47
				return
48
49
		self.player = PandaPlayer( panda = self )
50
		self.gui = PandaGUI( "script-pandora.xml", scriptPath, \
51
							 "Default", panda = self )
52
	
53
	def auth( self ):
54
		user = self.settings.getSetting( "username" )
55
		pwd = self.settings.getSetting( "password" )
56
		if user == "" or pwd == "":
57
			return False
58
		dlg = xbmcgui.DialogProgress()
59
		dlg.create( "PANDORA", "Logging In..." )
60
		dlg.update( 0 )
61
		ret = self.pandora.authListener( user, pwd )
62
		dlg.close()
63
		return ret
64
65
	def playStation( self, stationId ):
66
		self.curStation = stationId
67
		self.playlist = []
68
		self.getMoreSongs()
69
		self.playing = True
70
		self.playNextSong()
71
72
	def getStations( self ):
73
		return self.pandora.getStations()
74
	
75
	def getMoreSongs( self ):
76
		if self.curStation == "":
77
			raise PandaException()
78
		items = []
79
		fragment = self.pandora.getFragment( self.curStation )
80
		for s in fragment:
81
			item = xbmcgui.ListItem( s["songTitle"] )
82
			item.setIconImage( s["artRadio"] )
83
			item.setThumbnailImage( s["artRadio"] )
84
			item.setProperty( "Cover", s["artRadio"] )
85
			info = { "title"	:	s["songTitle"], \
86
					 "artist"	:	s["artistSummary"], \
87
					 "album"	:	s["albumTitle"], \
88
					 "genre"	:	"".join(s["genre"]), \
89
					}
90
			item.setInfo( "music", info )
91
			items.append( ( s["audioURL"], item ) )
92
		self.playlist.extend( items )
93
94
	def playNextSong( self ):
95
		if not self.playing:
96
			raise PandaException()
97
		try:
98
			next = self.playlist.pop( 0 )
99
			self.player.playSong( next )
100
			art = next[1].getProperty( "Cover" )
101
			self.gui.setProperty( "AlbumArt", art )
102
		except IndexError:
103
			self.getMoreSongs()
104
		if len( self.playlist ) == 0:
105
			#Out of songs, grab some more while playing
106
			self.getMoreSongs()
107
108
	def skipSong( self ):
109
		self.skip = True
110
		self.player.stop()
111
112
	def main( self ):
113
		if self.die:
114
			return
115
		self.gui.doModal()
116
		self.cleanup()
117
		xbmc.sleep( 500 ) #Wait to make sure everything finishes
118
119
	def stop( self ):
120
		self.playing = False
121
122
	def cleanup( self ):
123
		self.skip = False
124
		if self.playing:
125
			self.playing = False
126
			self.player.stop()
127
		del self.gui
128
		del self.player
129
130
	def quit( self ):
131
		if self.gui != None:
132
			self.gui.close()
133
134
if __name__ == '__main__':
135
	if not ( os.path.exists( os.path.join( scriptPath, "crypt_key_input.h" ) ) \
136
			and os.path.exists( os.path.join( scriptPath, "crypt_key_output.h" ) ) ):
137
		xbmcgui.Dialog().ok( "Pandora", "Missing encription key files." )
138
	else:
139
		panda = Panda()
140
		panda.main()