Advertisement
Guest User

Untitled

a guest
May 26th, 2012
196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 43.97 KB | None | 0 0
  1. import xbmc, xbmcgui, xbmcplugin #, xbmcaddon
  2. import sys
  3. import pickle
  4. import os
  5. import traceback
  6. import threading
  7. import random
  8. import gc
  9. from pprint import pprint
  10.  
  11. __scriptname__ = sys.modules[ "__main__" ].__scriptname__
  12. __version__ = sys.modules[ "__main__" ].__version__
  13. __settings__ = sys.modules[ "__main__" ].__settings__
  14. __language__ = sys.modules[ "__main__" ].__language__
  15. __scriptid__ = sys.modules[ "__main__" ].__scriptid__
  16. __debugging__ = sys.modules["__main__"].__debugging__
  17. __isXbox__ = sys.modules["__main__"].__isXbox__
  18. __cwd__ = sys.modules["__main__"].__cwd__
  19.  
  20. sys.path.append(os.path.join(__cwd__.replace(";",""),'resources','lib'))
  21. import uuid
  22.  
  23. from GrooveAPI import *
  24. from GrooveLib import *
  25. from GroovePlayer import GroovePlayer
  26. from GrooveGUI import *
  27. from operator import itemgetter, attrgetter
  28.  
  29. pGUI = None
  30.  
  31. def setPGUI(p):
  32.     global pGUI
  33.     pGUI = p
  34.  
  35. def lock():
  36.     cnt = pGUI.getControl(7005)
  37.     pGUI.setFocus(cnt)
  38.  
  39. def unlock():
  40.     pGUI.playlistHasFocus()
  41.  
  42. #plugin://%s/?playSong=%s&artistId=%s&albumId=%s&image=%s&songName=%s&artistName=%s&albumName=%s&options=%s
  43.  
  44. #plugin://script.audio.grooveshark/?
  45. #playSong=10779110
  46. #&artistId=401423
  47. #&albumId=1145459
  48. #&image=http%3A%2F%2Fbeta.grooveshark.com%2Fstatic%2Famazonart%2Fm3253484.jpg
  49. #&songName=Yes Sir I Can Boogie
  50. #&artistName=Goldfrapp
  51. #&albumName=Misc
  52. #&options=
  53. class NowPlaying:
  54.     def __init__(self, gui, gsapi, defaultCoverArt = None):
  55.         self.songs = []
  56.         self.gsapi = gsapi
  57.         self.defaultCoverArt = defaultCoverArt
  58.         self.gui = gui
  59.         pass
  60.  
  61.     def decode(self, s):
  62.         try:
  63.             return urllib.unquote_plus(s)
  64.         except:
  65.             print s
  66.             return "blabla"
  67.  
  68.     def _list(self, gui, gsapi):
  69.         playlist = xbmc.PlayList(xbmc.PLAYLIST_MUSIC)
  70.         n = playlist.size()
  71.         data = []
  72.         songs = []
  73.         for i in range(n):
  74.             song = playlist[i]
  75.             name = song.getfilename()
  76.             name = name.split('?')[1]
  77.             parts = name.split('&')
  78.             songId = parts[0].split('=')[1]
  79.             artistId = parts[1].split('=')[1]
  80.             albumId = parts[2].split('=')[1]
  81.             image = self.decode(parts[3].split('=')[1])
  82.             songName = self.decode(parts[4].split('=')[1])
  83.             artistName = self.decode(parts[5].split('=')[1])
  84.             albumName = self.decode(parts[6].split('=')[1])
  85.             options = parts[7].split('=')[1]
  86.             item = {'SongID': songId,\
  87.                     'Name': songName,\
  88.                     'AlbumName':albumName,\
  89.                     'ArtistName':artistName,\
  90.                     'ArtistID':artistId,\
  91.                     'AlbumID':albumId,\
  92.                     'ArtistID':artistId,\
  93.                     'CoverArt':image\
  94.                     }
  95.             data.append(item)
  96.         songs = Songs(data, defaultCoverArt = self.defaultCoverArt)
  97.         #pprint(data)
  98.         return songs._list(self.gui, self.gsapi)
  99.            
  100.  
  101. class Search(GS_Search):
  102.     def __init__(self, gui, defaultCoverArt = None):
  103.         self.gui = gui
  104.         GS_Search.__init__(self,\
  105.                     defaultCoverArt = defaultCoverArt,\
  106.                     songContainer = Song,\
  107.                     songsContainer = Songs,\
  108.                     albumContainer = Album,\
  109.                     albumsContainer = Albums,\
  110.                     artistContainer = Artist,\
  111.                     artistsContainer = Artists)
  112.  
  113.     def newSongContainer(self, item):
  114.         return self.songContainer(item, defaultCoverArt = self.defaultCoverArt)
  115.  
  116.     def newSongsContainer(self, item, sort = 'Score'):
  117.         return self.songsContainer(item, defaultCoverArt = self.defaultCoverArt)
  118.  
  119.     def newArtistContainer(self, item):
  120.         return self.artistContainer(item, defaultCoverArt = self.defaultCoverArt)
  121.  
  122.     def newArtistsContainer(self, item):
  123.         return self.artistsContainer(item, defaultCoverArt = self.defaultCoverArt)
  124.  
  125.     def newAlbumContainer(self, item):
  126.         return self.albumContainer(item, defaultCoverArt = self.defaultCoverArt)
  127.  
  128.     def newAlbumsContainer(self, item):
  129.         return self.albumsContainer(item, defaultCoverArt = self.defaultCoverArt)
  130.  
  131.     def get(self, n):
  132.         if n == 0:
  133.             return self.songs
  134.         if n == 1:
  135.             return self.artists
  136.         if n == 2:
  137.             return self.albums
  138.         if n == 3:
  139.             return self.songs
  140.  
  141.     def _list(self, gui, gsapi):
  142.         if self.queryText == None:
  143.             return
  144.         self.info = ''
  145.         pathArtist = os.path.join(__cwd__,'resources','skins','DefaultSkin', 'media', 'gs_artist.png')
  146.         pathAlbum = os.path.join(__cwd__,'resources','skins','DefaultSkin', 'media', 'gs_album.png')
  147.         pathSong = os.path.join(__cwd__,'resources','skins','DefaultSkin', 'media', 'gs_song.png')
  148.         pathPlaylist = os.path.join(__cwd__,'resources','skins','DefaultSkin', 'media', 'gs_playlist.png')
  149.         search = self
  150.         listItems = [\
  151.             xbmcgui.ListItem (label=__language__(3023), label2=str(search.countSongs()) + ' ' + __language__(3026), thumbnailImage=pathSong),\
  152.             xbmcgui.ListItem (label=__language__(3024), label2=str(search.countArtists()) + ' ' + __language__(3026), thumbnailImage=pathArtist),\
  153.             xbmcgui.ListItem (label=__language__(3025), label2=str(search.countAlbums()) + ' ' + __language__(3026), thumbnailImage=pathAlbum),\
  154.             #xbmcgui.ListItem (label=__language__(3042), label2=str(0) + ' ' + __language__(3026), thumbnailImage=pathPlaylist),\
  155.         ]
  156.         return [self, listItems]
  157.         pass
  158.  
  159. class Songs(GS_Songs):
  160.     def __init__(self, data, defaultCoverArt = None, sort = None):
  161.         GS_Songs.__init__(self, data, defaultCoverArt = defaultCoverArt, sort = sort)
  162.  
  163.     def setContainers(self):
  164.         self.songContainer = Song
  165.  
  166.     def _list(self, gui, gsapi):
  167.         try:
  168.             n = self.count()
  169.             self.info = str(n) + ' ' + __language__(3023)
  170.             listItems = []
  171.             for i in range(self.count()):
  172.                 song = self.get(i)
  173.                 try:
  174.                     durMin = int(song.duration/60.0)
  175.                     durSec = int(song.duration - durMin*60)
  176.                     if durSec < 10:
  177.                         durStr = '(' + str(durMin) + ':0' + str(durSec) + ')'
  178.                     else:
  179.                         durStr = '(' + str(durMin) + ':' + str(durSec) + ')'
  180.                 except:
  181.                     durStr = ''
  182.                 if gui.useCoverArt == True:
  183.                     path = song.coverart
  184.                     if path == None:
  185.                         path = 'Invalid cover path: ' + str(path)
  186.                         print path
  187.                 else:
  188.                     path = os.path.join(__cwd__, 'resources','skins','DefaultSkin','media','default-cover.png')
  189.                 l1 = song.name
  190.                 l2 = 'By ' + song.artistName + '\n From ' + song.albumName
  191.                 if song.year != None:
  192.                     try:
  193.                         lYear = ' (' + str(int(song.year)) + ')'
  194.                     except:
  195.                         lYear = ''
  196.                 else:
  197.                     lYear = ''
  198.                 l2 = l2 + lYear
  199.                 imageDir = os.path.join(__cwd__, 'resources','skins','DefaultSkin','media')
  200.                 path2 = os.path.join(imageDir, 'gs_smile.png')
  201.                 item = xbmcgui.ListItem (label=l1,label2=l2, thumbnailImage=path, iconImage = path2)
  202.                 listItems.append(item)
  203.             return self, listItems
  204.         except:
  205.             xbmc.log('GrooveShark Exception (listSongs): ' + str(sys.exc_info()[0]))
  206.             traceback.print_exc()
  207.             xbmcgui.unlock()
  208.         return [self, []]
  209.  
  210.     def queueAll(self, playlist = None, append = False):
  211.         if playlist == None:
  212.             playlist = xbmc.PlayList(xbmc.PLAYLIST_MUSIC)      
  213.         if append == False:
  214.             playlist.clear()
  215.             offset = 0
  216.         else:
  217.             offset = playlist.size()
  218.         for i in range(self.count()):
  219.             song = self.get(i)
  220.             self.queue(song, playlist = playlist, index = i + offset)
  221.  
  222.     def play(self, selected, gsapi, playlist = None):
  223.         # It's not pretty but it works
  224.         if playlist == None:
  225.             playlist = xbmc.PlayList(xbmc.PLAYLIST_MUSIC)      
  226.         self.queueAll(playlist, append = False)
  227.  
  228.         song = self.get(selected)
  229.         url = song.getStreamURL(gsapi)
  230.         songName = playlist[selected].getfilename()
  231.         playlist.remove(songName)
  232.  
  233.         self.queue(song, playlist = playlist, index = selected, url = url)
  234.         xbmc.Player().playselected(selected)
  235.         songName = playlist[selected].getfilename()
  236.         playlist.remove(songName)
  237.         self.queue(song, playlist = playlist, index = selected)
  238.        
  239.     def queue(self, song, playlist = None, index = -1, options = '', url = None):
  240.         if playlist == None:
  241.             playlist = xbmc.PlayList(xbmc.PLAYLIST_MUSIC)
  242.         if url == None:
  243.             url = self.defaultUrl(song)
  244.         if index < 0:
  245.             index = playlist.size()
  246.         listItem = self.createListItem(url, song)
  247.         playlist.add(url=url, listitem=listItem, index=index)
  248.  
  249.     def defaultUrl(self, song, options = ''):
  250.         return 'plugin://%s/?playSong=%s&artistId=%s&albumId=%s&image=%s&songName=%s&artistName=%s&albumName=%s&options=%s' % (__scriptid__, song.id, song.artistID, song.albumID, self.encode(song.coverart), self.encode(song.name), self.encode(song.artistName), self.encode(song.albumName), options) # Adding plugin:// to the url makes xbmc call the script to resolve the real url
  251.  
  252.     def encode(self, s):
  253.         try:
  254.             return urllib.quote_plus(s.encode('latin1','ignore'))
  255.         except:
  256.             print '########## GS Encode error'
  257.             print s
  258.             return '### encode error ###'
  259.  
  260.     def createListItem(self, url, song):
  261.         listItem = xbmcgui.ListItem('music', thumbnailImage=song.coverart, iconImage=song.coverart)
  262.         listItem.setProperty( 'Music', "true" )
  263.         listItem.setProperty('mimetype', 'audio/mpeg')
  264.         listItem.setProperty('IsPlayable', 'true') # Tell XBMC that it is playable and not a folder
  265.         listItem.setInfo(type = 'Music', infoLabels = {'title': song.name, 'artist': song.artistName, 'album': song.albumName, 'duration': song.duration, 'path':url})
  266.         return listItem
  267.  
  268. class Albums(GS_Albums):
  269.     def __init__(self, data, defaultCoverArt = None):
  270.         GS_Albums.__init__(self, data, defaultCoverArt = defaultCoverArt)
  271.  
  272.     def setContainers(self):
  273.         self.albumContainer = Album
  274.  
  275.     def _list(self, gui, gsapi):
  276.         n = self.count()
  277.         self.info = str(n) + ' ' + __language__(3025)
  278.         listItems = []
  279.         for i in range(self.count()):
  280.             album = self.get(i)
  281.             item = xbmcgui.ListItem (label=album.name, label2=album.artistName, thumbnailImage=album.coverart, iconImage=album.coverart)
  282.             listItems.append(item)
  283.         return [self, listItems]
  284.  
  285. class Artists(GS_Artists):
  286.     def __init__(self, data, defaultCoverArt = None):
  287.         GS_Artists.__init__(self, data, defaultCoverArt = defaultCoverArt)
  288.  
  289.     def setContainers(self):
  290.         self.artistContainer = Artist
  291.  
  292.     def _list(self, gui, gsapi):
  293.         n = self.count()
  294.         self.info = str(n) + ' ' + __language__(3024)
  295.         path = os.path.join(os.getcwd(),'resources','skins','DefaultSkin', 'media','default-cover.png')
  296.         listItems = []
  297.         for i in range(self.count()):
  298.             artist = self.get(i)
  299.             item = xbmcgui.ListItem (label=artist.name, thumbnailImage=path)
  300.             listItems.append(item)
  301.         return [self, listItems]
  302.  
  303. class Song(GS_Song):
  304.     def __init__(self, data, defaultCoverArt = None):
  305.         GS_Song.__init__(self, data, defaultCoverArt = defaultCoverArt)
  306.  
  307.     def _list(self, gui, gsapi):
  308.         return [None, None]
  309.  
  310.     def setContainers(self):
  311.         self.albumContainer = Album
  312.  
  313.  
  314. class Album(GS_Album):
  315.     def __init__(self, data, defaultCoverArt = None):
  316.         GS_Album.__init__(self, data, defaultCoverArt = defaultCoverArt)
  317.  
  318.     def setContainers(self):
  319.         self.songsContainer = Songs
  320.  
  321.     def _list(self, gui, gsapi):
  322.         songs = self.getSongs(gsapi)
  323.         return songs._list(gui, gsapi)
  324.        
  325. class Artist(GS_Artist):
  326.     def __init__(self, data, defaultCoverArt = None):
  327.         GS_Artist.__init__(self, data, defaultCoverArt = defaultCoverArt)
  328.  
  329.     def setContainers(self):
  330.         self.songsContainer = Songs
  331.         self.albumsContainer = Albums
  332.         self.artistsContainer = Artists
  333.  
  334.     def _list(self, gui, gsapi):
  335.         songs = self.getSongs(gsapi)
  336.         return songs._list(gui, gsapi)
  337.  
  338. class Playlist(Songs):
  339.     def _null(self):
  340.         pass
  341.        
  342. class Popular(GS_PopularSongs):
  343.     def __init__(self, gui, gsapi, type = 'monthly', defaultCoverArt = None):
  344.         self.defaultCoverArt = defaultCoverArt
  345.         self.gui = gui
  346.         self.type = type
  347.         GS_PopularSongs.__init__(self, defaultCoverArt = defaultCoverArt)
  348.  
  349.     def setContainers(self):
  350.         self.songContainer = Song
  351.  
  352.     def _list(self, gui, gsapi):
  353.         data = self._getPopular(gsapi)
  354.         return Songs(data, self.defaultCoverArt)._list(gui, gsapi)
  355.  
  356. class Favorites(GS_FavoriteSongs):
  357.     def __init__(self, gui, gsapi, defaultCoverArt = None):
  358.         self.defaultCoverArt = defaultCoverArt
  359.         self.gui = gui
  360.         self.type = type
  361.         GS_FavoriteSongs.__init__(self, defaultCoverArt = defaultCoverArt)
  362.  
  363.     def setContainers(self):
  364.         self.songContainer = Song
  365.  
  366.     def _list(self, gui, gsapi):
  367.         data = self._favorites(gsapi)
  368.         if data == None:
  369.             gui.notification(__language__(3027)) #Wrong username/password
  370.             return None
  371.         return Songs(data, self.defaultCoverArt)._list(gui, gsapi)
  372.  
  373. class Playlists(GS_Playlists):
  374.     def __init__(self, gui, defaultCoverArt = None):
  375.         self.gui = gui
  376.         GS_Playlists.__init__(self, defaultCoverArt = defaultCoverArt)
  377.  
  378.     def setContainers(self):
  379.         self.playlistContainer = Playlist
  380.  
  381.     def _list(self, gui, gsapi):
  382.         if self.getPlaylists(gsapi) == False:
  383.             gui.notification(__language__(3027))
  384.             return [None, None]
  385.         n = self.count()
  386.         self.info = str(n) + ' ' + __language__(3042)
  387.         listItems = []
  388.         for i in range(self.count()):
  389.             playlist = self.get(i)
  390.             if playlist.about == None:
  391.                 l2 = ''
  392.             else:
  393.                 l2 = playlist.about
  394.             item = xbmcgui.ListItem (label=playlist.name, label2=l2, thumbnailImage=self.defaultCoverArt, iconImage=self.defaultCoverArt)
  395.             listItems.append(item)
  396.         return [self, listItems]
  397.  
  398. class Playlist(GS_Playlist):
  399.     def setContainers(self):
  400.         self.songsContainer = Songs
  401.  
  402.     def _list(self, gui, gsapi):
  403.         data = self.getSongs(gsapi)
  404.         return self.songs._list(gui, gsapi)
  405.  
  406. class RootTree:
  407.     def __init__(self, gui, gsapi, defaultCoverArt = None):
  408.         self.defaultCoverArt = defaultCoverArt
  409.         self.gui = gui
  410.         self._search = Search(gui = gui, defaultCoverArt = self.defaultCoverArt)
  411.         self.tree = [self._search,\
  412.                         Popular(gui = gui, gsapi = gsapi, type = 'monthly', defaultCoverArt = self.defaultCoverArt),\
  413.                         Favorites(gui = gui, gsapi = gsapi, defaultCoverArt = self.defaultCoverArt),\
  414.                         Playlists(gui = gui, defaultCoverArt = self.defaultCoverArt),\
  415.                         NowPlaying(gui = gui, gsapi = gsapi, defaultCoverArt = self.defaultCoverArt)]
  416.  
  417.         pass
  418.  
  419.     def get(self, n):
  420.         return self.tree[n]
  421.  
  422.     def setSearch(self):
  423.         pass
  424.  
  425.     def _list(self, gui, gsapi):
  426.         self.info = ''
  427.         pathSearch = os.path.join(__cwd__,'resources','skins','DefaultSkin', 'media', 'gs_search.png')
  428.         pathPopular = os.path.join(__cwd__,'resources','skins','DefaultSkin', 'media', 'gs_popular.png')
  429.         pathFavorites = os.path.join(__cwd__,'resources','skins','DefaultSkin', 'media', 'gs_favorites.png')
  430.         pathPlaylist = os.path.join(__cwd__,'resources','skins','DefaultSkin', 'media', 'gs_playlist.png')
  431.         pathNowPlaying = os.path.join(__cwd__,'resources','skins','DefaultSkin', 'media', 'gs_song.png')
  432.         try:
  433.             searchLabel = 'Found ' + str(self._search.countResults()) + ' for "' + self._search.queryText + '"'
  434.         except:
  435.             searchLabel = 'Start a new search in the menu'
  436.             traceback.print_exc()
  437.  
  438.         listItems = [\
  439.             xbmcgui.ListItem (label=__language__(128), label2=searchLabel, thumbnailImage=pathSearch),\
  440.             xbmcgui.ListItem (label=__language__(108), label2=__language__(3041), thumbnailImage=pathPopular),\
  441.             xbmcgui.ListItem (label=__language__(129), label2='Your favorites', thumbnailImage=pathFavorites),\
  442.             xbmcgui.ListItem (label=__language__(117), label2=__language__(3039), thumbnailImage=pathPlaylist),\
  443.             xbmcgui.ListItem (label=__language__(107), label2='Have a look at the tunes you\'re playing', thumbnailImage=pathNowPlaying),\
  444.         ]
  445.         self.gui.setStateLabel('')
  446.         return [self, listItems]
  447.  
  448. class Navigation:
  449.     tree = []
  450.     def __init__(self, gui, gsapi, optionsCallBack = None, displayCallBack = None, optionsShowCallback = None):
  451.         self.gsapi = gsapi
  452.         self.gui = gui
  453.         self.optionsCallBack = optionsCallBack
  454.         self.displayCallBack = displayCallBack
  455.         self.optionsShowCallBack = optionsShowCallback
  456.         pass
  457.  
  458.     def showOptions(self, item):
  459.         self.debug('showOptions called in navi')
  460.         if self.optionsShowCallBack != None:
  461.             return self.optionsShowCallBack(item)
  462.  
  463.     def setOptions(self, item):
  464.         if self.optionsCallBack != None:
  465.             return self.optionsCallBack(item)
  466.  
  467.     def displayItems(self, item, selected = 0):
  468.         if self.displayCallBack != None:
  469.             return self.displayCallBack(item, selected = selected)
  470.  
  471.     def locationLabel(self):
  472.         return
  473.         location = ''
  474.         for i in range(len(self.tree)):
  475.             if self.location[i]['query'] != '':
  476.                 query = '(' + self.truncateText(self.location[i]['query'], 15) + ')'
  477.             else:
  478.                 query = ''
  479.             if i == 0:
  480.                 location = self.location[0]['folderName'] + ' ' + query
  481.             else:
  482.                 if self.location[i]['truncate'] == True:
  483.                     folderName = self.truncateText(self.location[i]['folderName'],15)
  484.                 else:
  485.                     folderName = self.location[i]['folderName']
  486.                 location += ' > ' + folderName + ' ' + query
  487.         self.setStateLabel(location)
  488.        
  489.  
  490.     def reset(self):
  491.         self.tree = []
  492.  
  493.     def navigate(self, p):
  494.         n = len(self.tree)
  495.         print 'Navigate: n = ' + str(n) + ', p = ' + str(p)
  496.         if n > 1:
  497.             if p == 0:
  498.                 self.up()
  499.             else:
  500.                 try:
  501.                     item = self.getBranchObject().get(p-1)
  502.                     print 'navigate()::get(): Type: ' + str(item)
  503.                     self.down(item, selected = p)
  504.                 except:
  505.                     traceback.print_exc()
  506.                     print 'navigate()::get() failed p-1'
  507.         else:
  508.             try:
  509.                 item = self.getBranchObject().get(p)
  510.                 print 'Type: ' + str(item)
  511.                 self.down(item, selected = p)
  512.             except:
  513.                 traceback.print_exc()
  514.                 print 'navigate()::get() failed p'
  515.  
  516.     def up(self):
  517.         n = len(self.tree)
  518.         if n > 1:
  519.             self.tree.pop(n-1)
  520.             self._list()
  521.         pass
  522.  
  523.     def addBack(self):
  524.         try:
  525.             n = len(self.tree)
  526.             if n > 1:
  527.                 path = os.path.join(__cwd__,'resources','skins','DefaultSkin', 'media', 'gs_back.png')
  528.                 item = xbmcgui.ListItem (label='', label2='', thumbnailImage=path, iconImage=self.gui.defaultCoverArt)
  529.                 self.gui.addItem(item)
  530.         except:
  531.             traceback.print_exc()
  532.  
  533.  
  534.     def hasBack(self):
  535.         n = len(self.tree)
  536.         if n > 1:
  537.             return True
  538.         return False
  539.  
  540.     def updateList(self, branch, subBranch, selected = 0):
  541.         while len(self.tree) > (branch + 1):
  542.             self.tree.pop(len(self.tree)-1)
  543.         _branch = self.tree[branch]
  544.         listItems = _branch['branchObject']._list(gui = self.gui, gsapi = self.gsapi)[1]
  545.         _branch['listItems'] = listItems
  546.         subBranchObj = _branch['branchObject'].get(subBranch)
  547.         self.down(subBranchObj, preSelected = selected)
  548.        
  549.        
  550.     def down(self, item, selected = 0, withList = True, preSelected = 0):
  551.         if item == None:
  552.             return
  553.         lock()
  554.         try:
  555.             res = item._list(self.gui, self.gsapi)
  556.             branchObject = res[0]
  557.             listItems = res[1]
  558.         except:
  559.             unlock()
  560.             traceback.print_exc()
  561.             return
  562.         try:
  563.             n = len(self.tree)
  564.             if n > 0:
  565.                 self.tree[n-1]['selected'] = selected
  566.             if branchObject != None:
  567.                 self.addBranch(listItems, branchObject, selected = preSelected)
  568.                 if withList == True:
  569.                     self._list()
  570.             else:
  571.                 self.showOptions(self.getBranchObject())
  572.         except:
  573.             unlock()
  574.             traceback.print_exc()
  575.             print 'Could not descend a level'
  576.  
  577.     def addBranch(self, listItems, branchObject, selected = 0):
  578.         n = len(listItems)
  579.         print 'sel: ' + str(selected) + ' n: ' + str(n)
  580.         if selected > n:
  581.             selected = n
  582.         self.tree.append({'listItems': listItems, 'branchObject': branchObject, 'selected': selected})
  583.  
  584.     def setSelected(self, selected):
  585.         n = len(self.tree)
  586.         self.tree[n-1]['selected'] = selected
  587.  
  588.     def getListItems(self, n = -1):
  589.         if n == -1:
  590.             n = len(self.tree)
  591.         return self.tree[n-1]['listItems']
  592.  
  593.     def getBranchObject(self, n = -1):
  594.         if n == -1:
  595.             n = len(self.tree)
  596.         return self.tree[n-1]['branchObject']
  597.  
  598.     def _list(self):
  599.         obj = self.getBranchObject()
  600.         try:
  601.             info = obj.info
  602.         except:
  603.             info = ''
  604.         self.gui.setInfoLabel(info)
  605.         self.gui.clearList()
  606.         self.addBack()
  607.         listItems = self.getListItems()
  608.         n = len(self.tree)
  609.         self.displayItems(listItems, selected = self.tree[n-1]['selected'])
  610.         self.setOptions(obj)
  611.    
  612.     def debug(self, msg):
  613.         print msg
  614.  
  615. class searchThread(threading.Thread):
  616.     def __init__(self, item, query, searchLimit):
  617.         threading.Thread.__init__(self)
  618.         self.item = item
  619.         self.query = query
  620.         self.searchLimit = searchLimit
  621.  
  622.     def run (self):
  623.         try:
  624.             function = self.item['function']
  625.             if self.query == None:
  626.                 self.item['result'] = function(self.searchLimit)
  627.             else:
  628.                 self.item['result'] = function(self.query, self.searchLimit)
  629.         except:
  630.             self.item['result'] = None
  631.             print "GrooveShark: Search thread failed"
  632.             traceback.print_exc()
  633.  
  634. class Options:
  635.     def __init__(self, cntList, cntLabel, cntImage, gui):
  636.         self.cntLabel = cntLabel
  637.         self.cntList = cntList
  638.         self.cntImage = cntImage
  639.         self.reset()
  640.  
  641.     def reset(self):
  642.         self.items = []
  643.         self.lastUpdatedItems = []
  644.         self.label = ''
  645.         self.image = ''
  646.  
  647.     def addOption(self, name, callback):
  648.         self.items.append({'name': name, 'callback': callback})
  649.  
  650.     def addOptions(self, items):
  651.         self.lastUpdatedItems = []
  652.         for item in items:
  653.             self.items.append(item)
  654.  
  655.     def setLabel(self, s):
  656.         self.label = s
  657.  
  658.     def setImage(self, path):
  659.         self.cntImage.setImage(path)
  660.  
  661.     def countEnabled(self, withBack = True):
  662.         if withBack == True:
  663.             return len(self.items)
  664.         n = 0
  665.         for item in self.items:
  666.             if item['enabledOnBack'] == True:
  667.                 n += 1
  668.         return n
  669.  
  670.     def execute(self):
  671.         n = self.cntList.getSelectedPosition()
  672.         try:
  673.             f = self.lastUpdatedItems[n]['callback']
  674.             f(obj = self.obj, selected = self.selected, item = self.lastUpdatedItems[n])
  675.         except:
  676.             print 'execute(): Error when using callback. Obj: ' + str(self.obj.__class__) + ', callback: ' + str(type(f)) + ', n: ' + str(n)
  677.             traceback.print_exc()
  678.  
  679.     def update(self, selected = 0, back = False, obj = None):
  680.         self.obj = obj
  681.         self.selected = selected
  682.         self.cntLabel.setLabel(self.label)
  683.         self.cntList.reset()
  684.         n = self.countEnabled(withBack = (not back))
  685.         for item in self.items:
  686.             icon = ''
  687.             try:
  688.                 icon = item['icon']
  689.             except:
  690.                 pass
  691.             listItem = xbmcgui.ListItem (label=item['name'], label2='', thumbnailImage=icon, iconImage='')
  692.             if back == True:
  693.                 if item['enabledOnBack'] == True:
  694.                     self.cntList.addItem(listItem)
  695.                     self.lastUpdatedItems.append(item)
  696.             else:
  697.                 self.cntList.addItem(listItem)
  698.                 self.lastUpdatedItems.append(item)
  699.  
  700. class GrooveClass(xbmcgui.WindowXML):
  701.     def setStateLabel(self, msg):
  702.         self.getControl(3000).setLabel(msg)
  703.  
  704.     def setInfoLabel(self, msg):
  705.         cnt = self.getControl(300011)
  706.         cnt.setLabel(msg)
  707.         cnt.setVisible(True)
  708.  
  709.     def notification(self, message):
  710.         cnt = self.getControl(7001)
  711.         label = self.getControl(7003)
  712.         label.setLabel(message)
  713.         self.setFocus(cnt)
  714.         xbmc.sleep(100)
  715.         self.playlistHasFocus()
  716.  
  717.     def displayItems(self, items, selected = 0):
  718.         xbmcgui.lock()
  719.         try:
  720.             for item in items:
  721.                 self.addItem(item)
  722.             self.setCurrentListPosition(selected)
  723.             self.playlistHasFocus()
  724.             xbmcgui.unlock()
  725.         except:
  726.             xbmcgui.unlock()
  727.             self.debug('displayItems(): Could not add items')
  728.  
  729.     def setOptionsPlaylists(self, song):
  730.         playlists = Playlists(self, defaultCoverArt = self.defaultCoverArt)
  731.         playlists.getPlaylists(self.gs)
  732.         self.options = self.optionsPlaylists
  733.         print 'setOptionsPlaylists() called'
  734.         cnt = self.getControl(500)
  735.         cnt.setEnabled(True)
  736.         items = []
  737.         for i in range(playlists.count()):
  738.             playlist = playlists.get(i)
  739.             item = {'name': playlist.name, 'callback': self.addSongToPlaylistExec, 'enabledOnBack': True, 'song': song, 'playlist': playlist}
  740.             items.append(item)
  741.  
  742.         self.options.reset()
  743.         self.options.setLabel('Which?')
  744.         self.options.setImage(os.path.join(self.imageDir, 'gs_addsong.png'))
  745.         self.options.addOptions(items)
  746.         self.options.update()
  747.  
  748.     def setOptionsMenu(self):
  749.         self.options = self.optionsMenu
  750.         self.debug('setOptionsMenu() called')
  751.         cnt = self.getControl(500)
  752.         cnt.setEnabled(True)
  753.         items = []
  754.         items = [{'name': __language__(106), 'callback': self.newSearch, 'enabledOnBack': True, 'icon': 'gs_search.png'},\
  755.                     {'name': __language__(117), 'callback': self.showPlaylists, 'enabledOnBack': True, 'icon': 'gs_playlist.png'},\
  756.                     {'name': __language__(107), 'callback': self.showNowPlaying, 'enabledOnBack': True, 'icon': 'gs_song.png'},\
  757.                     {'name': __language__(109), 'callback': self.settings, 'enabledOnBack': True, 'icon': 'gs_wrench.png'},\
  758.                     {'name': __language__(121), 'callback': self.exit, 'enabledOnBack': True, 'icon': 'gs_exit.png'}]
  759.  
  760.         self.options.reset()
  761.         self.options.setLabel('')
  762.         self.options.setImage(os.path.join(self.imageDir, 'gs_home.png'))
  763.         self.options.addOptions(items)
  764.         self.options.update()
  765.  
  766.     def setOptionsRight(self, obj):
  767.         self.options = self.optionsRight
  768.         print 'setOptionsRight() called'
  769.         cnt = self.getControl(500)
  770.         cnt.setEnabled(True)
  771.         if isinstance(obj, Song):
  772.             pass
  773.         if isinstance(obj, Songs):
  774.             items = [{'name': __language__(102), 'callback': self.play, 'enabledOnBack': False, 'icon':'gs_play_item.png'},\
  775.                         {'name': __language__(101), 'callback': self.queueSong, 'enabledOnBack': False, 'icon':'gs_enqueue.png'},\
  776.                         {'name': __language__(103), 'callback': self.queueAllSongs, 'enabledOnBack': True, 'icon':'gs_enqueue.png'},\
  777.                         {'name': __language__(104), 'callback': self.addSongToPlaylist, 'enabledOnBack': False, 'icon':'gs_addsong.png'},\
  778.                         {'name':  __language__(119), 'callback': self.findSimilarFromSong, 'enabledOnBack': False, 'icon':'gs_similar.png'},\
  779.                         {'name':  __language__(120), 'callback': self.songsOnAlbum, 'enabledOnBack': False, 'icon':'gs_album.png'}]
  780.             self.options.reset()
  781.             self.options.setLabel('')
  782.             self.options.setImage(os.path.join(self.imageDir, 'gs_song.png'))
  783.             self.options.addOptions(items)
  784.             self.options.update()
  785.         if isinstance(obj, Albums):
  786.             items = [{'name': __language__(125), 'callback': self.playAlbum, 'enabledOnBack': False, 'icon': 'gs_play_item.png'},\
  787.                         {'name': __language__(126), 'callback': self.queueAlbum, 'enabledOnBack': False, 'icon': 'gs_enqueue.png'},\
  788.                         {'name': __language__(127), 'callback': self.saveAlbumAsPlaylist, 'enabledOnBack': False, 'icon': 'gs_savealbum.png'},\
  789.                         {'name':  __language__(119), 'callback': self.findSimilarFromAlbum, 'enabledOnBack': False, 'icon': 'gs_similar.png'}]
  790.             self.options.reset()
  791.             self.options.setLabel('')
  792.             self.options.setImage(os.path.join(self.imageDir, 'gs_album.png'))
  793.             self.options.addOptions(items)
  794.             self.options.update()
  795.         if isinstance(obj, Playlists):
  796.             items = [{'name': __language__(111), 'callback': self.renamePlaylist, 'enabledOnBack': False, 'icon': 'gs_rename.png'},\
  797.                         {'name': __language__(112), 'callback': self.deletePlaylist, 'enabledOnBack': False, 'icon': 'gs_delete2.png'}]
  798.             self.options.reset()
  799.             self.options.setLabel('')
  800.             self.options.setImage(os.path.join(self.imageDir, 'gs_playlist.png'))
  801.             self.options.addOptions(items)
  802.             self.options.update()
  803.         if isinstance(obj, Artists):
  804.             items = [{'name': 'Play songs', 'callback': self.playSongsByArtist, 'enabledOnBack': False, 'icon': 'gs_play_item.png'},\
  805.                         {'name':  __language__(119), 'callback': self.findSimilarFromArtist, 'enabledOnBack': False, 'icon': 'gs_similar.png'}]
  806.             self.options.reset()
  807.             self.options.setLabel('')
  808.             self.options.setImage(os.path.join(self.imageDir, 'gs_artist.png'))
  809.             self.options.addOptions(items)
  810.             self.options.update()
  811.         if isinstance(obj, Search):
  812.             cnt = self.getControl(500)
  813.             cnt.setEnabled(False)
  814.             self.options.reset()
  815.             self.options.setLabel('')
  816.             self.options.update()
  817.         if isinstance(obj, RootTree):  
  818.             cnt = self.getControl(500)
  819.             cnt.setEnabled(False)
  820.             self.options.reset()
  821.             self.options.setLabel('')
  822.             self.options.update()
  823.  
  824.     def insertOptions(self, items):
  825.         cnt = self.getControl(500)
  826.         cnt.addItems(items)
  827.  
  828.     def setOptionsLabel(self, msg):
  829.         self.getControl(4100).setLabel(msg)
  830.  
  831.     def showOptionsRight(self, obj):
  832.         self.setOptionsRight(obj)
  833.         self.optionsHasFocus()
  834.  
  835.     def saveAlbumAsPlaylist(self, selected = 0, obj = None, item = None):
  836.         album = obj.get(selected)
  837.         name = album.artistName + ' - ' + album.name
  838.         name = self.getInput('Name for playlist', default=name)
  839.         if name == None:
  840.             return
  841.         if name != '':
  842.             lock()
  843.             try:
  844.                 songs = album.getSongs(self.gs)
  845.                 info = {'Name': name, 'PlaylistID': -1, 'About': ''}
  846.                 Playlist(info, songs = songs).saveAs(self.gs)
  847.                 unlock()
  848.                 self.notification('Saved')
  849.             except:
  850.                 unlock()
  851.                 self.notification('Sorry')
  852.         else:
  853.             unlock()
  854.             self.notification('Type a name')
  855.  
  856.     def addSongToPlaylist(self, selected = 0, obj = None, item = None):
  857.         lock()
  858.         try:
  859.             songs = obj
  860.             self.setOptionsPlaylists(songs.get(selected))      
  861.             unlock()
  862.             cnt = self.getControl(500)
  863.             self.setFocus(cnt)
  864.         except:
  865.             unlock()
  866.             self.notification('Sorry')         
  867.             traceback.print_exc()
  868.         pass
  869.  
  870.     def addSongToPlaylistExec(self, selected = 0, obj = None, item = None):
  871.         lock()
  872.         song = item['song']
  873.         playlist = item['playlist']
  874.         playlist.getSongs(self.gs)
  875.         playlist.addSong(song)
  876.         playlist.save(self.gs)
  877.         unlock()
  878.         self.notification('Added')
  879.  
  880.     def exit(self, selected = 0, obj = None, item = None):
  881.         self.close()
  882.  
  883.     def settings(self, selected = 0, obj = None, item = None):
  884.         try:
  885.             username = __settings__.getSetting('username')
  886.             password = __settings__.getSetting('password')
  887.             core = __settings__.getSetting('player_core')
  888.             debug = __settings__.getSetting('debug')
  889.             __settings__.openSettings()
  890.             #try:
  891.             #   self.searchLimit = int(__settings__.getSetting('search_limit'))
  892.             #except:
  893.             #   self.searchLimit = 100
  894.             #self.gs.setRemoveDuplicates(__settings__.getSetting('remove_duplicates'))
  895.             #self.useCoverArt = self.convertToBool(__settings__.getSetting('covers_in_script'))
  896.             #self.useCoverArtNowPlaying = self.convertToBool(__settings__.getSetting('cover_now_playing'))
  897.             # Check to see if things have changed:
  898.             if __settings__.getSetting('username') != username or __settings__.getSetting('password') != password:
  899.                 self.gs.startSession(__settings__.getSetting('username'), __settings__.getSetting('password'))
  900.             if __settings__.getSetting('player_core') != core:
  901.                 self.initPlayer()
  902.             if __settings__.getSetting('debug') != debug:
  903.                 debug = __settings__.getSetting('debug')
  904.                 if debug == 'false':
  905.                     __debugging__ = False
  906.                 else:
  907.                     __debugging__ = True
  908.                 self.gs._enableDebug(__debugging__)
  909.         except:
  910.             traceback.print_exc()
  911.  
  912.     def newSearch(self, selected = 0, obj = None, item = None):
  913.         self.playlistHasFocus()
  914.         search = SearchGUI()
  915.         #text = self.getInput(__language__(1000), "")
  916.         result = search.getResult()
  917.         if result != None:
  918.             lock()
  919.             try:
  920.                 text = result['query']
  921.                 self.rootTree.tree[0].search(query= text, gsapi = self.gs)
  922.                 self.navi.updateList(0, 0)
  923.                 self.navi._list()
  924.                 unlock()
  925.             except:
  926.                 unlock()
  927.                 self.notification('Sorry')
  928.  
  929.     def deletePlaylist(self, selected = 0, obj = None, item = None):
  930.         lock()
  931.         try:
  932.             playlist = obj.get(selected)
  933.             playlist.delete(self.gs)
  934.             self.navi.updateList(0, 3, selected = selected) #Reload playlists
  935.             unlock()
  936.             self.notification('Deleted')
  937.         except:
  938.             unlock()
  939.             self.notification('Sorry')
  940.  
  941.     def renamePlaylist(self, selected = 0, obj = None, item = None):
  942.         playlist = obj.get(selected)
  943.         name = self.getInput(__language__(111), default=playlist.name)
  944.         if name != '' and name != None:
  945.             lock()
  946.             try:
  947.                 playlist.rename(self.gs, name)
  948.                 self.navi.updateList(0, 3, selected = selected) #Reload playlists
  949.                 unlock()
  950.                 self.notification('Renamed')
  951.             except:
  952.                 unlock()
  953.                 self.notification('Sorry')
  954.  
  955.     def play(self, selected = 0, obj = None, item = None):
  956.         lock()
  957.         try:
  958.             obj.play(selected = selected, gsapi = self.gs, playlist = self.xbmcPlaylist)
  959.             unlock()
  960.         except:
  961.             unlock()
  962.             self.notification('Sorry')
  963.             traceback.print_exc()
  964.  
  965.     def queueSong(self, selected = 0, obj = None, item = None):
  966.         lock()
  967.         try:
  968.             song = obj.get(selected)
  969.             obj.queue(song, playlist = self.xbmcPlaylist)
  970.             unlock()
  971.             self.notification('Queued')
  972.         except:
  973.             unlock()
  974.             self.notification('Sorry')
  975.  
  976.     def queueAllSongs(self, selected = 0, obj = None, item = None):
  977.         lock()
  978.         try:
  979.             obj.queueAll(playlist = self.xbmcPlaylist, append = True)
  980.             unlock()
  981.             self.notification('Queued')
  982.         except:
  983.             unlock()
  984.             self.notification('Sorry')
  985.  
  986.     def playAlbum(self, selected = 0, obj = None, item = None):
  987.         lock()
  988.         try:
  989.             album = obj.get(selected)
  990.             songs = album.getSongs(self.gs)
  991.             songs.play(selected = 0, gsapi = self.gs, playlist = self.xbmcPlaylist)
  992.             unlock()
  993.         except:
  994.             unlock()
  995.             self.notification('Sorry')
  996.  
  997.     def queueAlbum(self, selected = 0, obj = None, item = None):
  998.         lock()
  999.         try:
  1000.             album = obj.get(selected)
  1001.             songs = album.getSongs(self.gs)
  1002.             songs.queueAll(playlist = self.xbmcPlaylist, append = True)
  1003.             unlock()
  1004.             self.notification('Queued')
  1005.         except:
  1006.             unlock()
  1007.             self.notification('Sorry')
  1008.  
  1009.     def playSongsByArtist(self, selected = 0, obj = None, item = None):
  1010.         lock()
  1011.         try:
  1012.             artist = obj.get(selected)
  1013.             songs = artist.getSongs(self.gs)
  1014.             songs.play(selected = 0, gsapi = self.gs, playlist = self.xbmcPlaylist)
  1015.             unlock()
  1016.         except:
  1017.             unlock()
  1018.             self.notification('Sorry')
  1019.  
  1020.     def showPlaylists(self, selected = 0, obj = None, item = None):
  1021.         self.navi.updateList(0, 3)
  1022.         self.navi._list()
  1023.  
  1024.     def showNowPlaying(self, selected = 0, obj = None, item = None):
  1025.         self.navi.updateList(0, 4)
  1026.         self.navi._list()
  1027.         return
  1028.         #Disable the old way for now
  1029.         wId = xbmcgui.getCurrentWindowId()
  1030.         gWin = xbmcgui.Window(wId)
  1031.         pWin = xbmcgui.Window(10500)
  1032.         selected = self.getCurrentListPosition()
  1033.         self.navi.setSelected(selected)
  1034.         pWin.show()
  1035.         while xbmcgui.getCurrentWindowId() == 10500: #Music playlist
  1036.             xbmc.sleep(100)
  1037.             pass
  1038.         while xbmcgui.getCurrentWindowId() == 12006:#Visualization
  1039.             xbmc.sleep(100)
  1040.         if xbmcgui.getCurrentWindowId() != wId:
  1041.             gWin.show()
  1042.         self.navi._list()
  1043.  
  1044.     def findSimilarFromSong(self, selected = 0, obj = None, item = None):
  1045.         lock()
  1046.         try:
  1047.             song = obj.get(selected)
  1048.             artist = Artist(song.artistID)
  1049.             artists = artist.similar(gsapi = self.gs)
  1050.             self.navi.down(artists, selected+1)
  1051.             unlock()
  1052.         except:
  1053.             unlock()
  1054.             self.notification('Sorry')
  1055.  
  1056.     def findSimilarFromAlbum(self, selected = 0, obj = None, item = None):
  1057.         lock()
  1058.         try:
  1059.             album = obj.get(selected)
  1060.             artist = Artist(album.artistID)
  1061.             artists = artist.similar(gsapi = self.gs)
  1062.             self.navi.down(artists, selected+1)
  1063.             unlock()
  1064.         except:
  1065.             unlock()
  1066.             self.notification('Sorry')
  1067.  
  1068.     def findSimilarFromArtist(self, selected = 0, obj = None, item = None):
  1069.         lock()
  1070.         try:
  1071.             artist = obj.get(selected)
  1072.             artists = artist.similar(gsapi = self.gs)
  1073.             self.navi.down(artists, selected+1)
  1074.             unlock()
  1075.         except:
  1076.             unlock()
  1077.             self.notification('Sorry')
  1078.  
  1079.     def songsOnAlbum(self, selected = 0, obj = None, item = None):
  1080.         lock()
  1081.         try:
  1082.             song = obj.get(selected)
  1083.             albumId = song.albumID
  1084.             songs = Album(albumId, defaultCoverArt = self.defaultCoverArt).getSongs(gsapi = self.gs)
  1085.             self.navi.down(songs, selected+1)
  1086.             unlock()
  1087.         except:
  1088.             unlock()
  1089.             self.notification('Sorry')
  1090.  
  1091.     def message(self, message, title = ''):
  1092.         dialog = xbmcgui.Dialog()
  1093.         dialog.ok(title, message)
  1094.  
  1095.     def onInit(self):
  1096.         setPGUI(self)
  1097.         try:
  1098.             if self.initialized == True:
  1099.                 self.navi._list()
  1100.                 pass
  1101.         except:
  1102.             self.initVars()
  1103.             self.loadState()
  1104.             try:
  1105.                 self.gs = GrooveAPI(enableDebug = __debugging__, cwd = self.confDir ,clientUuid = None, clientVersion = None)
  1106.                 username = __settings__.getSetting("username")
  1107.                 password = __settings__.getSetting("password")
  1108.                 self.gs.startSession(username, password)
  1109.                 self.gs.setRemoveDuplicates(__settings__.getSetting('remove_duplicates'))
  1110.             except:
  1111.                 self.message(__language__(3046), __language__(3011)) #Unable to get new session ID
  1112.                 xbmc.log('GrooveShark Exception (onInit): ' + str(sys.exc_info()[0]))
  1113.                 traceback.print_exc()
  1114.                 self.close()
  1115.                 return
  1116.             self.initialized = True
  1117.             self.initPlayer()
  1118.             self.optionsRight = Options(self.getControl(500), self.getControl(4100), self.getControl(410), self)
  1119.             self.optionsPlaylists = Options(self.getControl(500), self.getControl(4100), self.getControl(410), self)
  1120.             self.optionsMenu = Options(self.getControl(500), self.getControl(4100), self.getControl(410), self)
  1121.             self.navi = Navigation(self, self.gs, displayCallBack = self.displayItems, optionsCallBack = self.setOptionsRight, optionsShowCallback = self.showOptionsRight)
  1122.             self.rootTree = RootTree(self, self.gs, defaultCoverArt = os.path.join(self.imageDir, 'default-cover.png'))
  1123.             self.navi.down(self.rootTree)
  1124.  
  1125.     def __del__(self):
  1126.         print 'GrooveShark: __del__() called'
  1127.         self.saveState()
  1128.  
  1129.     def initPlayer(self):
  1130.         try:
  1131.             core = __settings__.getSetting('player_core')
  1132.             if core == 'MPlayer':
  1133.                 self.player = GroovePlayer(xbmc.PLAYER_CORE_MPLAYER)
  1134.             elif core == 'DVDPlayer':
  1135.                 self.player = GroovePlayer(xbmc.PLAYER_CORE_DVDPLAYER)
  1136.             elif core == 'PAPlayer':
  1137.                 self.player = GroovePlayer(xbmc.PLAYER_CORE_PAPLAYER)
  1138.             else:
  1139.                 self.player = GroovePlayer()
  1140.             print 'GrooveShark: Player core: ' + core
  1141.             self.player.setCallBackFunc(self.playerChanged)
  1142.         except:
  1143.             xbmc.log('GrooveShark Exception (initPlayer): ' + str(sys.exc_info()[0]))
  1144.             traceback.print_exc()
  1145.        
  1146.     def onFocus(self, controlID):
  1147.         self.debug('onFocus(): id = ' + str(controlID)                  )
  1148.         pass
  1149.  
  1150.     def onAction(self, action):
  1151.         aId = action.getId()
  1152.         if aId == 10:
  1153.             if self.getFocusId() == 500:
  1154.                 self.playlistHasFocus()
  1155.             else:
  1156.                 self.setOptionsMenu()
  1157.                 self.optionsHasFocus()
  1158.         elif aId == 1:
  1159.             cid = self.getFocusId()
  1160.             if cid != 500:
  1161.                 self.setOptionsMenu()
  1162.                 self.optionsHasFocus()
  1163.             else:
  1164.                 self.playlistHasFocus()
  1165.  
  1166.         elif aId == 2:
  1167.             cid = self.getFocusId()
  1168.             if cid != 500:
  1169.                 self.setOptionsRight(self.navi.getBranchObject())
  1170.                 self.optionsHasFocus()
  1171.             else:
  1172.                 self.playlistHasFocus()
  1173.  
  1174.         elif aId == 9:
  1175.             self.navi.up()
  1176.         else:
  1177.             pass
  1178.  
  1179.     def onClick(self, control):
  1180.         self.debug('onClick: ' + str(control))
  1181.         if control == 500:
  1182.             self.options.execute()
  1183.             if self.options == self.optionsRight:
  1184.                 pass #FIXME
  1185.  
  1186.         elif control == 50:
  1187.             self.setOptionsRight(self.navi.getBranchObject())
  1188.             self.navi.navigate(self.getCurrentListPosition())
  1189.         else:
  1190.             pass
  1191.    
  1192.     def debug(self, msg):
  1193.         if __debugging__ == True:
  1194.             print 'GrooveShark: ' + str(msg)
  1195.  
  1196.     def convertToBool(self, s):
  1197.         if s == 'true' or s == 'True' or s == True:
  1198.             return True
  1199.         else:
  1200.             return False
  1201.  
  1202.     def initVars(self):
  1203.         self.nowPlayingList = []
  1204.         self.searchText = ""
  1205.         self.rootDir = __cwd__
  1206.         self.xbmcPlaylist = xbmc.PlayList(xbmc.PLAYLIST_MUSIC)
  1207.         self.defaultCoverArt = os.path.join(__cwd__,'resources','skins','DefaultSkin', 'media','default-cover.png')
  1208.         #try:
  1209.         #   self.searchLimit = int(__settings__.getSetting('search_limit'))
  1210.         #except:
  1211.         #   self.searchLimit = 100
  1212.         #self.useCoverArt = self.convertToBool(__settings__.getSetting('covers_in_script'))
  1213.         self.useCoverArt = True
  1214.         #self.useCoverArtNowPlaying = self.convertToBool(__settings__.getSetting('cover_now_playing'))
  1215.         if __isXbox__ == True:
  1216.             self.dataDir = 'script_data'
  1217.             dataRoot = os.path.join('special://profile/', self.dataDir)
  1218.             if os.path.exists(dataRoot) == False:
  1219.                 os.mkdir(dataRoot)
  1220.         else:
  1221.             self.dataDir = 'addon_data'
  1222.  
  1223.         self.imageDir = os.path.join(__cwd__,'resources','skins','DefaultSkin', 'media')
  1224.         self.confDir = os.path.join('special://profile/', self.dataDir, __scriptid__)
  1225.         self.defaultArtTinyUrl = 'http://beta.grooveshark.com/webincludes/img/defaultart/album/tdefault.png'
  1226.         self.defaultArtSmallUrl = 'http://beta.grooveshark.com/webincludes/img/defaultart/album/sdefault.png'
  1227.         self.defaultArtMediumUrl = 'http://beta.grooveshark.com/webincludes/img/defaultart/album/mdefault.png'
  1228.  
  1229.     def saveState(self):
  1230.         try:
  1231.             print 'GrooveShark: Saving state'
  1232.             self.location[len(self.location)-1]['itemFocused'] = self.getCurrentListPosition()
  1233.             dir = os.path.join(self.confDir, 'state')
  1234.             # Create the 'state' directory if it doesn't exist.
  1235.             if not os.path.exists(dir):
  1236.                 os.mkdir(dir)
  1237.             path = os.path.join(dir, 'state.txt')
  1238.             f = open(path, 'wb')
  1239.             pickle.dump(self.getState(), f, protocol=pickle.HIGHEST_PROTOCOL)
  1240.             f.close()
  1241.         except IOError, e:
  1242.             print 'There was an error while saving the state pickle (%s)' % e
  1243.             pass
  1244.         except:
  1245.             print "An unknown error occured during save state: " + str(sys.exc_info()[0])
  1246.             traceback.print_exc()
  1247.             pass
  1248.  
  1249.     def loadState(self):
  1250.  
  1251.         path = os.path.join(self.confDir, 'state', 'state.txt')
  1252.         try:
  1253.             f = open(path, 'rb')
  1254.             self.playlistId,\
  1255.             self.playlistName,\
  1256.             self.searchText,\
  1257.             self.rootDir,\
  1258.             self.location,\
  1259.             self.nowPlayingList = pickle.load(f)
  1260.             f.close()
  1261.             return True
  1262.         except:
  1263.             self.debug(str(sys.exc_info()[0]))
  1264.             return False
  1265.             pass       
  1266.  
  1267.     def getState(self):
  1268.         # Use this instead of __getstate__() for pickling
  1269.         return (self.playlistId,\
  1270.         self.playlistName,\
  1271.         self.searchText,\
  1272.         self.rootDir,\
  1273.         self.location,\
  1274.         self.nowPlayingList)
  1275.  
  1276.     def truncateText(self, text, n):
  1277.         if len(text) > n:
  1278.             return text[0:n-3] + '...'
  1279.         else:
  1280.             return text
  1281.  
  1282.     def isRadioOn(self):
  1283.         protocol = 'plugin://' + __scriptid__ + '/?playSong'
  1284.         songList = []
  1285.         try:
  1286.             url = self.xbmcPlaylist[0].getfilename()
  1287.         except:
  1288.             return False
  1289.         parts = url.split('=')
  1290.         try:
  1291.             if parts[0] == protocol:
  1292.                 parts = url.split('&')
  1293.                 print parts[2]
  1294.                 if parts[2] == 'options=radio':
  1295.                     return True
  1296.             else:
  1297.                 return False
  1298.         except:
  1299.             return False
  1300.  
  1301.     def replaceCharacters(self, text, items):
  1302.         newText = text
  1303.         for item in items:
  1304.             newText = newText.replace(item['searchFor'], item['replaceWith'])
  1305.         return newText
  1306.  
  1307.     def playlistHasFocus(self):
  1308.         self.setFocus(self.getControl(205))
  1309.  
  1310.     def optionsHasFocus(self):
  1311.         if self.navi.hasBack() == True:
  1312.             n = self.getCurrentListPosition()
  1313.             if n == 0:
  1314.                 #self.getControl(500).setVisible(False)
  1315.                 print 'Updating options, back = True'
  1316.                 self.options.update(n-1, back = True)
  1317.             else:
  1318.                 print 'Updating options, back = False'
  1319.                 obj = self.navi.getBranchObject()
  1320.                 self.options.update(n-1, back = False, obj = obj)
  1321.         self.setFocusId(500)
  1322.  
  1323.     def playerChanged(self, event, windowId = None):
  1324.         if event == 0: # Stopped
  1325.             pass
  1326.            
  1327.         elif event == 1: # Ended
  1328.             if __isXbox__ == True:
  1329.                 self.playNextSong()
  1330.                 if windowId != None:
  1331.                     if windowId == 12006: #Visualization
  1332.                         xbmcgui.Window(windowId).show()
  1333.            
  1334.         elif event == 2: # Started
  1335.             if __isXbox__ == True:
  1336.                 pass
  1337.             else:
  1338.                 if self.xbmcPlaylist.size() > 1:
  1339.                     # FIXME: Some code for updating the cover of the next playing
  1340.                     pass
  1341.             pass
  1342.            
  1343.         elif event == 3: # Playback paused
  1344.             if __isXbox__ == True:
  1345.                 pass
  1346.            
  1347.         elif event == 4: # Playback resumed
  1348.             if __isXbox__ == True:
  1349.                 pass
  1350.  
  1351.         elif event == 5: # Play next
  1352.             if __isXbox__ == True:
  1353.                 self.playNextSong()
  1354.                 if windowId != None:
  1355.                     if windowId == 12006: #Visualization
  1356.                         xbmcgui.Window(windowId).show()
  1357.             pass
  1358.                                                    
  1359.     def getInput(self, title, default="", hidden=False):
  1360.         keyboard = xbmc.Keyboard(default, title)
  1361.         keyboard.setHiddenInput(hidden)
  1362.         keyboard.doModal()
  1363.         if keyboard.isConfirmed():
  1364.             return keyboard.getText()
  1365.         else:
  1366.             return None
  1367.                
  1368.     def savePlaylist(self, playlistId = 0, name = '', about = '', songList = []):
  1369.         try:
  1370.             if self.gs.loggedInStatus() != 1:
  1371.                 result = self.login()
  1372.                 if result == 1:
  1373.                     pass
  1374.                 elif result == -1:
  1375.                     return 0
  1376.                 elif result == -2:
  1377.                     self.message(__language__(3028),__language__(3029))
  1378.                     return 0
  1379.                 else:
  1380.                     return 0
  1381.  
  1382.             if name == '':
  1383.                 pName = self.getInput(__language__(3009))
  1384.             else:
  1385.                 pName = name
  1386.             if pName == '' or pName == None or pName == 0:
  1387.                 self.message(__language__(3010), __language__(3011))
  1388.                 return 0
  1389.             b = busy()
  1390.             if playlistId == 0:
  1391.                 pId = self.gs.playlistCreate(pName, about)
  1392.                 if pId == 0:
  1393.                     b.close()
  1394.                     del b
  1395.                     self.message(__language__(3008)+ ' 1')
  1396.                     return 0           
  1397.             else:
  1398.                 pId = playlistId
  1399.            
  1400.             if songList != []:
  1401.                 songIds = songList
  1402.             else:  
  1403.                 n = len(self.playlist)
  1404.                 songIds = []
  1405.                 for i in range(n):
  1406.                     songIds.append(self.getSongIdFromList(self.playlist, i))
  1407.  
  1408.             if self.gs.playlistReplace(pId, songIds) == 0:
  1409.                 b.close()
  1410.                 del b
  1411.                 self.message(__language__(3008)+ ' 2')
  1412.                 return 0
  1413.             else:
  1414.                 if songList == []:
  1415.                     self.playlistId = pId
  1416.                     self.playlistName = pName
  1417.                     self.setStateLabel(__language__(3007) + ' (' + self.playlistName + ')')
  1418.                 b.close()
  1419.                 del b
  1420.                 return pId
  1421.  
  1422.         except:
  1423.             traceback.print_exc()
  1424.             b.close()
  1425.             del b
  1426.             self.message(__language__(3008)+ ' 3')
  1427.             return 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement