From d0ee2f275ade8df273f8e4e0db2a20ec59c0a92f Mon Sep 17 00:00:00 2001 From: lusum Date: Tue, 9 Feb 2021 00:23:08 +0100 Subject: [PATCH 01/40] add submode instead of object_id, better management of modes --- addon.xml | 2 +- resources/lib/ampache_monitor.py | 2 +- resources/lib/ampache_plugin.py | 556 ++++++++++++++++--------------- resources/settings.xml | 8 +- 4 files changed, 289 insertions(+), 279 deletions(-) diff --git a/addon.xml b/addon.xml index 595c078..d07a3d9 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + diff --git a/resources/lib/ampache_monitor.py b/resources/lib/ampache_monitor.py index eadf834..5c270e2 100644 --- a/resources/lib/ampache_monitor.py +++ b/resources/lib/ampache_monitor.py @@ -46,6 +46,6 @@ def onNotification(self, sender, method, data): except: xbmc.log("AmpacheMonitor::no playing file " , xbmc.LOGDEBUG) return - xbmc.executebuiltin('RunPlugin(plugin://plugin.audio.ampache/?mode=47)') + xbmc.executebuiltin('RunPlugin(plugin://plugin.audio.ampache/?mode=205)') diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index b359b6b..310157e 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -213,7 +213,8 @@ def addLinks(elem,object_type,useCacheArt,mode): continue try: artist_id = getNestedTypeId(node,"artist") - cm.append( ( ut.tString(30141), "Container.Update(%s?object_id=%s&mode=2)" % ( sys.argv[0],artist_id ) ) ) + cm.append( ( ut.tString(30141),"Container.Update(%s?object_id=%s&mode=1&submode=6)" % + ( sys.argv[0],artist_id ) ) ) except: pass @@ -248,7 +249,7 @@ def addLinks(elem,object_type,useCacheArt,mode): handle=int(sys.argv[1]) - u=sys.argv[0]+"?object_id="+str(object_id)+"&mode="+str(mode) + u=sys.argv[0]+"?object_id="+str(object_id)+"&mode="+str(mode)+"&submode=71" #xbmc.log("AmpachePlugin::addLinks: u - " + u, xbmc.LOGDEBUG ) isFolder=True tu= (u,liz,isFolder) @@ -278,7 +279,7 @@ def addSongLinks(elem): try: artist_id = getNestedTypeId(node,"artist") cm.append( ( ut.tString(30138), - "Container.Update(%s?object_id=%s&mode=15)" % ( + "Container.Update(%s?object_id=%s&mode=1&submode=6)" % ( sys.argv[0],artist_id ) ) ) except: pass @@ -286,21 +287,21 @@ def addSongLinks(elem): try: album_id = getNestedTypeId(node,"album") cm.append( ( ut.tString(30139), - "Container.Update(%s?object_id=%s&mode=16)" % ( + "Container.Update(%s?object_id=%s&mode=2&submode=6)" % ( sys.argv[0],album_id ) ) ) except: pass song_title = str(node.findtext("title")) cm.append( ( ut.tString(30140), - "Container.Update(%s?title=%s&mode=17)" % ( + "Container.Update(%s?title=%s&mode=3&submode=12)" % ( sys.argv[0],urllib.parse.quote_plus(song_title) ) ) ) if cm != []: liz.addContextMenuItems(cm) song_url = node.findtext("url") - track_parameters = { "mode": 45, "song_url" : song_url, "object_id" : song_id} + track_parameters = { "mode": 200, "song_url" : song_url, "object_id" : song_id} url = sys.argv[0] + '?' + urllib.parse.urlencode(track_parameters) tu= (url,liz) it.append(tu) @@ -345,7 +346,7 @@ def play_track(object_id,song_url): xbmcplugin.setResolvedUrl(handle=int(sys.argv[1]), succeeded=True,listitem=liz) #Main function to add xbmc plugin elements -def addDir(name,object_id,mode,offset=None): +def addDir(name,mode,submode,offset=None,object_id=None): infoLabels={ "Title": name } liz=xbmcgui.ListItem(name) @@ -354,10 +355,12 @@ def addDir(name,object_id,mode,offset=None): handle=int(sys.argv[1]) - u=sys.argv[0]+"?object_id="+str(object_id)+"&mode="+str(mode) + u=sys.argv[0]+"?mode="+str(mode)+"&submode="+str(submode) #offset, in case of very long lists if offset: u = u + "&offset="+str(offset) + if object_id: + u = u + "&object_id="+str(object_id) xbmc.log("AmpachePlugin::addDir url " + u, xbmc.LOGDEBUG) xbmcplugin.addDirectoryItem(handle=handle,url=u,listitem=liz,isFolder=True) @@ -375,7 +378,7 @@ def addItem( object_type, mode , elem, useCacheArt=True): addLinks(elem,object_type,useCacheArt,mode) return -def get_all(object_type,offset=None): +def get_all(object_type, mode ,offset=None): if offset == None: offset=0 try: @@ -391,9 +394,12 @@ def get_all(object_type,offset=None): else: get_items(object_type, limit=step, offset=offset, useCacheArt=False) if newLimit < limit: - return newLimit + pass else: - return None + newLimit = None + + if newLimit: + addDir(ut.tString(30194),mode,5,offset=newLimit) #this functions handles the majority of the requests to the server #so, we have a lot of optional params @@ -429,7 +435,7 @@ def get_items(object_type, object_id=None, add=None,\ if object_type == 'albums': if object_subtype == 'artist_albums': action = 'artist_albums' - addDir("All Songs",object_id,12) + addDir("All Songs",1,72, object_id=object_id) elif object_subtype == 'tag_albums': action = 'tag_albums' elif object_subtype == 'album': @@ -457,11 +463,11 @@ def get_items(object_type, object_id=None, add=None,\ #set the mode if object_type == 'artists': - mode = 2 + mode = 1 elif object_type == 'albums': - mode = 3 + mode = 2 elif object_type == 'playlists': - mode = 14 + mode = 4 elif object_type == 'tags': if object_subtype == 'tag_artists': mode = 19 @@ -547,14 +553,12 @@ def do_search(object_type,object_subtype=None,thisFilter=None): def get_stats(object_type, object_subtype=None, limit=5000 ): - ampConn = ampache_connect.AmpacheConnect() - xbmc.log("AmpachePlugin::get_stats ", xbmc.LOGDEBUG) mode = None if object_type == 'artists': - mode = 2 + mode = 1 elif object_type == 'albums': - mode = 3 + mode = 2 xbmcplugin.setContent(int(sys.argv[1]), object_type) @@ -565,8 +569,10 @@ def get_stats(object_type, object_subtype=None, limit=5000 ): else: amtype = ut.otype_to_type(object_type) thisFilter = object_subtype - + try: + ampConn = ampache_connect.AmpacheConnect() + ampConn.filter = thisFilter ampConn.limit = limit ampConn.type = amtype @@ -576,20 +582,20 @@ def get_stats(object_type, object_subtype=None, limit=5000 ): except: return -def get_recent(object_type,object_id,object_subtype=None): +def get_recent(object_type,submode,object_subtype=None): - if object_id == 9999998: + if submode == 31: update = ampache.getSetting("add") xbmc.log(update[:10],xbmc.LOGINFO) get_items(object_type=object_type,add=update[:10],object_subtype=object_subtype) - elif object_id == 9999997: + elif submode == 32: get_items(object_type=object_type,add=ut.get_time(-7),object_subtype=object_subtype) - elif object_id == 9999996: + elif submode == 33: get_items(object_type=object_type,add=ut.get_time(-30),object_subtype=object_subtype) - elif object_id == 9999995: + elif submode == 34: get_items(object_type=object_type,add=ut.get_time(-90),object_subtype=object_subtype) -def get_random(object_type): +def get_random(object_type, random_items): xbmc.log("AmpachePlugin::get_random: object_type " + object_type, xbmc.LOGDEBUG) mode = None #object type can be : albums, artists, songs, playlists @@ -598,17 +604,16 @@ def get_random(object_type): amtype = ut.otype_to_type(object_type) if object_type == 'albums': - mode = 3 - elif object_type == 'artists': mode = 2 + elif object_type == 'artists': + mode = 1 elif object_type == 'playlists': - mode = 14 + mode = 4 #song is the same mode xbmcplugin.setContent(int(sys.argv[1]), object_type) try: - random_items = (int(ampache.getSetting("random_items"))*3)+3 xbmc.log("AmpachePlugin::get_random: random_items " + str(random_items), xbmc.LOGDEBUG ) items = int(ampache.getSetting(object_type)) xbmc.log("AmpachePlugin::get_random: total items in the catalog " + str(items), xbmc.LOGDEBUG ) @@ -645,7 +650,7 @@ def get_random(object_type): except: pass -def checkCloseMusicPlaylist(addon_url, mode, object_id=None, title=None): +def checkCloseMusicPlaylist(addon_url, mode, submode, object_id=None, title=None): """ this function checks if musicplaylist window is active and switchs to the music window necessary when we have to display albums or songs @@ -656,11 +661,11 @@ def checkCloseMusicPlaylist(addon_url, mode, object_id=None, title=None): xbmc.executebuiltin('Dialog.Close(busydialog)') xbmc.executebuiltin("ActivateWindow(music)") if object_id: - xbmc.executebuiltin("Container.Update(%s?object_id=%s&mode=%s)" %\ - ( addon_url,object_id, mode ) ) + xbmc.executebuiltin("Container.Update(%s?object_id=%s&mode=%s&submode=%s)" %\ + ( addon_url,object_id, mode, submode ) ) elif title: - xbmc.executebuiltin("Container.Update(%s?title=%s&mode=%s)" %\ - ( addon_url,title, mode ) ) + xbmc.executebuiltin("Container.Update(%s?title=%s&mode=%s&submode=%s)" %\ + ( addon_url,title, mode, submode ) ) def main_params(plugin_url): @@ -672,6 +677,7 @@ def main_params(plugin_url): """ m_params={} m_params['mode'] = None + m_params['submode'] = None m_params['object_id'] = None m_params['title'] = None #used only in play tracks @@ -686,6 +692,11 @@ def main_params(plugin_url): xbmc.log("AmpachePlugin::mode " + str(m_params['mode']), xbmc.LOGDEBUG) except: pass + try: + m_params['submode']=int(params["submode"]) + xbmc.log("AmpachePlugin::submode " + str(m_params['submode']), xbmc.LOGDEBUG) + except: + pass try: m_params['object_id']=int(params["object_id"]) xbmc.log("AmpachePlugin::object_id " + str(m_params['object_id']), xbmc.LOGDEBUG) @@ -709,25 +720,25 @@ def main_params(plugin_url): return m_params -def manage_get_all(object_type, mode ,offset): - new_offset=get_all(object_type,offset) - if new_offset: - addDir(ut.tString(30194),None,mode,new_offset) - #add new line in case of new stat function implemented, checking the version #in menus -def manage_stats_menu(object_id, object_type, num_items): - if object_id == 9999993: +def manage_stats_menu(submode, object_type): + + num_items = (int(ampache.getSetting("random_items"))*3)+3 + + if submode == 40: + get_random(object_type, num_items) + elif submode == 41: get_stats(object_type=object_type,object_subtype="highest",limit=num_items) - elif object_id == 9999992: + elif submode == 42: get_stats(object_type=object_type,object_subtype="frequent",limit=num_items) - elif object_id == 9999991: + elif submode == 43: get_stats(object_type=object_type,object_subtype="flagged",limit=num_items) - elif object_id == 9999990: + elif submode == 44: get_stats(object_type=object_type,object_subtype="forgotten",limit=num_items) - elif object_id == 9999989: + elif submode == 45: get_stats(object_type=object_type,object_subtype="newest",limit=num_items) - elif object_id == 9999988: + elif submode == 46: get_stats(object_type=object_type,object_subtype="recent",limit=num_items) def Main(): @@ -739,9 +750,9 @@ def Main(): #until endDirectoryMode -> endDirectoy and checkConnection #from endDirectoryMode to endCheckConnection -> no endDirectory but checkConnection #else no end and no check - endDirectoryMode = 40 - endCheckConnection = 50 - modeMax = 100 + endDirectoryMode = 200 + endCheckConnection = 300 + modeMax = 1000 endDir = True addon_url = sys.argv[0] @@ -753,6 +764,7 @@ def Main(): m_params=main_params(plugin_url) #faster to change variable mode = m_params['mode'] + submode = m_params['submode'] object_id = m_params['object_id'] servers_manager.initializeServer() @@ -773,322 +785,320 @@ def Main(): #start menu if mode==None: #search - addDir(ut.tString(30101),None,4) + addDir(ut.tString(30101),53,None) #quick access - addDir(ut.tString(30102),None,25) + addDir(ut.tString(30102),52,None) #explore - addDir(ut.tString(30103),None,23) + addDir(ut.tString(30103),50,None) #library - addDir(ut.tString(30104),None,24) + addDir(ut.tString(30104),51,None) #switch server - addDir(ut.tString(30023),None,54) + addDir(ut.tString(30023),304,None) #settings - addDir(ut.tString(30105),None,50) + addDir(ut.tString(30105),300,None) - #artist mode ( called from search screen ( mode 4 ), recent ( mode 5 ) ) - #and others + #artist mode elif mode==1: #artist, album, songs, playlist follow the same structure - #search function - num_items = (int(ampache.getSetting("random_items"))*3)+3 #get all artists - if object_id == None: - manage_get_all("artists", mode ,m_params['offset']) + if submode == 5: + get_all("artists", mode ,m_params['offset']) #get_items("artists", limit=None, useCacheArt=False) - elif object_id == 9999999: + #get the artist from this album's artist_id + elif submode == 6: + checkCloseMusicPlaylist(addon_url, mode, submode, object_id=object_id ) + get_items(object_type="artists",object_id=object_id,object_subtype="artist") + #search function + #10-30 search + elif submode == 10: endDir = do_search("artists") #recent function - elif object_id > 9999994 and object_id < 9999999: - get_recent( "artists", object_id ) - elif object_id == 9999994: - #removed cause nasty recursive call using some commands in web interface - #addDir("Refresh..",9999994,2,os.path.join(imagepath,'refresh_icon.png')) - #get random is separated from stats to mantain compatibility with - #older ampache api - get_random('artists') - #object_id between 99..93 e 99..88 ( highest .. recent ) - elif object_id >= 9999988 and object_id <=9999993: - manage_stats_menu(object_id, "artists", num_items) + #30-40 recent + elif submode > 30 and submode < 35: + get_recent( "artists", submode ) + #submode between 40-46( random.. recent ) + #40-70 stats + elif submode >= 40 and submode <= 46: + manage_stats_menu(submode, "artists") + #get all albums from an artist_id + elif submode == 71: + get_items(object_type="albums",object_id=object_id,object_subtype="artist_albums") + #get all songs from an artist_id + elif submode == 72: + get_items(object_type="songs",object_id=object_id,object_subtype="artist_songs" ) - #albums mode ( called from search screen ( mode 4 ) , recent ( mode 5 ) + #albums mode #and others elif mode==2: - num_items = (int(ampache.getSetting("random_items"))*3)+3 #get all albums - if object_id == None: - manage_get_all("albums", mode ,m_params['offset']) + if submode == 5: + get_all("albums", mode ,m_params['offset']) #get_items("albums", limit=None, useCacheArt=False) - elif object_id == 9999999: + #get the album from the song's album_id + elif submode == 6: + checkCloseMusicPlaylist(addon_url, mode, submode, object_id=object_id ) + get_items(object_type="albums",object_id=object_id,object_subtype="album") + elif submode == 10: endDir = do_search("albums") - elif object_id > 9999994 and object_id < 9999999: - get_recent( "albums", object_id ) - elif object_id == 9999994: - #removed cause nasty recursive call using some commands in web interface - #addDir("Refresh..",9999990,2,os.path.join(imagepath, 'refresh_icon.png')) - get_random('albums') - elif object_id >= 9999988 and object_id <=9999993: - manage_stats_menu(object_id, "albums", num_items) - elif object_id: - get_items(object_type="albums",object_id=object_id,object_subtype="artist_albums") + elif submode > 30 and submode < 35: + get_recent( "albums", submode ) + elif submode >= 40 and submode <= 46: + manage_stats_menu(submode, "albums") + #get all songs from an album_id + elif submode == 71: + get_items(object_type="songs",object_id=object_id,object_subtype="album_songs") - #song mode ( called from search screen ( mode 4 ) and recent ( mode 5 ) ) + #song mode #and others elif mode == 3: - num_items = (int(ampache.getSetting("random_items"))*3)+3 - if object_id == None: - #handle wrong object_id - pass - elif object_id > 9999994 and object_id < 9999999: - get_recent( "songs", object_id ) - elif object_id == 9999999: + #10-30 search + if submode == 10: endDir = do_search("songs") - elif object_id == 9999994: - #removed cause nasty recursive call using some commands in web interface - #addDir("Refresh..",9999994,2,os.path.join(imagepath, 'refresh_icon.png')) - get_random('songs') - elif object_id >= 9999988 and object_id <=9999993: - manage_stats_menu(object_id, "songs", num_items) - else: - get_items(object_type="songs",object_id=object_id,object_subtype="album_songs") - - #search mode + # submode 11 : search all + elif submode == 11: + endDir = do_search("songs","search_songs") + #get all song with this title + elif submode == 12: + checkCloseMusicPlaylist(addon_url, mode,submode, object_id=object_id ) + endDir = do_search("songs",thisFilter=m_params['title']) + #30-40 recent + elif submode > 30 and submode < 35: + get_recent( "songs", submode ) + #40-70 stats + elif submode >= 40 and submode <= 46: + manage_stats_menu(submode, "songs") + + #playlist mode elif mode==4: - if not (ut.strBool_to_bool(ampache.getSetting("old-search-gui"))): - endDir = searchGui() - else: - #old search gui - #search artist - addDir(ut.tString(30120),9999999,1) - #search album - addDir(ut.tString(30121),9999999,2) - #search song - addDir(ut.tString(30122),9999999,3) - #search playlist - addDir(ut.tString(30123),9999999,13) - #search all - addDir(ut.tString(30124),9999999,11) - #search tag - addDir(ut.tString(30125),9999999,18) - - - # recently added screen - elif mode==5: - addDir(ut.tString(30126),9999998,6) - addDir(ut.tString(30127),9999997,6) - addDir(ut.tString(30128),9999996,6) - addDir(ut.tString(30129),9999995,6) - - #screen with recent time possibilities ( subscreen of recent artists, - #recent albums, recent songs ) ( called from mode 5 ) - elif mode==6: - #not clean, but i don't want to change too much the old code - if object_id > 9999995: - #object_id for playlists is 9999995 so 9999999-object_id is 4 that is search mode - #i have to use another method, so i use the hardcoded mode number (13) - mode_new = 9999999-object_id - elif object_id == 9999995: - mode_new = 13 - - addDir(ut.tString(30130),9999998,mode_new) - addDir(ut.tString(30131),9999997,mode_new) - addDir(ut.tString(30132),9999996,mode_new) - addDir(ut.tString(30133),9999995,mode_new) - - #general random mode screen - elif mode==7: - addDir(ut.tString(30134),9999994,1) - addDir(ut.tString(30135),9999994,2) - addDir(ut.tString(30136),9999994,3) - addDir(ut.tString(30137),9999994,13) - - # mode 11 : search all - elif mode==11: - endDir = do_search("songs","search_songs") - - # mode 12 : artist_songs - elif mode==12: - get_items(object_type="songs",object_id=object_id,object_subtype="artist_songs" ) - - #playlist full list - elif mode==13: - if object_id == None: - manage_get_all("playlists", mode ,m_params['offset']) + if submode == 5: + get_all("playlists", mode ,m_params['offset']) #get_items(object_type="playlists") - elif object_id == 9999999: + elif submode == 10: endDir = do_search("playlists") - elif object_id > 9999994 and object_id < 9999999: - get_recent( "playlists", object_id ) - elif object_id == 9999994: - #removed cause nasty recursive call using some commands in web interface - #addDir("Refresh..",9999994,2,os.path.join(imagepath, 'refresh_icon.png')) - get_random('playlists') - elif object_id: - get_items(object_type="playlists",object_id=object_id) - - #playlist song mode - elif mode==14: - get_items(object_type="songs",object_id=object_id,object_subtype="playlist_songs") - - elif mode==15: - checkCloseMusicPlaylist(addon_url, mode, object_id=object_id ) - get_items(object_type="artists",object_id=object_id,object_subtype="artist") - - elif mode==16: - checkCloseMusicPlaylist(addon_url, mode, object_id=object_id ) - get_items(object_type="albums",object_id=object_id,object_subtype="album") - - elif mode==17: - checkCloseMusicPlaylist(addon_url, mode, object_id=object_id ) - endDir = do_search("songs",thisFilter=m_params['title']) - - #tags - elif mode==18: - #object_id always 9999999 - #search tag_artist - addDir(ut.tString(30142),object_id,19) - #search tag_album - addDir(ut.tString(30143),object_id,20) - #search tag_song - addDir(ut.tString(30144),object_id,21) - + elif submode > 30 and submode < 35: + get_recent( "playlists", submode ) + elif submode == 40: + manage_stats_menu(submode, "playlists") + #elif object_id: + # get_items(object_type="playlists",object_id=object_id) + #get all songs from a playlist_id + elif submode == 71: + get_items(object_type="songs",object_id=object_id,object_subtype="playlist_songs") + + #mode 5 podcast + + #19-21 tags/genres mode elif mode==19: - if object_id == 9999999: + #get_all tags/genres + if submode == 5: + get_items(object_type = "tags", object_subtype="tag_artists") + #search tag/genre + elif submode == 10: endDir = do_search("tags","tag_artists") - elif object_id: + #get all songs from a tag_id/genre_id + elif submode == 71: get_items(object_type="artists", object_subtype="tag_artists",object_id=object_id) - else: - get_items(object_type = "tags", object_subtype="tag_artists") elif mode==20: - if object_id == 9999999: + if submode == 5: + get_items(object_type = "tags", object_subtype="tag_albums") + elif submode == 10: endDir = do_search("tags","tag_albums") - elif object_id: + elif submode == 71: get_items(object_type="albums", object_subtype="tag_albums",object_id=object_id) - else: - get_items(object_type = "tags", object_subtype="tag_albums") elif mode==21: - if object_id == 9999999: + if submode == 5: + get_items(object_type = "tags", object_subtype="tag_songs") + elif submode == 10: endDir = do_search("tags","tag_songs") - elif object_id: + elif submode == 71: get_items(object_type="songs", object_subtype="tag_songs",object_id=object_id) - else: - get_items(object_type = "tags", object_subtype="tag_songs") + #main meus 50-100 #explore - elif mode==23: + elif mode==50: #recently added - addDir(ut.tString(30145),None,5) + addDir(ut.tString(30145),107,None) #random - addDir(ut.tString(30146),None,7) + addDir(ut.tString(30146),100,None) if(int(ampache.getSetting("api-version"))) >= 400001: #highest - addDir(ut.tString(30148),9999993,30) + addDir(ut.tString(30148),101,None) #frequent - addDir(ut.tString(30164),9999992,31) + addDir(ut.tString(30164),102,None) #flagged - addDir(ut.tString(30165),9999991,32) + addDir(ut.tString(30165),103,None) #forgotten - addDir(ut.tString(30166),9999990,33) + addDir(ut.tString(30166),104,None) #newest - addDir(ut.tString(30167),9999989,34) + addDir(ut.tString(30167),105,None) #recent - addDir(ut.tString(30193),9999988,35) + addDir(ut.tString(30193),106,None) #Library - elif mode==24: - addDir(ut.tString(30115) +" (" + ampache.getSetting("artists")+ ")",None,1) - addDir(ut.tString(30116) + " (" + ampache.getSetting("albums") + ")",None,2) - addDir(ut.tString(30118) + " (" + ampache.getSetting("playlists")+ ")",None,13) + elif mode==51: + addDir(ut.tString(30115) +" (" + ampache.getSetting("artists")+ ")",1,5) + addDir(ut.tString(30116) + " (" + ampache.getSetting("albums") + ")",2,5) + addDir(ut.tString(30118) + " (" + ampache.getSetting("playlists")+ ")",4,5) apiVersion = int(ampache.getSetting("api-version")) if apiVersion >= 380001: - addDir(ut.tString(30119),None,18) + #get all tags ( submode 5 ) + addDir(ut.tString(30119),54,5) #quick access - elif mode==25: + elif mode==52: #random album - addDir(ut.tString(30135),9999994,2) + addDir(ut.tString(30135),2,40) if(int(ampache.getSetting("api-version"))) >= 400001: #newest albums - addDir(ut.tString(30162),9999989,2) + addDir(ut.tString(30162),2,45) #frequent albums - addDir(ut.tString(30153),9999992,2) + addDir(ut.tString(30153),2,42) #recently played albums - addDir(ut.tString(30191),9999988,2) + addDir(ut.tString(30191),2,46) else: #use recently added albums for old api versions - addDir(ut.tString(30127),9999997,6) + addDir(ut.tString(30127),55,32) #server playlist ( AKA random songs ) - addDir(ut.tString(30147),9999994,3) + addDir(ut.tString(30147),3,40) + + #search mode + elif mode==53: + if not (ut.strBool_to_bool(ampache.getSetting("old-search-gui"))): + endDir = searchGui() + else: + #old search gui + #search artist + addDir(ut.tString(30120),1,10) + #search album + addDir(ut.tString(30121),2,10) + #search song + addDir(ut.tString(30122),3,10) + #search playlist + addDir(ut.tString(30123),4,10) + #search all + addDir(ut.tString(30124),3,11) + #search tag + addDir(ut.tString(30125),54,10) + + + #search tags + elif mode==54: + #search tag_artist + addDir(ut.tString(30142),19,submode) + #search tag_album + addDir(ut.tString(30143),20,submode) + #search tag_song + addDir(ut.tString(30144),21,submode) + + #screen with recent time possibilities ( subscreen of recent artists, + #recent albums, recent songs ) + elif mode==55: + mode_new = submode - 30 + + #last update + addDir(ut.tString(30130),mode_new,31) + #1 week + addDir(ut.tString(30131),mode_new,32) + addDir(ut.tString(30132),mode_new,33) + addDir(ut.tString(30133),mode_new,34) + + + #stats 100-150 + #random + elif mode==100: + #artists + addDir(ut.tString(30134),1,40) + #albums + addDir(ut.tString(30135),2,40) + #songs + addDir(ut.tString(30136),3,40) + #playlists + addDir(ut.tString(30137),4,40) #highest - elif mode==30: - #artist - addDir(ut.tString(30149),9999993,1) - #album - addDir(ut.tString(30150),9999993,2) - #song - addDir(ut.tString(30151),9999993,3) + elif mode==101: + #artists + addDir(ut.tString(30149),1,41) + #albums + addDir(ut.tString(30150),2,41) + #songs + addDir(ut.tString(30151),3,41) #frequent - elif mode==31: - addDir(ut.tString(30152),9999992,1) - addDir(ut.tString(30153),9999992,2) - addDir(ut.tString(30154),9999992,3) + elif mode==102: + addDir(ut.tString(30152),1,42) + addDir(ut.tString(30153),2,42) + addDir(ut.tString(30154),3,42) #flagged - elif mode==32: - addDir(ut.tString(30155),9999991,1) - addDir(ut.tString(30156),9999991,2) - addDir(ut.tString(30157),9999991,3) + elif mode==103: + addDir(ut.tString(30155),1,43) + addDir(ut.tString(30156),2,43) + addDir(ut.tString(30157),3,43) #forgotten - elif mode==33: - addDir(ut.tString(30158),9999990,1) - addDir(ut.tString(30159),9999990,2) - addDir(ut.tString(30160),9999990,3) + elif mode==104: + addDir(ut.tString(30158),1,44) + addDir(ut.tString(30159),2,44) + addDir(ut.tString(30160),3,44) #newest - elif mode==34: - addDir(ut.tString(30161),9999989,1) - addDir(ut.tString(30162),9999989,2) - addDir(ut.tString(30163),9999989,3) + elif mode==105: + addDir(ut.tString(30161),1,45) + addDir(ut.tString(30162),2,45) + addDir(ut.tString(30163),3,45) - #recent - elif mode==35: - addDir(ut.tString(30190),9999988,1) - addDir(ut.tString(30191),9999988,2) - addDir(ut.tString(30192),9999988,3) - + #recently added + elif mode==106: + addDir(ut.tString(30190),1,46) + addDir(ut.tString(30191),2,46) + addDir(ut.tString(30192),3,46) + + # recent + elif mode==107: + #recently added artist + addDir(ut.tString(30126),55,31) + #recently added album + addDir(ut.tString(30127),55,32) + #recently added song + addDir(ut.tString(30128),55,33) + #recently added playlist + addDir(ut.tString(30129),55,34) + + + #others mode 200-250 #play track mode ( mode set in add_links function ) - #mode 45 to avoid endDirectory - elif mode==45: + #mode 200 to avoid endDirectory + elif mode==200: #workaround busydialog bug xbmc.executebuiltin('Dialog.Close(busydialog)') play_track(object_id, m_params['song_url']) #change rating - elif mode==47: + elif mode==205: setRating() + #settings mode 300-350 #settings - elif mode==50: + elif mode==300: ampache.openSettings() #the four modes below are used to manage servers - elif mode==51: + elif mode==301: if servers_manager.addServer(): servers_manager.switchServer() - elif mode==52: + elif mode==302: if servers_manager.deleteServer(): servers_manager.switchServer() - elif mode==53: + elif mode==303: servers_manager.modifyServer() - elif mode==54: + elif mode==304: servers_manager.switchServer() #no end directory item ( problem with failed searches ) diff --git a/resources/settings.xml b/resources/settings.xml index 6d892a6..03657d2 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -7,9 +7,9 @@ - - - - + + + + From 5d4087dd88be3dcbfe96d696cff7ffcc0447f6e1 Mon Sep 17 00:00:00 2001 From: lusum Date: Tue, 9 Feb 2021 00:34:27 +0100 Subject: [PATCH 02/40] simpler handling of connection error --- resources/lib/ampache_connect.py | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/resources/lib/ampache_connect.py b/resources/lib/ampache_connect.py index 1d82b6f..6625079 100644 --- a/resources/lib/ampache_connect.py +++ b/resources/lib/ampache_connect.py @@ -65,25 +65,19 @@ def getCodeMessError(self,tree): #ampache api 4 and below try: errormess = tree.findtext('error') - code = errornode.attrib["code"] - xbmc.log("AmpachePlugin::getCodeMessError: Client error code " + \ - str(code) + " message " + str(errormess) , xbmc.LOGDEBUG) - return code, errormess + return errormess except: #do nothing pass #ampache api 5 and above try: errormess = errornode.findtext("errorMessage") - code = errornode.attrib["errorCode"] - xbmc.log("AmpachePlugin::getCodeMessError: Client error code " + \ - str(code) + " message " + str(errormess) , xbmc.LOGDEBUG) - return code, errormess + return errormess except: #do nothing pass - return code, errormess + return errormess def getHashedPassword(self,timeStamp): enablePass = self._connectionData["enable_password"] @@ -173,14 +167,10 @@ def AMPACHECONNECT(self,showok=False): xbmc.log("AmpachePlugin::AMPACHECONNECT: unable to print contents " + \ repr(e) , xbmc.LOGDEBUG) tree=ET.XML(contents) - code, errormess = self.getCodeMessError(tree) + errormess = self.getCodeMessError(tree) if errormess: - if "time" in errormess and code == "401": - #permission error, check password or api_key - xbmcgui.Dialog().notification(ut.tString(30198),ut.tString(30204)) - else: - #connection error - xbmcgui.Dialog().notification(ut.tString(30198),ut.tString(30202)) + #connection error + xbmcgui.Dialog().notification(ut.tString(30198),ut.tString(30202)) raise self.ConnectionError xbmc.log("AmpachePlugin::AMPACHECONNECT ConnectionOk",xbmc.LOGDEBUG) if showok: @@ -219,9 +209,8 @@ def ampache_http_request(self,action): xbmc.log("AmpachePlugin::ampache_http_request: unable print contents " + \ repr(e) , xbmc.LOGDEBUG) tree=ET.XML(contents) - code, errormess = self.getCodeMessError(tree) + errormess = self.getCodeMessError(tree) if errormess: - xbmcgui.Dialog().notification(ut.tString(30198),ut.tString(30202)) raise self.ConnectionError return tree From 72bd06fc92be39fc2a022b23f8bf78705b6cb424 Mon Sep 17 00:00:00 2001 From: lusum Date: Tue, 9 Feb 2021 13:43:39 +0100 Subject: [PATCH 03/40] new README --- README | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/README b/README index 77a4d5c..642dabd 100644 --- a/README +++ b/README @@ -1,31 +1,29 @@ ampache-xbmc-plugin - This is a plugin for XBMC/KODI providing basic connectivity to the Streaming Software Ampache. +This is a plugin for XBMC/KODI providing basic connectivity to the Streaming Software Ampache. +The plugin is included in Kodi Official Repository - If you want to use it, zip it up and add it to your XBMC/KODI via System->AddOns->Install from ZIP. - - In the new version of KODI you have to do AddOns->Addon Icon ( top/left in Kodi default Skin )->Install from ZIP. +If you want to use the cutting edge version, download the zip file and add it to your XBMC/KODI via System->AddOns->Install from ZIP. +In the new version of KODI you have to do AddOns->Addon Icon ( top/left in Kodi default Skin )->Install from ZIP. - This plugin support the ampache API from 350001 to the last one. - - Tested with kodi 18,6, 18.8, 19 +This plugin supports the ampache API from 350001 to the last one. - Tested with web controls and kore app +Tested with kodi 18,6, 18.9, 19 - It is tested with the lastest ampache server and nextcloud music. +Tested with web controls and kore app ( kore app offers only a partial plugin support ) + +It is tested with the latest stable ampache server and nextcloud music. - Troubleshooting: +Troubleshooting: - Nextcloud music don't use api-key, but username/password, if you have problems to connect unckeck api_key box - - Web controls works better with the old search interface, it is possibile to enable in the settings - - The crashes in kodi are due to bugs in kodi 18.5-19 ( double busy dialog bug ) and in kore app. +Nextcloud music don't use api-key, but username/password, if you have problems to connect unckeck api_key box - To avoid random crashes in kodi don't do any operation in the last five seconds of a song, - due to a kodi bug, playing next song generates a busy dialog ( impossible to avoid ) - and operating on kodi generates another busy dialog. +Web controls work better with the old search interface, it is possibile to enable it in the settings - The combination of two busy dialogs working crashes kodi (https://github.com/xbmc/xbmc/issues/16756) +The crashes in kodi are due to bugs in kodi 18.5-19 ( double busy dialog bug ) and in kore app. +To avoid random crashes in kodi don't do any operation in the last five seconds of a song, +due to a kodi bug, playing next song generates a busy dialog ( impossible to avoid ) +and operating on kodi generates another busy dialog. +The combination of two busy dialogs working crashes kodi (https://github.com/xbmc/xbmc/issues/16756) From c606a75666964720cef6d56aee3abba9b682b027 Mon Sep 17 00:00:00 2001 From: lusum Date: Tue, 9 Feb 2021 14:22:48 +0100 Subject: [PATCH 04/40] object_id is now a string, smart playlist support, bug fixed --- resources/lib/ampache_plugin.py | 57 ++++++++++++++------------------- resources/lib/art.py | 20 ++++++------ resources/lib/utils.py | 8 ++--- 3 files changed, 38 insertions(+), 47 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 310157e..85faaa6 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -126,7 +126,7 @@ def get_infolabels(object_type , node): def getNestedTypeId(node,elem_type): obj_elem = node.find(elem_type) - obj_id = int(obj_elem.attrib["id"]) + obj_id = obj_elem.attrib["id"] return obj_id #this function is used to speed up the loading of the images using differents @@ -145,7 +145,7 @@ def precacheArt(elem,object_type): object_id = None else: try: - object_id = int(node.attrib["id"]) + object_id = node.attrib["id"] except: object_id = None if object_id == None: @@ -168,7 +168,7 @@ def check_get_art_url(node): #it handles albumArt and song info def fillListItemWithSongInfo(liz,node): - object_id = int(node.attrib["id"]) + object_id = node.attrib["id"] image_url = check_get_art_url(node) try: album_id = getNestedTypeId(node,"album") @@ -191,10 +191,8 @@ def addLinks(elem,object_type,useCacheArt,mode): for node in elem.iter(elem_type): cm = [] - try: - object_id = int(node.attrib["id"]) - except: - object_id == None + object_id = node.attrib["id"] + if object_id is None or object_id == "": continue #xbmc.log("AmpachePlugin::addLinks: object_id - " + str(object_id) , xbmc.LOGDEBUG ) #xbmc.log("AmpachePlugin::addLinks: node " + ET.tostring(node) , xbmc.LOGDEBUG ) @@ -211,12 +209,10 @@ def addLinks(elem,object_type,useCacheArt,mode): allid.add(object_id) else: continue - try: - artist_id = getNestedTypeId(node,"artist") + artist_id = getNestedTypeId(node,"artist") + if artist_id is not None and artist_id <> "": cm.append( ( ut.tString(30141),"Container.Update(%s?object_id=%s&mode=1&submode=6)" % ( sys.argv[0],artist_id ) ) ) - except: - pass name = get_album_artist_name(node) if useCacheArt: @@ -249,7 +245,7 @@ def addLinks(elem,object_type,useCacheArt,mode): handle=int(sys.argv[1]) - u=sys.argv[0]+"?object_id="+str(object_id)+"&mode="+str(mode)+"&submode=71" + u=sys.argv[0]+"?object_id="+object_id+"&mode="+str(mode)+"&submode=71" #xbmc.log("AmpachePlugin::addLinks: u - " + u, xbmc.LOGDEBUG ) isFolder=True tu= (u,liz,isFolder) @@ -266,31 +262,26 @@ def addSongLinks(elem): ok=True it=[] for node in elem.iter("song"): - try: - song_id = int(node.attrib["id"]) - except: - song_id = None + song_id = node.attrib["id"] + if song_id is None or song_id == "": continue liz=xbmcgui.ListItem() fillListItemWithSongInfo(liz,node) liz.setProperty("IsPlayable", "true") cm = [] - try: - artist_id = getNestedTypeId(node,"artist") + + artist_id = getNestedTypeId(node,"artist") + if artist_id is not None and artist_id <> "": cm.append( ( ut.tString(30138), "Container.Update(%s?object_id=%s&mode=1&submode=6)" % ( sys.argv[0],artist_id ) ) ) - except: - pass - try: - album_id = getNestedTypeId(node,"album") + album_id = getNestedTypeId(node,"album") + if album_id is not None and album_id <> "": cm.append( ( ut.tString(30139), "Container.Update(%s?object_id=%s&mode=2&submode=6)" % ( sys.argv[0],album_id ) ) ) - except: - pass song_title = str(node.findtext("title")) cm.append( ( ut.tString(30140), @@ -321,8 +312,8 @@ def play_track(object_id,song_url): try: plugin_url = xbmc.getInfoLabel('ListItem.FileNameAndPath') params=ut.get_params(plugin_url) - old_object_id=int(params["object_id"]) - xbmc.log("AmpachePlugin::play_track old_object_id " + str(old_object_id), xbmc.LOGDEBUG) + old_object_id=params["object_id"] + xbmc.log("AmpachePlugin::play_track old_object_id " + old_object_id, xbmc.LOGDEBUG) except: pass @@ -360,7 +351,7 @@ def addDir(name,mode,submode,offset=None,object_id=None): if offset: u = u + "&offset="+str(offset) if object_id: - u = u + "&object_id="+str(object_id) + u = u + "&object_id="+object_id xbmc.log("AmpachePlugin::addDir url " + u, xbmc.LOGDEBUG) xbmcplugin.addDirectoryItem(handle=handle,url=u,listitem=liz,isFolder=True) @@ -420,7 +411,7 @@ def get_items(object_type, object_id=None, add=None,\ #object_id could be None in some requests, like recently added and get_all #items if object_id: - xbmc.log("AmpachePlugin::get_items: object_id " + str(object_id), xbmc.LOGDEBUG) + xbmc.log("AmpachePlugin::get_items: object_id " + object_id, xbmc.LOGDEBUG) if limit == None: limit = int(ampache.getSetting(object_type)) @@ -512,7 +503,7 @@ def setRating(): return object_id = ut.get_objectId_from_fileURL( file_url ) - if object_id == None: + if object_id is None or object_id == "": return rating = xbmc.getInfoLabel('MusicPlayer.UserRating') if rating == "": @@ -526,7 +517,7 @@ def setRating(): ampConn = ampache_connect.AmpacheConnect() action = "rate" - ampConn.id = str(object_id) + ampConn.id = object_id ampConn.type = "song" ampConn.rating = str(amp_rating) @@ -698,8 +689,8 @@ def main_params(plugin_url): except: pass try: - m_params['object_id']=int(params["object_id"]) - xbmc.log("AmpachePlugin::object_id " + str(m_params['object_id']), xbmc.LOGDEBUG) + m_params['object_id']=params["object_id"] + xbmc.log("AmpachePlugin::object_id " + m_params['object_id'], xbmc.LOGDEBUG) except: pass try: @@ -860,7 +851,7 @@ def Main(): endDir = do_search("songs","search_songs") #get all song with this title elif submode == 12: - checkCloseMusicPlaylist(addon_url, mode,submode, object_id=object_id ) + checkCloseMusicPlaylist(addon_url, mode,submode,title=m_params['title'] ) endDir = do_search("songs",thisFilter=m_params['title']) #30-40 recent elif submode > 30 and submode < 35: diff --git a/resources/lib/art.py b/resources/lib/art.py index f410541..5ee6039 100644 --- a/resources/lib/art.py +++ b/resources/lib/art.py @@ -22,21 +22,21 @@ def cacheArt(imageID,elem_type,url=None): cacheDirType = os.path.join( cacheDir , elem_type ) #security check - if imageID == None: + if imageID is None or imageID == "": raise NameError possible_ext = ["jpg", "png" , "bmp", "gif", "tiff"] for ext in possible_ext: - imageName = str(imageID) + "." + ext + imageName = imageID + "." + ext pathImage = os.path.join( cacheDirType , imageName ) if os.path.exists( pathImage ): - xbmc.log("AmpachePlugin::CacheArt: cached, id " + str(imageID) + " extension " + ext ,xbmc.LOGDEBUG) + xbmc.log("AmpachePlugin::CacheArt: cached, id " + imageID + " extension " + ext ,xbmc.LOGDEBUG) return pathImage #no return, not found ampacheConnect = ampache_connect.AmpacheConnect() action = 'get_art' - ampacheConnect.id = str(imageID) + ampacheConnect.id = imageID ampacheConnect.type = elem_type if url: @@ -44,7 +44,7 @@ def cacheArt(imageID,elem_type,url=None): headers,contents = ampacheConnect.handle_request(url) else: headers,contents = ampacheConnect.ampache_binary_request(action) - #xbmc.log("AmpachePlugin::CacheArt: File needs fetching, id " + str(imageID),xbmc.LOGDEBUG) + #xbmc.log("AmpachePlugin::CacheArt: File needs fetching, id " + imageID,xbmc.LOGDEBUG) extension = headers['content-type'] if extension: mimetype, options = cgi.parse_header(extension) @@ -61,20 +61,20 @@ def cacheArt(imageID,elem_type,url=None): raise NameError if maintype == 'image': if subtype == "jpeg": - fname = str(imageID) + ".jpg" + fname = imageID + ".jpg" else: - fname = str(imageID) + '.' + subtype + fname = imageID + '.' + subtype pathImage = os.path.join( cacheDirType , fname ) with open( pathImage, 'wb') as f: f.write(contents) f.close() - #xbmc.log("AmpachePlugin::CacheArt: Cached " + str(fname), xbmc.LOGDEBUG ) + #xbmc.log("AmpachePlugin::CacheArt: Cached " + fname, xbmc.LOGDEBUG ) return pathImage else: - xbmc.log("AmpachePlugin::CacheArt: It didnt work, id " + str(imageID) , xbmc.LOGDEBUG ) + xbmc.log("AmpachePlugin::CacheArt: It didnt work, id " + imageID , xbmc.LOGDEBUG ) raise NameError else: - xbmc.log("AmpachePlugin::CacheArt: No file found, id " + str(imageID) , xbmc.LOGDEBUG ) + xbmc.log("AmpachePlugin::CacheArt: No file found, id " + imageID , xbmc.LOGDEBUG ) raise NameError def get_artLabels(albumArt): diff --git a/resources/lib/utils.py b/resources/lib/utils.py index 9349811..0d7f1ed 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -95,13 +95,13 @@ def get_objectId_from_fileURL( file_url ): #i use two kind of object_id, i don't know, but sometime i have different #url, btw, no problem, i handle both and i solve the problem in this way try: - object_id=int(params["object_id"]) - xbmc.log("AmpachePlugin::object_id " + str(object_id), xbmc.LOGDEBUG) + object_id=params["object_id"] + xbmc.log("AmpachePlugin::object_id " + object_id, xbmc.LOGDEBUG) except: pass try: - object_id=int(params["oid"]) - xbmc.log("AmpachePlugin::object_id " + str(object_id), xbmc.LOGDEBUG) + object_id=params["oid"] + xbmc.log("AmpachePlugin::object_id " + object_id, xbmc.LOGDEBUG) except: pass return object_id From 04d9ab879f9016b9f9d4fd8c77d8dab33a7d5525 Mon Sep 17 00:00:00 2001 From: lusum Date: Tue, 9 Feb 2021 14:27:08 +0100 Subject: [PATCH 05/40] better function name --- resources/lib/ampache_plugin.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 85faaa6..62040fe 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -641,10 +641,11 @@ def get_random(object_type, random_items): except: pass -def checkCloseMusicPlaylist(addon_url, mode, submode, object_id=None, title=None): +def switchFromMusicPlaylist(addon_url, mode, submode, object_id=None, title=None): """ this function checks if musicplaylist window is active and switchs to the music window - necessary when we have to display albums or songs + necessary when we have to call a function like "get album from this + artist" """ if xbmc.getCondVisibility("Window.IsActive(musicplaylist)"): #close busydialog to activate music window @@ -797,7 +798,7 @@ def Main(): #get_items("artists", limit=None, useCacheArt=False) #get the artist from this album's artist_id elif submode == 6: - checkCloseMusicPlaylist(addon_url, mode, submode, object_id=object_id ) + switchFromMusicPlaylist(addon_url, mode, submode, object_id=object_id ) get_items(object_type="artists",object_id=object_id,object_subtype="artist") #search function #10-30 search @@ -828,7 +829,7 @@ def Main(): #get_items("albums", limit=None, useCacheArt=False) #get the album from the song's album_id elif submode == 6: - checkCloseMusicPlaylist(addon_url, mode, submode, object_id=object_id ) + switchFromMusicPlaylist(addon_url, mode, submode, object_id=object_id ) get_items(object_type="albums",object_id=object_id,object_subtype="album") elif submode == 10: endDir = do_search("albums") @@ -851,7 +852,7 @@ def Main(): endDir = do_search("songs","search_songs") #get all song with this title elif submode == 12: - checkCloseMusicPlaylist(addon_url, mode,submode,title=m_params['title'] ) + switchFromMusicPlaylist(addon_url, mode,submode,title=m_params['title'] ) endDir = do_search("songs",thisFilter=m_params['title']) #30-40 recent elif submode > 30 and submode < 35: From a26a6813f0378ac0e617763e5ca9bf3ec5dd9a14 Mon Sep 17 00:00:00 2001 From: lusum Date: Tue, 9 Feb 2021 23:30:17 +0100 Subject: [PATCH 06/40] remove useless varialbe --- resources/lib/ampache_connect.py | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/lib/ampache_connect.py b/resources/lib/ampache_connect.py index 6625079..8d8d2da 100644 --- a/resources/lib/ampache_connect.py +++ b/resources/lib/ampache_connect.py @@ -58,7 +58,6 @@ def fillConnectionSettings(self,tree,nTime): self._ampache.setSetting("token-exp", str(nTime+24000)) def getCodeMessError(self,tree): - code = None errormess = None errornode = tree.find("error") if errornode is not None: From 74e6689cd0e7f8eb5d4d80d41bb9911a1f9e7b01 Mon Sep 17 00:00:00 2001 From: lusum Date: Tue, 9 Feb 2021 23:45:05 +0100 Subject: [PATCH 07/40] move some functions to utils --- resources/lib/ampache_plugin.py | 41 +++++------------------------- resources/lib/utils.py | 45 +++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 62040fe..91ef722 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -79,18 +79,9 @@ def get_album_artist_name(node): fullname = fullname + " - [ " + ut.tString(30195) + " " + disknumber + " ]" return fullname -def getRating(rating): - if rating: - #converts from five stats ampache rating to ten stars kodi rating - rating = int(float(rating)*2) - else: - #zero equals no rating - rating = 0 - return rating - def get_infolabels(object_type , node): infoLabels = None - rating = getRating(node.findtext("rating")) + rating = ut.getRating(node.findtext("rating")) if object_type == 'albums': infoLabels = { 'Title' : str(node.findtext("name")) , @@ -453,19 +444,7 @@ def get_items(object_type, object_id=None, add=None,\ #set the mode - if object_type == 'artists': - mode = 1 - elif object_type == 'albums': - mode = 2 - elif object_type == 'playlists': - mode = 4 - elif object_type == 'tags': - if object_subtype == 'tag_artists': - mode = 19 - elif object_subtype == 'tag_albums': - mode = 20 - elif object_subtype == 'tag_songs': - mode = 21 + mode = ut.otype_to_mode(object_type, object_subtype) #here the documentation for an ampache connection #first create the connection object @@ -545,11 +524,8 @@ def do_search(object_type,object_subtype=None,thisFilter=None): def get_stats(object_type, object_subtype=None, limit=5000 ): xbmc.log("AmpachePlugin::get_stats ", xbmc.LOGDEBUG) - mode = None - if object_type == 'artists': - mode = 1 - elif object_type == 'albums': - mode = 2 + + mode = ut.otype_to_mode(object_type) xbmcplugin.setContent(int(sys.argv[1]), object_type) @@ -594,13 +570,8 @@ def get_random(object_type, random_items): ampConn = ampache_connect.AmpacheConnect() amtype = ut.otype_to_type(object_type) - if object_type == 'albums': - mode = 2 - elif object_type == 'artists': - mode = 1 - elif object_type == 'playlists': - mode = 4 - #song is the same mode + + mode = ut.otype_to_mode(object_type) xbmcplugin.setContent(int(sys.argv[1]), object_type) diff --git a/resources/lib/utils.py b/resources/lib/utils.py index 0d7f1ed..c776f90 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -6,6 +6,42 @@ #main plugin/service library ampache = xbmcaddon.Addon("plugin.audio.ampache") +def otype_to_mode(object_type, object_subtype=None): + mode = None + if object_type == 'artists': + mode = 1 + elif object_type == 'albums': + mode = 2 + elif object_type == 'songs': + mode = 3 + elif object_type == 'playlists': + mode = 4 + elif object_type == 'tags' or object_type == 'genres': + if object_subtype == 'tag_artists' or object_subtype == 'genre_artists': + mode = 19 + elif object_subtype == 'tag_albums' or object_subtype == 'genre_albums': + mode = 20 + elif object_subtype == 'tag_songs' or object_subtype == 'genre_songs': + mode = 21 + + return mode + +def mode_to_tags(mode): + if(int(ampache.getSetting("api-version"))) < 500000: + if mode == 19: + return "tags","tag_artists" + if mode == 20: + return "tags","tag_albums" + if mode == 21: + return "tags","tag_songs" + else: + if mode == 19: + return "genres","genre_artists" + if mode == 20: + return "genres","genre_albums" + if mode == 21: + return "genres","genre_songs" + def otype_to_type(object_type): if object_type == 'albums': return 'album' @@ -105,3 +141,12 @@ def get_objectId_from_fileURL( file_url ): except: pass return object_id + +def getRating(rating): + if rating: + #converts from five stats ampache rating to ten stars kodi rating + rating = int(float(rating)*2) + else: + #zero equals no rating + rating = 0 + return rating From 000be0dadeb6e342eba3dad94d81dea262143f78 Mon Sep 17 00:00:00 2001 From: lusum Date: Wed, 10 Feb 2021 00:02:32 +0100 Subject: [PATCH 08/40] tag/genre support --- resources/lib/ampache_plugin.py | 58 ++++++++++++++++++--------------- resources/lib/utils.py | 2 ++ 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 91ef722..f470063 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -49,12 +49,20 @@ def searchGui(): endDir = do_search("songs","search_songs") elif ret == 5: ret2 = dialog.contextmenu([ut.tString(30112),ut.tString(30113),ut.tString(30114)]) - if ret2 == 0: - endDir = do_search("tags","tag_artists") - elif ret2 == 1: - endDir = do_search("tags","tag_albums") - elif ret2 == 2: - endDir = do_search("tags","tag_songs") + if(int(ampache.getSetting("api-version"))) < 500000: + if ret2 == 0: + endDir = do_search("tags","tag_artists") + elif ret2 == 1: + endDir = do_search("tags","tag_albums") + elif ret2 == 2: + endDir = do_search("tags","tag_songs") + else: + if ret2 == 0: + endDir = do_search("genres","genre_artists") + elif ret2 == 1: + endDir = do_search("genres","genre_albums") + elif ret2 == 2: + endDir = do_search("genres","genre_songs") return endDir @@ -420,16 +428,22 @@ def get_items(object_type, object_id=None, add=None,\ addDir("All Songs",1,72, object_id=object_id) elif object_subtype == 'tag_albums': action = 'tag_albums' + elif object_subtype == 'genre_albums': + action = 'genre_albums' elif object_subtype == 'album': action = 'album' elif object_type == 'artists': if object_subtype == 'tag_artists': action = 'tag_artists' - if object_subtype == 'artist': + elif object_subtype == 'genre_artists': + action = 'genre_artists' + elif object_subtype == 'artist': action = 'artist' elif object_type == 'songs': if object_subtype == 'tag_songs': action = 'tag_songs' + elif object_subtype == 'genre_songs': + action = 'genre_songs' elif object_subtype == 'playlist_songs': action = 'playlist_songs' elif object_subtype == 'album_songs': @@ -852,32 +866,22 @@ def Main(): #mode 5 podcast #19-21 tags/genres mode - elif mode==19: + elif mode>=19 and mode <=21: + object_type, object_subtype = ut.mode_to_tags(mode) #get_all tags/genres if submode == 5: - get_items(object_type = "tags", object_subtype="tag_artists") + get_items(object_type = object_type, object_subtype=object_subtype) #search tag/genre elif submode == 10: - endDir = do_search("tags","tag_artists") + endDir = do_search(object_type,object_subtype) #get all songs from a tag_id/genre_id elif submode == 71: - get_items(object_type="artists", object_subtype="tag_artists",object_id=object_id) - - elif mode==20: - if submode == 5: - get_items(object_type = "tags", object_subtype="tag_albums") - elif submode == 10: - endDir = do_search("tags","tag_albums") - elif submode == 71: - get_items(object_type="albums", object_subtype="tag_albums",object_id=object_id) - - elif mode==21: - if submode == 5: - get_items(object_type = "tags", object_subtype="tag_songs") - elif submode == 10: - endDir = do_search("tags","tag_songs") - elif submode == 71: - get_items(object_type="songs", object_subtype="tag_songs",object_id=object_id) + if mode == 19: + get_items(object_type="artists", object_subtype=object_subtype,object_id=object_id) + elif mode == 20: + get_items(object_type="albums", object_subtype=object_subtype,object_id=object_id) + elif mode == 21: + get_items(object_type="songs", object_subtype=object_subtype,object_id=object_id) #main meus 50-100 #explore diff --git a/resources/lib/utils.py b/resources/lib/utils.py index c776f90..630fa5e 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -53,6 +53,8 @@ def otype_to_type(object_type): return 'playlist' elif object_type == 'tags': return 'tag' + elif object_type == 'genres': + return 'genre' return None def int_to_strBool(s): From a362849204d55539f8446083b60e209658134acd Mon Sep 17 00:00:00 2001 From: lusum Date: Wed, 10 Feb 2021 00:32:53 +0100 Subject: [PATCH 09/40] remove obsolete code --- resources/lib/ampache_plugin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index f470063..1e17e16 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -209,7 +209,7 @@ def addLinks(elem,object_type,useCacheArt,mode): else: continue artist_id = getNestedTypeId(node,"artist") - if artist_id is not None and artist_id <> "": + if artist_id is not None and artist_id != "": cm.append( ( ut.tString(30141),"Container.Update(%s?object_id=%s&mode=1&submode=6)" % ( sys.argv[0],artist_id ) ) ) @@ -271,13 +271,13 @@ def addSongLinks(elem): cm = [] artist_id = getNestedTypeId(node,"artist") - if artist_id is not None and artist_id <> "": + if artist_id is not None and artist_id != "": cm.append( ( ut.tString(30138), "Container.Update(%s?object_id=%s&mode=1&submode=6)" % ( sys.argv[0],artist_id ) ) ) album_id = getNestedTypeId(node,"album") - if album_id is not None and album_id <> "": + if album_id is not None and album_id != "": cm.append( ( ut.tString(30139), "Container.Update(%s?object_id=%s&mode=2&submode=6)" % ( sys.argv[0],album_id ) ) ) From cfb92b6e9ffb1125a89eea71d64893969c75ce7e Mon Sep 17 00:00:00 2001 From: lusum Date: Wed, 10 Feb 2021 00:42:44 +0100 Subject: [PATCH 10/40] remove useless code --- resources/lib/ampache_plugin.py | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 1e17e16..625ba3e 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -304,35 +304,9 @@ def play_track(object_id,song_url): xbmc.log("AmpachePlugin::play_track object or song null", xbmc.LOGINFO ) return - old_object_id = None - - #it checks if we need the song infolabels ( object_id cached is different from - #object_id of the song, for instance as kore app call the song - try: - plugin_url = xbmc.getInfoLabel('ListItem.FileNameAndPath') - params=ut.get_params(plugin_url) - old_object_id=params["object_id"] - xbmc.log("AmpachePlugin::play_track old_object_id " + old_object_id, xbmc.LOGDEBUG) - except: - pass - liz = xbmcgui.ListItem() - try: - if old_object_id == None or old_object_id != object_id: - xbmc.log("AmpachePlugin::play_track refresh infoLabels", xbmc.LOGDEBUG) - - ampConn = ampache_connect.AmpacheConnect() - ampConn.filter = object_id - elem = ampConn.ampache_http_request("song") - - for thisnode in elem: - node = thisnode - fillListItemWithSongInfo(liz,node) - liz.setProperty("IsPlayable", "true") - except: - pass - liz.setPath(song_url) + xbmcplugin.setResolvedUrl(handle=int(sys.argv[1]), succeeded=True,listitem=liz) #Main function to add xbmc plugin elements From 5801a2e7cd4f143a31e676567dea97c684c22a7b Mon Sep 17 00:00:00 2001 From: lusum Date: Wed, 10 Feb 2021 01:01:02 +0100 Subject: [PATCH 11/40] remove useless code --- resources/lib/ampache_plugin.py | 45 ++++++++++++++++----------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 625ba3e..103b04c 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -165,22 +165,6 @@ def check_get_art_url(node): url = node.findtext("art") return url -#it handles albumArt and song info -def fillListItemWithSongInfo(liz,node): - object_id = node.attrib["id"] - image_url = check_get_art_url(node) - try: - album_id = getNestedTypeId(node,"album") - albumArt = art.get_art(album_id,"album",image_url) - except: - albumArt = art.get_art(None,"album",image_url) - liz.setLabel(str(node.findtext("title"))) - liz.setArt( art.get_artLabels(albumArt) ) - #needed by play_track to play the song, added here to uniform api - liz.setPath(node.findtext("url")) - liz.setInfo( type="music", infoLabels=get_infolabels("songs", node) ) - liz.setMimeType(node.findtext("mime")) - def addLinks(elem,object_type,useCacheArt,mode): image = "DefaultFolder.png" @@ -264,9 +248,26 @@ def addSongLinks(elem): song_id = node.attrib["id"] if song_id is None or song_id == "": continue + + song_url = str(node.findtext("url")) + song_title = str(node.findtext("title")) + liz=xbmcgui.ListItem() - fillListItemWithSongInfo(liz,node) + + image_url = check_get_art_url(node) + try: + album_id = getNestedTypeId(node,"album") + albumArt = art.get_art(album_id,"album",image_url) + except: + albumArt = art.get_art(None,"album",image_url) + + liz.setLabel(song_title) + liz.setArt( art.get_artLabels(albumArt) ) + #needed by play_track to play the song, added here to uniform api + liz.setInfo( type="music", infoLabels=get_infolabels("songs", node) ) + liz.setMimeType(node.findtext("mime")) liz.setProperty("IsPlayable", "true") + liz.setPath(song_url) cm = [] @@ -282,7 +283,6 @@ def addSongLinks(elem): "Container.Update(%s?object_id=%s&mode=2&submode=6)" % ( sys.argv[0],album_id ) ) ) - song_title = str(node.findtext("title")) cm.append( ( ut.tString(30140), "Container.Update(%s?title=%s&mode=3&submode=12)" % ( sys.argv[0],urllib.parse.quote_plus(song_title) ) ) ) @@ -290,8 +290,7 @@ def addSongLinks(elem): if cm != []: liz.addContextMenuItems(cm) - song_url = node.findtext("url") - track_parameters = { "mode": 200, "song_url" : song_url, "object_id" : song_id} + track_parameters = { "mode": 200, "song_url" : song_url} url = sys.argv[0] + '?' + urllib.parse.urlencode(track_parameters) tu= (url,liz) it.append(tu) @@ -299,8 +298,8 @@ def addSongLinks(elem): xbmcplugin.addDirectoryItems(handle=int(sys.argv[1]),items=it,totalItems=len(elem)) #The function that actually plays an Ampache URL by using setResolvedUrl -def play_track(object_id,song_url): - if song_url == None or object_id == None: +def play_track(song_url): + if song_url == None: xbmc.log("AmpachePlugin::play_track object or song null", xbmc.LOGINFO ) return @@ -1016,7 +1015,7 @@ def Main(): elif mode==200: #workaround busydialog bug xbmc.executebuiltin('Dialog.Close(busydialog)') - play_track(object_id, m_params['song_url']) + play_track(m_params['song_url']) #change rating elif mode==205: From a351ac95f037b9733d6100b3129057413b8451f8 Mon Sep 17 00:00:00 2001 From: lusum Date: Wed, 10 Feb 2021 01:25:17 +0100 Subject: [PATCH 12/40] partially merge getRandom and getstats, remove duplications, remove uselesss code --- resources/lib/ampache_plugin.py | 53 +++++++++++---------------------- 1 file changed, 17 insertions(+), 36 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 103b04c..4207470 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -300,7 +300,7 @@ def addSongLinks(elem): #The function that actually plays an Ampache URL by using setResolvedUrl def play_track(song_url): if song_url == None: - xbmc.log("AmpachePlugin::play_track object or song null", xbmc.LOGINFO ) + xbmc.log("AmpachePlugin::play_track song null", xbmc.LOGINFO ) return liz = xbmcgui.ListItem() @@ -387,7 +387,6 @@ def get_items(object_type, object_id=None, add=None,\ if limit == None: limit = int(ampache.getSetting(object_type)) - mode = None xbmcplugin.setContent(int(sys.argv[1]), object_type) #default: object_type is the action,otherwise see the if list below @@ -551,53 +550,31 @@ def get_recent(object_type,submode,object_subtype=None): def get_random(object_type, random_items): xbmc.log("AmpachePlugin::get_random: object_type " + object_type, xbmc.LOGDEBUG) - mode = None #object type can be : albums, artists, songs, playlists - ampConn = ampache_connect.AmpacheConnect() - - amtype = ut.otype_to_type(object_type) - mode = ut.otype_to_mode(object_type) xbmcplugin.setContent(int(sys.argv[1]), object_type) - try: - xbmc.log("AmpachePlugin::get_random: random_items " + str(random_items), xbmc.LOGDEBUG ) - items = int(ampache.getSetting(object_type)) - xbmc.log("AmpachePlugin::get_random: total items in the catalog " + str(items), xbmc.LOGDEBUG ) - except: - return + items = int(ampache.getSetting(object_type)) if random_items > items: #if items are less than random_itmes, return all items get_items(object_type, limit=items) return - #playlists are not in the new stats api, so, use the old mode - if(int(ampache.getSetting("api-version"))) >= 400001 and object_type != 'playlists': - action = 'stats' - thisFilter = 'random' + + seq = random.sample(list(range(items)),random_items) + xbmc.log("AmpachePlugin::get_random: seq " + str(seq), xbmc.LOGDEBUG ) + elements = [] + for item_id in seq: try: - ampConn.filter = thisFilter - ampConn.limit = random_items - ampConn.type = amtype + ampConn = ampache_connect.AmpacheConnect() - elem = ampConn.ampache_http_request(action) + ampConn.offset = item_id + ampConn.limit = 1 + elem = ampConn.ampache_http_request(object_type) addItem( object_type, mode , elem) except: - return - - else: - seq = random.sample(list(range(items)),random_items) - xbmc.log("AmpachePlugin::get_random: seq " + str(seq), xbmc.LOGDEBUG ) - elements = [] - for item_id in seq: - try: - ampConn.offset = item_id - ampConn.limit = 1 - elem = ampConn.ampache_http_request(object_type) - addItem( object_type, mode , elem) - except: - pass + pass def switchFromMusicPlaylist(addon_url, mode, submode, object_id=None, title=None): """ @@ -677,7 +654,11 @@ def manage_stats_menu(submode, object_type): num_items = (int(ampache.getSetting("random_items"))*3)+3 if submode == 40: - get_random(object_type, num_items) + #playlists are not in the new stats api, so, use the old mode + if(int(ampache.getSetting("api-version"))) < 400001 or object_type == 'playlists': + get_random(object_type, num_items) + else: + get_stats(object_type=object_type,object_subtype="random",limit=num_items) elif submode == 41: get_stats(object_type=object_type,object_subtype="highest",limit=num_items) elif submode == 42: From 398efa66210ca952dee79742d33cfd765e9b6a86 Mon Sep 17 00:00:00 2001 From: lusum Date: Wed, 10 Feb 2021 12:33:38 +0100 Subject: [PATCH 13/40] remove useless code and comments --- resources/lib/ampache_connect.py | 6 ------ resources/lib/ampache_plugin.py | 1 - 2 files changed, 7 deletions(-) diff --git a/resources/lib/ampache_connect.py b/resources/lib/ampache_connect.py index 8d8d2da..a2b255b 100644 --- a/resources/lib/ampache_connect.py +++ b/resources/lib/ampache_connect.py @@ -214,12 +214,6 @@ def ampache_http_request(self,action): return tree def build_ampache_url(self,action): - if ut.check_tokenexp(): - xbmc.log("refreshing token...", xbmc.LOGDEBUG ) - try: - self.AMPACHECONNECT() - except: - return token = self._ampache.getSetting("token") thisURL = self._connectionData["url"] + self.getBaseUrl() + '?action=' + action thisURL += '&auth=' + token diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 4207470..68b21cd 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -263,7 +263,6 @@ def addSongLinks(elem): liz.setLabel(song_title) liz.setArt( art.get_artLabels(albumArt) ) - #needed by play_track to play the song, added here to uniform api liz.setInfo( type="music", infoLabels=get_infolabels("songs", node) ) liz.setMimeType(node.findtext("mime")) liz.setProperty("IsPlayable", "true") From 80dfa3bfa73775baaf92f07a7dd4c72056b34fbf Mon Sep 17 00:00:00 2001 From: lusum Date: Wed, 10 Feb 2021 12:43:13 +0100 Subject: [PATCH 14/40] handle non standard mimetypes --- resources/lib/art.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/art.py b/resources/lib/art.py index 5ee6039..4fe44f4 100644 --- a/resources/lib/art.py +++ b/resources/lib/art.py @@ -49,7 +49,7 @@ def cacheArt(imageID,elem_type,url=None): if extension: mimetype, options = cgi.parse_header(extension) #little hack when content-type is not standard - if mimetype == "JPG": + if mimetype == "JPG" or mimetype == "jpeg": maintype = "image" subtype = "jpg" else: From 439993f6e2695071b1343bcd7acab03b4299c5b6 Mon Sep 17 00:00:00 2001 From: lusum Date: Wed, 10 Feb 2021 12:53:19 +0100 Subject: [PATCH 15/40] remove obsolete comments --- resources/lib/ampache_plugin.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 68b21cd..3a241bb 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -759,7 +759,6 @@ def Main(): #albums mode - #and others elif mode==2: #get all albums if submode == 5: @@ -780,7 +779,6 @@ def Main(): get_items(object_type="songs",object_id=object_id,object_subtype="album_songs") #song mode - #and others elif mode == 3: #10-30 search if submode == 10: From d0617ec9de343cfce8041c4c0e134de439b2d73e Mon Sep 17 00:00:00 2001 From: lusum Date: Wed, 10 Feb 2021 16:09:02 +0100 Subject: [PATCH 16/40] ampache connect only when it is used --- resources/lib/ampache_plugin.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 3a241bb..69314ec 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -699,8 +699,6 @@ def Main(): servers_manager.initializeServer() - ampacheConnect = ampache_connect.AmpacheConnect() - #check if the connection is expired #connect to the server #do not connect on main screen and when we operate setting; @@ -708,6 +706,7 @@ def Main(): if mode!=None and mode < endCheckConnection: if ut.check_tokenexp(): try: + ampacheConnect = ampache_connect.AmpacheConnect() ampacheConnect.AMPACHECONNECT() except: pass From f31493efa400cd3e446c94d4a25b6e7b45f5f6f9 Mon Sep 17 00:00:00 2001 From: lusum Date: Wed, 10 Feb 2021 17:43:48 +0100 Subject: [PATCH 17/40] added basic video support, update translations --- .../resource.language.en_gb/strings.po | 12 +++ .../resource.language.it_it/strings.po | 45 +++++++--- resources/lib/ampache_connect.py | 3 + resources/lib/ampache_plugin.py | 83 +++++++++++++++---- resources/lib/utils.py | 4 + 5 files changed, 118 insertions(+), 29 deletions(-) diff --git a/resources/language/resource.language.en_gb/strings.po b/resources/language/resource.language.en_gb/strings.po index 95dafb5..f8e531f 100644 --- a/resources/language/resource.language.en_gb/strings.po +++ b/resources/language/resource.language.en_gb/strings.po @@ -453,3 +453,15 @@ msgstr "" msgctxt "#30204" msgid "Permission error. If you are using Nextcloud don't check api_key box" msgstr "" + +msgctxt "#30220" +msgid "Video" +msgstr "" + +msgctxt "#30221" +msgid "Videos" +msgstr "" + +msgctxt "#30222" +msgid "Search Videos..." +msgstr "" diff --git a/resources/language/resource.language.it_it/strings.po b/resources/language/resource.language.it_it/strings.po index b4182b9..70cd990 100644 --- a/resources/language/resource.language.it_it/strings.po +++ b/resources/language/resource.language.it_it/strings.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: XBMC Addons\n" "Report-Msgid-Bugs-To: alanwww1@xbmc.org\n" "POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n" -"PO-Revision-Date: 2021-01-06 11:30+0100\n" +"PO-Revision-Date: 2021-02-10 17:42+0100\n" "Last-Translator: \n" "Language-Team: English (http://www.transifex.com/projects/p/xbmc-addons/" "language/en/)\n" @@ -106,19 +106,19 @@ msgstr "Tutto" msgctxt "#30111" msgid "Tag" -msgstr "" +msgstr "Genere" msgctxt "#30112" msgid "Artist tag" -msgstr "Tag artista" +msgstr "Genere artista" msgctxt "#30113" msgid "Album tag" -msgstr "Tag album" +msgstr "Genere album" msgctxt "#30114" msgid "Song tag" -msgstr "Tag canzone" +msgstr "Genere canzone" msgctxt "#30115" msgid "Artists" @@ -138,7 +138,7 @@ msgstr "" msgctxt "#30119" msgid "Tags" -msgstr "" +msgstr "Genere" # code msgctxt "#30120" @@ -236,15 +236,15 @@ msgstr "Mostra tutti gli album di questo artista" msgctxt "#30142" msgid "Artist tags..." -msgstr "Tag Artisti..." +msgstr "Generi Artisti..." msgctxt "#30143" msgid "Album tags..." -msgstr "Tag Album..." +msgstr "Generi Album..." msgctxt "#30144" msgid "Song tags..." -msgstr "Tag Canzoni..." +msgstr "Generi Canzoni..." msgctxt "#30145" msgid "Recently Added..." @@ -312,7 +312,7 @@ msgstr "Canzoni Dimenticate..." msgctxt "#30161" msgid "Newest Artists..." -msgstr "Nuovi artisti.." +msgstr "Nuovi artisti..." msgctxt "#30162" msgid "Newest Albums..." @@ -420,11 +420,11 @@ msgstr "Plugin Ampache" msgctxt "#30190" msgid "Recently Played Artists..." -msgstr "Artisti suonati recentemente.." +msgstr "Artisti suonati recentemente..." msgctxt "#30191" msgid "Recently Played Albums..." -msgstr "Album suonati recentemente.." +msgstr "Album suonati recentemente..." msgctxt "#30192" msgid "Recently Played Songs..." @@ -462,6 +462,27 @@ msgctxt "#30204" msgid "Permission error. If you are using Nextcloud don't check api_key box" msgstr "Permessi errati. Se state usando Nextcloud non utilizzare l'api_key" +msgctxt "#30220" +msgid "Video" +msgstr "" + +msgctxt "#30221" +msgid "Videos" +msgstr "Video" + +# code +msgctxt "#30222" +msgid "Search Videos..." +msgstr "Ricerca video..." + +# code +#, fuzzy +#~| msgctxt "#30122" +#~| msgid "Search Songs..." +#~ msgctxt "#30221" +#~ msgid "Search Videos..." +#~ msgstr "Ricerca canzoni..." + #~ msgctxt "#30190" #~ msgid "Recent Artists..." #~ msgstr "Artisti recenti.." diff --git a/resources/lib/ampache_connect.py b/resources/lib/ampache_connect.py index a2b255b..00ffeb7 100644 --- a/resources/lib/ampache_connect.py +++ b/resources/lib/ampache_connect.py @@ -52,6 +52,9 @@ def fillConnectionSettings(self,tree,nTime): self._ampache.setSetting("albums", tree.findtext("albums")) self._ampache.setSetting("songs", tree.findtext("songs")) self._ampache.setSetting("playlists", tree.findtext("playlists")) + videos = tree.findtext("videos") + if videos: + self._ampache.setSetting("videos", videos) self._ampache.setSetting("session_expire", tree.findtext("session_expire")) self._ampache.setSetting("add", tree.findtext("add")) self._ampache.setSetting("token", token) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 69314ec..fe38b55 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -35,7 +35,7 @@ def searchGui(): dialog = xbmcgui.Dialog() ret = dialog.contextmenu([ut.tString(30106),ut.tString(30107),ut.tString(30108),\ - ut.tString(30109),ut.tString(30110),ut.tString(30111)]) + ut.tString(30109),ut.tString(30110),ut.tString(30220),ut.tString(30111)]) endDir = False if ret == 0: endDir = do_search("artists") @@ -48,6 +48,8 @@ def searchGui(): elif ret == 4: endDir = do_search("songs","search_songs") elif ret == 5: + endDir = do_search("videos") + elif ret == 6: ret2 = dialog.contextmenu([ut.tString(30112),ut.tString(30113),ut.tString(30114)]) if(int(ampache.getSetting("api-version"))) < 500000: if ret2 == 0: @@ -121,6 +123,14 @@ def get_infolabels(object_type , node): 'Mediatype' : 'song' } + elif object_type == 'videos': + infoLabels = { + 'Title' : str(node.findtext("name")) , + 'VideoResolution' : node.findtext("resolution") , + 'Size' : node.findtext("size") , + 'Mediatype' : 'video' + } + return infoLabels def getNestedTypeId(node,elem_type): @@ -242,7 +252,6 @@ def addLinks(elem,object_type,useCacheArt,mode): def addSongLinks(elem): xbmcplugin.setContent(int(sys.argv[1]), "songs") - ok=True it=[] for node in elem.iter("song"): song_id = node.attrib["id"] @@ -289,21 +298,47 @@ def addSongLinks(elem): if cm != []: liz.addContextMenuItems(cm) - track_parameters = { "mode": 200, "song_url" : song_url} + track_parameters = { "mode": 200, "play_url" : song_url} url = sys.argv[0] + '?' + urllib.parse.urlencode(track_parameters) tu= (url,liz) it.append(tu) xbmcplugin.addDirectoryItems(handle=int(sys.argv[1]),items=it,totalItems=len(elem)) +def addVideoLinks(elem): + xbmcplugin.setContent(int(sys.argv[1]), "videos") + it=[] + for node in elem.iter("video"): + video_id = node.attrib["id"] + if video_id is None or video_id == "": + continue + + video_url = str(node.findtext("url")) + video_title = str(node.findtext("title")) + + liz=xbmcgui.ListItem() + + liz.setLabel(video_title) + liz.setInfo( type="video", infoLabels=get_infolabels("videos", node) ) + liz.setMimeType(node.findtext("mime")) + liz.setProperty("IsPlayable", "true") + liz.setPath(video_url) + + track_parameters = { "mode": 200, "play_url" : video_url} + url = sys.argv[0] + '?' + urllib.parse.urlencode(track_parameters) + tu= (url,liz) + it.append(tu) + + xbmcplugin.addDirectoryItems(handle=int(sys.argv[1]),items=it,totalItems=len(elem)) + #The function that actually plays an Ampache URL by using setResolvedUrl -def play_track(song_url): - if song_url == None: - xbmc.log("AmpachePlugin::play_track song null", xbmc.LOGINFO ) +def play_track(url): + if url == None: + xbmc.log("AmpachePlugin::play_track url null", xbmc.LOGINFO ) return liz = xbmcgui.ListItem() - liz.setPath(song_url) + liz.setPath(url) xbmcplugin.setResolvedUrl(handle=int(sys.argv[1]), succeeded=True,listitem=liz) @@ -327,15 +362,17 @@ def addDir(name,mode,submode,offset=None,object_id=None): xbmcplugin.addDirectoryItem(handle=handle,url=u,listitem=liz,isFolder=True) #this function add items to the directory using the low level addLinks of ddSongLinks functions -def addItem( object_type, mode , elem, useCacheArt=True): +def addItems( object_type, mode , elem, useCacheArt=True): image = "DefaultFolder.png" - xbmc.log("AmpachePlugin::addItem: object_type - " + str(object_type) , xbmc.LOGDEBUG ) + xbmc.log("AmpachePlugin::addItems: object_type - " + str(object_type) , xbmc.LOGDEBUG ) if useCacheArt: precacheArt(elem,object_type) if object_type == 'songs': addSongLinks(elem) + elif object_type == 'videos': + addVideoLinks(elem) else: addLinks(elem,object_type,useCacheArt,mode) return @@ -442,7 +479,7 @@ def get_items(object_type, object_id=None, add=None,\ #or ampache_binary_request if the server return a binary file (eg. an #image ) #it could be very simply to add json api, but we have to rewrite all - #function that rely on xml input, like additem + #function that rely on xml input, like additems try: ampConn = ampache_connect.AmpacheConnect() @@ -453,7 +490,7 @@ def get_items(object_type, object_id=None, add=None,\ ampConn.offset = offset elem = ampConn.ampache_http_request(action) - addItem( object_type, mode , elem, useCacheArt) + addItems( object_type, mode , elem, useCacheArt) except: return @@ -530,7 +567,7 @@ def get_stats(object_type, object_subtype=None, limit=5000 ): ampConn.type = amtype elem = ampConn.ampache_http_request(action) - addItem( object_type, mode , elem) + addItems( object_type, mode , elem) except: return @@ -571,7 +608,7 @@ def get_random(object_type, random_items): ampConn.offset = item_id ampConn.limit = 1 elem = ampConn.ampache_http_request(object_type) - addItem( object_type, mode , elem) + addItems( object_type, mode , elem) except: pass @@ -607,7 +644,7 @@ def main_params(plugin_url): m_params['object_id'] = None m_params['title'] = None #used only in play tracks - m_params['song_url'] = None + m_params['play_url'] = None #used to managed very long lists m_params['offset'] = None @@ -634,8 +671,8 @@ def main_params(plugin_url): except: pass try: - m_params['song_url']=urllib.parse.unquote_plus(params["song_url"]) - xbmc.log("AmpachePlugin::song_url " + m_params['song_url'], xbmc.LOGDEBUG) + m_params['play_url']=urllib.parse.unquote_plus(params["play_url"]) + xbmc.log("AmpachePlugin::play_url " + m_params['play_url'], xbmc.LOGDEBUG) except: pass try: @@ -815,6 +852,14 @@ def Main(): #mode 5 podcast + #video + elif mode==8: + if submode == 5: + get_all("videos", mode ,m_params['offset']) + #get_items(object_type="playlists") + elif submode == 10: + endDir = do_search("videos") + #19-21 tags/genres mode elif mode>=19 and mode <=21: object_type, object_subtype = ut.mode_to_tags(mode) @@ -859,6 +904,8 @@ def Main(): addDir(ut.tString(30115) +" (" + ampache.getSetting("artists")+ ")",1,5) addDir(ut.tString(30116) + " (" + ampache.getSetting("albums") + ")",2,5) addDir(ut.tString(30118) + " (" + ampache.getSetting("playlists")+ ")",4,5) + if ampache.getSetting("videos"): + addDir(ut.tString(30221) + " (" + ampache.getSetting("videos")+ ")",8,5) apiVersion = int(ampache.getSetting("api-version")) if apiVersion >= 380001: #get all tags ( submode 5 ) @@ -897,6 +944,8 @@ def Main(): addDir(ut.tString(30123),4,10) #search all addDir(ut.tString(30124),3,11) + #search video + addDir(ut.tString(30222),8,10) #search tag addDir(ut.tString(30125),54,10) @@ -992,7 +1041,7 @@ def Main(): elif mode==200: #workaround busydialog bug xbmc.executebuiltin('Dialog.Close(busydialog)') - play_track(m_params['song_url']) + play_track(m_params['play_url']) #change rating elif mode==205: diff --git a/resources/lib/utils.py b/resources/lib/utils.py index 630fa5e..779aede 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -16,6 +16,8 @@ def otype_to_mode(object_type, object_subtype=None): mode = 3 elif object_type == 'playlists': mode = 4 + elif object_type == 'videos': + mode = 8 elif object_type == 'tags' or object_type == 'genres': if object_subtype == 'tag_artists' or object_subtype == 'genre_artists': mode = 19 @@ -55,6 +57,8 @@ def otype_to_type(object_type): return 'tag' elif object_type == 'genres': return 'genre' + elif object_type == 'videos': + return 'video' return None def int_to_strBool(s): From 0d6ba4c5bc9e87d63c0aa64a0bd49c97619cdfd6 Mon Sep 17 00:00:00 2001 From: lusum Date: Wed, 10 Feb 2021 23:38:00 +0100 Subject: [PATCH 18/40] little fix, remove old commented code --- resources/lib/ampache_plugin.py | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index fe38b55..a74e73b 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -24,14 +24,6 @@ #possible to start a song without initialising the plugin ampache = xbmcaddon.Addon("plugin.audio.ampache") -#ampache_addon_path = ampache.getAddonInfo('path') -#ampache_dir = xbmc.translatePath( ampache_addon_path ) -#if PY2: -# ampache_dir = ampache_dir.decode('utf-8') -#BASE_RESOURCE_PATH = os.path.join( ampache_dir, 'resources' ) -#mediaDir = os.path.join( BASE_RESOURCE_PATH , 'media' ) -#imagepath = os.path.join( mediaDir ,'images') - def searchGui(): dialog = xbmcgui.Dialog() ret = dialog.contextmenu([ut.tString(30106),ut.tString(30107),ut.tString(30108),\ @@ -187,8 +179,6 @@ def addLinks(elem,object_type,useCacheArt,mode): object_id = node.attrib["id"] if object_id is None or object_id == "": continue - #xbmc.log("AmpachePlugin::addLinks: object_id - " + str(object_id) , xbmc.LOGDEBUG ) - #xbmc.log("AmpachePlugin::addLinks: node " + ET.tostring(node) , xbmc.LOGDEBUG ) name = str(node.findtext("name")) @@ -424,7 +414,6 @@ def get_items(object_type, object_id=None, add=None,\ if limit == None: limit = int(ampache.getSetting(object_type)) - xbmcplugin.setContent(int(sys.argv[1]), object_type) #default: object_type is the action,otherwise see the if list below action = object_type @@ -736,6 +725,8 @@ def Main(): servers_manager.initializeServer() + ampacheConnect = ampache_connect.AmpacheConnect() + #check if the connection is expired #connect to the server #do not connect on main screen and when we operate setting; @@ -743,7 +734,6 @@ def Main(): if mode!=None and mode < endCheckConnection: if ut.check_tokenexp(): try: - ampacheConnect = ampache_connect.AmpacheConnect() ampacheConnect.AMPACHECONNECT() except: pass @@ -769,7 +759,6 @@ def Main(): #get all artists if submode == 5: get_all("artists", mode ,m_params['offset']) - #get_items("artists", limit=None, useCacheArt=False) #get the artist from this album's artist_id elif submode == 6: switchFromMusicPlaylist(addon_url, mode, submode, object_id=object_id ) @@ -799,7 +788,6 @@ def Main(): #get all albums if submode == 5: get_all("albums", mode ,m_params['offset']) - #get_items("albums", limit=None, useCacheArt=False) #get the album from the song's album_id elif submode == 6: switchFromMusicPlaylist(addon_url, mode, submode, object_id=object_id ) @@ -837,15 +825,12 @@ def Main(): elif mode==4: if submode == 5: get_all("playlists", mode ,m_params['offset']) - #get_items(object_type="playlists") elif submode == 10: endDir = do_search("playlists") elif submode > 30 and submode < 35: get_recent( "playlists", submode ) elif submode == 40: manage_stats_menu(submode, "playlists") - #elif object_id: - # get_items(object_type="playlists",object_id=object_id) #get all songs from a playlist_id elif submode == 71: get_items(object_type="songs",object_id=object_id,object_subtype="playlist_songs") @@ -856,7 +841,6 @@ def Main(): elif mode==8: if submode == 5: get_all("videos", mode ,m_params['offset']) - #get_items(object_type="playlists") elif submode == 10: endDir = do_search("videos") From d7da0f4fd69481bbdd38f8b47d83e780b83cc1bd Mon Sep 17 00:00:00 2001 From: lusum Date: Wed, 10 Feb 2021 23:59:05 +0100 Subject: [PATCH 19/40] cancel old session values at the start to avoid that one expired old session could block the first connection to the server --- resources/lib/ampache_plugin.py | 3 +-- resources/lib/art_clean.py | 6 ++++++ resources/lib/service.py | 3 ++- resources/lib/utils.py | 5 +++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index a74e73b..28d5484 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -725,8 +725,6 @@ def Main(): servers_manager.initializeServer() - ampacheConnect = ampache_connect.AmpacheConnect() - #check if the connection is expired #connect to the server #do not connect on main screen and when we operate setting; @@ -734,6 +732,7 @@ def Main(): if mode!=None and mode < endCheckConnection: if ut.check_tokenexp(): try: + ampacheConnect = ampache_connect.AmpacheConnect() ampacheConnect.AMPACHECONNECT() except: pass diff --git a/resources/lib/art_clean.py b/resources/lib/art_clean.py index f84515e..46b46f2 100644 --- a/resources/lib/art_clean.py +++ b/resources/lib/art_clean.py @@ -19,6 +19,12 @@ user_mediaDir = os.path.join( user_dir , 'media' ) cacheDir = os.path.join( user_mediaDir , 'cache' ) +def clean_settings(): + ampache.setSetting("session_expire", "") + ampache.setSetting("add", "") + ampache.setSetting("token", "") + ampache.setSetting("token-exp", "") + def clean_cache_art(): #hack to force the creation of profile directory if don't exists if not os.path.isdir(user_dir): diff --git a/resources/lib/service.py b/resources/lib/service.py index 9b0acad..33806cb 100644 --- a/resources/lib/service.py +++ b/resources/lib/service.py @@ -1,5 +1,6 @@ from ampache_monitor import AmpacheMonitor -from art_clean import clean_cache_art +from art_clean import clean_cache_art, clean_settings +clean_settings() clean_cache_art() AmpacheMonitor().run() diff --git a/resources/lib/utils.py b/resources/lib/utils.py index 779aede..f6cdd1a 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -80,14 +80,15 @@ def strBool_to_bool(s): raise ValueError def check_tokenexp(): - tokenexp = int(ampache.getSetting("token-exp")) + session_time = ampache.getSetting("session_expire") + if session_time is None or session_time == "": + return True #from python 3.7 we can easly compare the dates, otherwise we use the old #method if sys.version_info >= (3, 7): try: - session_time = ampache.getSetting("session_expire") s_time = datetime.datetime.fromisoformat(session_time) if datetime.datetime.now(datetime.timezone.utc) > s_time: return True From b13cd791a05a0873d0ff5b97b1edaa2949da9f3f Mon Sep 17 00:00:00 2001 From: lusum Date: Thu, 11 Feb 2021 00:20:54 +0100 Subject: [PATCH 20/40] correct way --- resources/lib/ampache_connect.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/ampache_connect.py b/resources/lib/ampache_connect.py index 00ffeb7..f7b3af4 100644 --- a/resources/lib/ampache_connect.py +++ b/resources/lib/ampache_connect.py @@ -22,7 +22,7 @@ class ConnectionError(Exception): pass def __init__(self): - self._ampache = xbmcaddon.Addon() + self._ampache = xbmcaddon.Addon("plugin.audio.ampache") jsStorServer = json_storage.JsonStorage("servers.json") serverStorage = jsStorServer.getData() self._connectionData = serverStorage["servers"][serverStorage["current_server"]] From cb30a2e83914e91868ea8be614ab87f54f6dd8ab Mon Sep 17 00:00:00 2001 From: lusum Date: Thu, 11 Feb 2021 00:22:02 +0100 Subject: [PATCH 21/40] correct way --- resources/lib/json_storage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/json_storage.py b/resources/lib/json_storage.py index ee12ada..2e27385 100644 --- a/resources/lib/json_storage.py +++ b/resources/lib/json_storage.py @@ -12,7 +12,7 @@ class JsonStorage(object): def __init__(self,filename): - ampache = xbmcaddon.Addon() + ampache = xbmcaddon.Addon("plugin.audio.ampache") if PY2: base_dir = xbmc.translatePath( ampache.getAddonInfo('profile')) base_dir = base_dir.decode('utf-8') From 319c123215a07e471581aa79c16be6d03f215be2 Mon Sep 17 00:00:00 2001 From: lusum Date: Thu, 11 Feb 2021 00:32:37 +0100 Subject: [PATCH 22/40] README updated --- README | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README b/README index 642dabd..a33dfd2 100644 --- a/README +++ b/README @@ -27,3 +27,8 @@ To avoid random crashes in kodi don't do any operation in the last five seconds due to a kodi bug, playing next song generates a busy dialog ( impossible to avoid ) and operating on kodi generates another busy dialog. The combination of two busy dialogs working crashes kodi (https://github.com/xbmc/xbmc/issues/16756) + +When you update the 2.0 version from an old version, expecially on raspberri pi, the plugin could not work. +This behaviour is due to the kodi addon cache. To correct this one time problem, it is necessary to reboot the +mediacenter or, if the problem continues, uninstall and reinstall the plugin. + From 557d03cf70ee1ca668eaf2885fe7c824e455b8ce Mon Sep 17 00:00:00 2001 From: lusum Date: Thu, 11 Feb 2021 00:35:46 +0100 Subject: [PATCH 23/40] typo --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index a33dfd2..ee43573 100644 --- a/README +++ b/README @@ -28,7 +28,7 @@ due to a kodi bug, playing next song generates a busy dialog ( impossible to avo and operating on kodi generates another busy dialog. The combination of two busy dialogs working crashes kodi (https://github.com/xbmc/xbmc/issues/16756) -When you update the 2.0 version from an old version, expecially on raspberri pi, the plugin could not work. +When you update the 2.0 version from an old version, expecially on raspberry pi, the plugin could not work. This behaviour is due to the kodi addon cache. To correct this one time problem, it is necessary to reboot the mediacenter or, if the problem continues, uninstall and reinstall the plugin. From 1182cd6787712e1bd5a7ba05692d59eebd5a6e27 Mon Sep 17 00:00:00 2001 From: lusum Date: Fri, 12 Feb 2021 16:14:05 +0100 Subject: [PATCH 24/40] merge addSongLinks and addVideoLinks in addPlayLinks --- resources/lib/ampache_plugin.py | 122 +++++++++++++------------------- resources/lib/utils.py | 9 ++- 2 files changed, 56 insertions(+), 75 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 28d5484..efa8435 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -236,85 +236,65 @@ def addLinks(elem,object_type,useCacheArt,mode): xbmcplugin.addDirectoryItems(handle=int(sys.argv[1]),items=it,totalItems=len(elem)) -# Used to populate items for songs on XBMC. Calls plugin script with mode == 45 and object_id == (ampache song id) -# TODO: Merge with addLinks(). Same basic idea going on, this one adds links all at once, as the other one -# Also, some property things, some different context menu things. -def addSongLinks(elem): +# Used to populate items for songs on XBMC. Calls plugin script with mode == +# 45 and play_ur == (ampache item url) +def addPlayLinks(elem, object_type , object_subtype=None): - xbmcplugin.setContent(int(sys.argv[1]), "songs") + xbmcplugin.setContent(int(sys.argv[1]), object_type) it=[] - for node in elem.iter("song"): - song_id = node.attrib["id"] - if song_id is None or song_id == "": - continue - song_url = str(node.findtext("url")) - song_title = str(node.findtext("title")) + elem_type = ut.otype_to_type(object_type,object_subtype) - liz=xbmcgui.ListItem() + for node in elem.iter(elem_type): + object_id = node.attrib["id"] + if object_id is None or object_id == "": + continue - image_url = check_get_art_url(node) - try: - album_id = getNestedTypeId(node,"album") - albumArt = art.get_art(album_id,"album",image_url) - except: - albumArt = art.get_art(None,"album",image_url) + play_url = str(node.findtext("url")) + object_title = str(node.findtext("title")) - liz.setLabel(song_title) - liz.setArt( art.get_artLabels(albumArt) ) - liz.setInfo( type="music", infoLabels=get_infolabels("songs", node) ) - liz.setMimeType(node.findtext("mime")) + liz=xbmcgui.ListItem() liz.setProperty("IsPlayable", "true") - liz.setPath(song_url) - - cm = [] + liz.setPath(play_url) + liz.setLabel(object_title) - artist_id = getNestedTypeId(node,"artist") - if artist_id is not None and artist_id != "": - cm.append( ( ut.tString(30138), - "Container.Update(%s?object_id=%s&mode=1&submode=6)" % ( - sys.argv[0],artist_id ) ) ) - - album_id = getNestedTypeId(node,"album") - if album_id is not None and album_id != "": - cm.append( ( ut.tString(30139), - "Container.Update(%s?object_id=%s&mode=2&submode=6)" % ( - sys.argv[0],album_id ) ) ) - - cm.append( ( ut.tString(30140), - "Container.Update(%s?title=%s&mode=3&submode=12)" % ( - sys.argv[0],urllib.parse.quote_plus(song_title) ) ) ) - - if cm != []: - liz.addContextMenuItems(cm) - - track_parameters = { "mode": 200, "play_url" : song_url} - url = sys.argv[0] + '?' + urllib.parse.urlencode(track_parameters) - tu= (url,liz) - it.append(tu) - - xbmcplugin.addDirectoryItems(handle=int(sys.argv[1]),items=it,totalItems=len(elem)) - -def addVideoLinks(elem): - xbmcplugin.setContent(int(sys.argv[1]), "videos") - it=[] - for node in elem.iter("video"): - video_id = node.attrib["id"] - if video_id is None or video_id == "": - continue + if elem_type == "song": + image_url = check_get_art_url(node) + try: + album_id = getNestedTypeId(node,"album") + albumArt = art.get_art(album_id,"album",image_url) + except: + albumArt = art.get_art(None,"album",image_url) - video_url = str(node.findtext("url")) - video_title = str(node.findtext("title")) + liz.setArt( art.get_artLabels(albumArt) ) + liz.setInfo( type="music", infoLabels=get_infolabels("songs", node) ) + liz.setMimeType(node.findtext("mime")) - liz=xbmcgui.ListItem() + cm = [] - liz.setLabel(video_title) - liz.setInfo( type="video", infoLabels=get_infolabels("videos", node) ) - liz.setMimeType(node.findtext("mime")) - liz.setProperty("IsPlayable", "true") - liz.setPath(video_url) + artist_id = getNestedTypeId(node,"artist") + if artist_id is not None and artist_id != "": + cm.append( ( ut.tString(30138), + "Container.Update(%s?object_id=%s&mode=1&submode=6)" % ( + sys.argv[0],artist_id ) ) ) - track_parameters = { "mode": 200, "play_url" : video_url} + album_id = getNestedTypeId(node,"album") + if album_id is not None and album_id != "": + cm.append( ( ut.tString(30139), + "Container.Update(%s?object_id=%s&mode=2&submode=6)" % ( + sys.argv[0],album_id ) ) ) + + cm.append( ( ut.tString(30140), + "Container.Update(%s?title=%s&mode=3&submode=12)" % ( + sys.argv[0],urllib.parse.quote_plus(object_title) ) ) ) + + if cm != []: + liz.addContextMenuItems(cm) + elif elem_type == "video": + liz.setInfo( type="video", infoLabels=get_infolabels("videos", node) ) + liz.setMimeType(node.findtext("mime")) + + track_parameters = { "mode": 200, "play_url" : play_url} url = sys.argv[0] + '?' + urllib.parse.urlencode(track_parameters) tu= (url,liz) it.append(tu) @@ -352,17 +332,15 @@ def addDir(name,mode,submode,offset=None,object_id=None): xbmcplugin.addDirectoryItem(handle=handle,url=u,listitem=liz,isFolder=True) #this function add items to the directory using the low level addLinks of ddSongLinks functions -def addItems( object_type, mode , elem, useCacheArt=True): +def addItems( object_type, mode , elem, useCacheArt=True, object_subtype=None): image = "DefaultFolder.png" xbmc.log("AmpachePlugin::addItems: object_type - " + str(object_type) , xbmc.LOGDEBUG ) if useCacheArt: precacheArt(elem,object_type) - if object_type == 'songs': - addSongLinks(elem) - elif object_type == 'videos': - addVideoLinks(elem) + if object_type == 'songs' or object_type == 'videos': + addPlayLinks(elem,object_type,object_subtype) else: addLinks(elem,object_type,useCacheArt,mode) return diff --git a/resources/lib/utils.py b/resources/lib/utils.py index f6cdd1a..e9452d8 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -44,13 +44,11 @@ def mode_to_tags(mode): if mode == 21: return "genres","genre_songs" -def otype_to_type(object_type): +def otype_to_type(object_type,object_subtype=None): if object_type == 'albums': return 'album' elif object_type == 'artists': return 'artist' - elif object_type == 'songs': - return 'song' elif object_type == 'playlists': return 'playlist' elif object_type == 'tags': @@ -59,6 +57,11 @@ def otype_to_type(object_type): return 'genre' elif object_type == 'videos': return 'video' + elif object_type == 'songs': + if object_subtype is None: + return 'song' + elif object_subtype == 'podcasts': + return None return None def int_to_strBool(s): From a46798ae36e2baa8903e7b162cec85e3642b7ec2 Mon Sep 17 00:00:00 2001 From: lusum Date: Fri, 12 Feb 2021 16:27:15 +0100 Subject: [PATCH 25/40] initial podcast support --- resources/lib/utils.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/resources/lib/utils.py b/resources/lib/utils.py index e9452d8..7c3e538 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -16,6 +16,8 @@ def otype_to_mode(object_type, object_subtype=None): mode = 3 elif object_type == 'playlists': mode = 4 + elif object_type == 'podcasts': + mode = 5 elif object_type == 'videos': mode = 8 elif object_type == 'tags' or object_type == 'genres': @@ -55,13 +57,15 @@ def otype_to_type(object_type,object_subtype=None): return 'tag' elif object_type == 'genres': return 'genre' + elif object_type == 'podcasts': + return 'podcast' elif object_type == 'videos': return 'video' elif object_type == 'songs': if object_subtype is None: return 'song' - elif object_subtype == 'podcasts': - return None + elif object_subtype == 'podcast_episodes': + return 'podcast_episode' return None def int_to_strBool(s): From a7d98961add2741158fc46b52f3236b967117e79 Mon Sep 17 00:00:00 2001 From: lusum Date: Fri, 12 Feb 2021 16:40:16 +0100 Subject: [PATCH 26/40] add podcast support (continue) --- resources/lib/ampache_connect.py | 3 +++ resources/lib/ampache_plugin.py | 28 ++++++++++++++++++++-------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/resources/lib/ampache_connect.py b/resources/lib/ampache_connect.py index f7b3af4..6f3e760 100644 --- a/resources/lib/ampache_connect.py +++ b/resources/lib/ampache_connect.py @@ -55,6 +55,9 @@ def fillConnectionSettings(self,tree,nTime): videos = tree.findtext("videos") if videos: self._ampache.setSetting("videos", videos) + podcasts = tree.findtext("podcasts") + if podcasts: + self._ampache.setSetting("podcasts", podcasts) self._ampache.setSetting("session_expire", tree.findtext("session_expire")) self._ampache.setSetting("add", tree.findtext("add")) self._ampache.setSetting("token", token) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index efa8435..a6bc16e 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -40,8 +40,6 @@ def searchGui(): elif ret == 4: endDir = do_search("songs","search_songs") elif ret == 5: - endDir = do_search("videos") - elif ret == 6: ret2 = dialog.contextmenu([ut.tString(30112),ut.tString(30113),ut.tString(30114)]) if(int(ampache.getSetting("api-version"))) < 500000: if ret2 == 0: @@ -57,8 +55,11 @@ def searchGui(): endDir = do_search("genres","genre_albums") elif ret2 == 2: endDir = do_search("genres","genre_songs") - - return endDir + elif ret == 6: + endDir = do_search("videos") + elif ret == 7: + endDir = do_search("podcasts") + return endDir #return album and artist name, only album could be confusing def get_album_artist_name(node): @@ -812,7 +813,15 @@ def Main(): elif submode == 71: get_items(object_type="songs",object_id=object_id,object_subtype="playlist_songs") - #mode 5 podcast + #podcasts + elif mode==5: + if submode == 5: + get_all("podcasts", mode ,m_params['offset']) + elif submode == 10: + endDir = do_search("podcasts") + #get all episodes + elif submode == 71: + get_items(object_type="songs",object_id=object_id,object_subtype="podcast_episodes") #video elif mode==8: @@ -867,6 +876,8 @@ def Main(): addDir(ut.tString(30118) + " (" + ampache.getSetting("playlists")+ ")",4,5) if ampache.getSetting("videos"): addDir(ut.tString(30221) + " (" + ampache.getSetting("videos")+ ")",8,5) + if ampache.getSetting("podcasts"): + addDir(ut.tString(30221) + " (" + ampache.getSetting("podcasts")+ ")",8,5) apiVersion = int(ampache.getSetting("api-version")) if apiVersion >= 380001: #get all tags ( submode 5 ) @@ -905,11 +916,12 @@ def Main(): addDir(ut.tString(30123),4,10) #search all addDir(ut.tString(30124),3,11) - #search video - addDir(ut.tString(30222),8,10) #search tag addDir(ut.tString(30125),54,10) - + #search video + addDir(ut.tString(30222),8,10) + #search podcast + #addDir(ut.tString(30222),8,10) #search tags elif mode==54: From e1d729dc56911cf3fa25f71d38494c65f7bbaeec Mon Sep 17 00:00:00 2001 From: lusum Date: Fri, 12 Feb 2021 16:43:44 +0100 Subject: [PATCH 27/40] typo --- resources/lib/ampache_plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index a6bc16e..57f1b53 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -59,7 +59,7 @@ def searchGui(): endDir = do_search("videos") elif ret == 7: endDir = do_search("podcasts") - return endDir + return endDir #return album and artist name, only album could be confusing def get_album_artist_name(node): From 2634704390b42a0e0ff0d6c86e294e532684fcd3 Mon Sep 17 00:00:00 2001 From: lusum Date: Fri, 12 Feb 2021 16:48:53 +0100 Subject: [PATCH 28/40] typo --- resources/lib/ampache_plugin.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 57f1b53..9ad9ecb 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -40,6 +40,10 @@ def searchGui(): elif ret == 4: endDir = do_search("songs","search_songs") elif ret == 5: + endDir = do_search("videos") + elif ret == 6: + endDir = do_search("podcasts") + elif ret == 7: ret2 = dialog.contextmenu([ut.tString(30112),ut.tString(30113),ut.tString(30114)]) if(int(ampache.getSetting("api-version"))) < 500000: if ret2 == 0: @@ -55,10 +59,6 @@ def searchGui(): endDir = do_search("genres","genre_albums") elif ret2 == 2: endDir = do_search("genres","genre_songs") - elif ret == 6: - endDir = do_search("videos") - elif ret == 7: - endDir = do_search("podcasts") return endDir #return album and artist name, only album could be confusing From 5677c2ec30d56f2753462230cbc29dc515488541 Mon Sep 17 00:00:00 2001 From: lusum Date: Fri, 12 Feb 2021 16:55:04 +0100 Subject: [PATCH 29/40] podcast support almost complete --- resources/lib/ampache_plugin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 9ad9ecb..18e6dda 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -27,7 +27,7 @@ def searchGui(): dialog = xbmcgui.Dialog() ret = dialog.contextmenu([ut.tString(30106),ut.tString(30107),ut.tString(30108),\ - ut.tString(30109),ut.tString(30110),ut.tString(30220),ut.tString(30111)]) + ut.tString(30109),ut.tString(30110),ut.tString(30220),ut.tString(30225),ut.tString(30111)]) endDir = False if ret == 0: endDir = do_search("artists") @@ -877,7 +877,7 @@ def Main(): if ampache.getSetting("videos"): addDir(ut.tString(30221) + " (" + ampache.getSetting("videos")+ ")",8,5) if ampache.getSetting("podcasts"): - addDir(ut.tString(30221) + " (" + ampache.getSetting("podcasts")+ ")",8,5) + addDir(ut.tString(30226) + " (" + ampache.getSetting("podcasts")+ ")",8,5) apiVersion = int(ampache.getSetting("api-version")) if apiVersion >= 380001: #get all tags ( submode 5 ) @@ -921,7 +921,7 @@ def Main(): #search video addDir(ut.tString(30222),8,10) #search podcast - #addDir(ut.tString(30222),8,10) + addDir(ut.tString(30227),8,10) #search tags elif mode==54: From 1ba6e79804368a0f1bed9d667f48aefd1fbe75a2 Mon Sep 17 00:00:00 2001 From: lusum Date: Fri, 12 Feb 2021 16:57:53 +0100 Subject: [PATCH 30/40] update translations --- .../resource.language.en_gb/strings.po | 12 ++++++ .../resource.language.it_it/strings.po | 41 ++++++------------- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/resources/language/resource.language.en_gb/strings.po b/resources/language/resource.language.en_gb/strings.po index f8e531f..a7e91ac 100644 --- a/resources/language/resource.language.en_gb/strings.po +++ b/resources/language/resource.language.en_gb/strings.po @@ -465,3 +465,15 @@ msgstr "" msgctxt "#30222" msgid "Search Videos..." msgstr "" + +msgctxt "#30225" +msgid "Podcast" +msgstr "" + +msgctxt "#30226" +msgid "Podcasts" +msgstr "" + +msgctxt "#30227" +msgid "Search Podcasts..." +msgstr "" diff --git a/resources/language/resource.language.it_it/strings.po b/resources/language/resource.language.it_it/strings.po index 70cd990..3ffd121 100644 --- a/resources/language/resource.language.it_it/strings.po +++ b/resources/language/resource.language.it_it/strings.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: XBMC Addons\n" "Report-Msgid-Bugs-To: alanwww1@xbmc.org\n" "POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n" -"PO-Revision-Date: 2021-02-10 17:42+0100\n" +"PO-Revision-Date: 2021-02-12 16:53+0100\n" "Last-Translator: \n" "Language-Team: English (http://www.transifex.com/projects/p/xbmc-addons/" "language/en/)\n" @@ -138,7 +138,7 @@ msgstr "" msgctxt "#30119" msgid "Tags" -msgstr "Genere" +msgstr "Generi" # code msgctxt "#30120" @@ -475,30 +475,15 @@ msgctxt "#30222" msgid "Search Videos..." msgstr "Ricerca video..." +msgctxt "#30225" +msgid "Podcast" +msgstr "" + +msgctxt "#30226" +msgid "Podcasts" +msgstr "" + # code -#, fuzzy -#~| msgctxt "#30122" -#~| msgid "Search Songs..." -#~ msgctxt "#30221" -#~ msgid "Search Videos..." -#~ msgstr "Ricerca canzoni..." - -#~ msgctxt "#30190" -#~ msgid "Recent Artists..." -#~ msgstr "Artisti recenti.." - -#~ msgctxt "#30191" -#~ msgid "Recent Albums..." -#~ msgstr "Album recenti.." - -#~ msgctxt "#30192" -#~ msgid "Recent Songs..." -#~ msgstr "Canzoni recenti..." - -#~ msgctxt "#30193" -#~ msgid "Recent..." -#~ msgstr "Recenti..." - -#~ msgctxt "#30170" -#~ msgid "Enter the Name" -#~ msgstr "Inserisci il nome del server" +msgctxt "#30227" +msgid "Search Podcasts..." +msgstr "Ricerca podcast..." From 7e6a0a06554b60081f0d252f73e719a4c8f23a7b Mon Sep 17 00:00:00 2001 From: lusum Date: Fri, 12 Feb 2021 16:58:55 +0100 Subject: [PATCH 31/40] disable now not working code --- resources/lib/ampache_plugin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 18e6dda..42277af 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -821,7 +821,8 @@ def Main(): endDir = do_search("podcasts") #get all episodes elif submode == 71: - get_items(object_type="songs",object_id=object_id,object_subtype="podcast_episodes") + pass + #get_items(object_type="songs",object_id=object_id,object_subtype="podcast_episodes") #video elif mode==8: From 5f30921a0622a8686fccd9c07b344cf565ff423c Mon Sep 17 00:00:00 2001 From: lusum Date: Fri, 12 Feb 2021 17:00:58 +0100 Subject: [PATCH 32/40] little bug --- resources/lib/ampache_plugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 42277af..01f68c1 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -878,7 +878,7 @@ def Main(): if ampache.getSetting("videos"): addDir(ut.tString(30221) + " (" + ampache.getSetting("videos")+ ")",8,5) if ampache.getSetting("podcasts"): - addDir(ut.tString(30226) + " (" + ampache.getSetting("podcasts")+ ")",8,5) + addDir(ut.tString(30226) + " (" + ampache.getSetting("podcasts") ")",5,5) apiVersion = int(ampache.getSetting("api-version")) if apiVersion >= 380001: #get all tags ( submode 5 ) @@ -922,7 +922,7 @@ def Main(): #search video addDir(ut.tString(30222),8,10) #search podcast - addDir(ut.tString(30227),8,10) + addDir(ut.tString(30227),5,10) #search tags elif mode==54: From f399523da0bf7488c9fe8d879139f4df9e5a880e Mon Sep 17 00:00:00 2001 From: lusum Date: Fri, 12 Feb 2021 17:02:56 +0100 Subject: [PATCH 33/40] little bug --- resources/lib/ampache_plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 01f68c1..b8dddb9 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -878,7 +878,7 @@ def Main(): if ampache.getSetting("videos"): addDir(ut.tString(30221) + " (" + ampache.getSetting("videos")+ ")",8,5) if ampache.getSetting("podcasts"): - addDir(ut.tString(30226) + " (" + ampache.getSetting("podcasts") ")",5,5) + ddDir(ut.tString(30226) + " (" + ampache.getSetting("podcasts")+ ")",5,5) apiVersion = int(ampache.getSetting("api-version")) if apiVersion >= 380001: #get all tags ( submode 5 ) From 8932cdb63f3db4862c4103a6d898b3af958c4094 Mon Sep 17 00:00:00 2001 From: lusum Date: Tue, 16 Feb 2021 16:04:22 +0100 Subject: [PATCH 34/40] add podcast_episodes support, some refactoring --- resources/lib/ampache_plugin.py | 36 ++++++++++++++++++--------------- resources/lib/utils.py | 5 ++--- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index b8dddb9..8ec1a33 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -336,6 +336,8 @@ def addDir(name,mode,submode,offset=None,object_id=None): def addItems( object_type, mode , elem, useCacheArt=True, object_subtype=None): image = "DefaultFolder.png" xbmc.log("AmpachePlugin::addItems: object_type - " + str(object_type) , xbmc.LOGDEBUG ) + if object_subtype: + xbmc.log("AmpachePlugin::addItems: object_subtype - " + str(object_subtype) , xbmc.LOGDEBUG ) if useCacheArt: precacheArt(elem,object_type) @@ -400,34 +402,36 @@ def get_items(object_type, object_id=None, add=None,\ #discriminate between subtypes if object_type == 'albums': if object_subtype == 'artist_albums': - action = 'artist_albums' + action = object_subtype addDir("All Songs",1,72, object_id=object_id) elif object_subtype == 'tag_albums': - action = 'tag_albums' + action = object_subtype elif object_subtype == 'genre_albums': - action = 'genre_albums' + action = object_subtype elif object_subtype == 'album': - action = 'album' + action = object_subtype elif object_type == 'artists': if object_subtype == 'tag_artists': - action = 'tag_artists' + action = object_subtype elif object_subtype == 'genre_artists': - action = 'genre_artists' + action = object_subtype elif object_subtype == 'artist': - action = 'artist' + action = object_subtype elif object_type == 'songs': if object_subtype == 'tag_songs': - action = 'tag_songs' + action = object_subtype elif object_subtype == 'genre_songs': - action = 'genre_songs' + action = object_subtype elif object_subtype == 'playlist_songs': - action = 'playlist_songs' + action = object_subtype elif object_subtype == 'album_songs': - action = 'album_songs' + action = object_subtype elif object_subtype == 'artist_songs': - action = 'artist_songs' + action = object_subtype elif object_subtype == 'search_songs': - action = 'search_songs' + action = object_subtype + elif object_subtype == 'podcast_episodes': + action = object_subtype if object_id: thisFilter = object_id @@ -458,7 +462,7 @@ def get_items(object_type, object_id=None, add=None,\ ampConn.offset = offset elem = ampConn.ampache_http_request(action) - addItems( object_type, mode , elem, useCacheArt) + addItems( object_type, mode , elem, useCacheArt,object_subtype) except: return @@ -821,8 +825,8 @@ def Main(): endDir = do_search("podcasts") #get all episodes elif submode == 71: - pass - #get_items(object_type="songs",object_id=object_id,object_subtype="podcast_episodes") + if(int(ampache.getSetting("api-version"))) > 440000: + get_items(object_type="songs",object_id=object_id,object_subtype="podcast_episodes") #video elif mode==8: diff --git a/resources/lib/utils.py b/resources/lib/utils.py index 7c3e538..82d543e 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -62,10 +62,9 @@ def otype_to_type(object_type,object_subtype=None): elif object_type == 'videos': return 'video' elif object_type == 'songs': - if object_subtype is None: - return 'song' - elif object_subtype == 'podcast_episodes': + if object_subtype == 'podcast_episodes': return 'podcast_episode' + return 'song' return None def int_to_strBool(s): From 720c70f13165df477f83f2177ee04175beea890a Mon Sep 17 00:00:00 2001 From: lusum Date: Tue, 16 Feb 2021 16:36:05 +0100 Subject: [PATCH 35/40] more elegant solution --- resources/lib/ampache_plugin.py | 38 +++++++++++---------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 8ec1a33..e48bdbf 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -398,39 +398,27 @@ def get_items(object_type, object_id=None, add=None,\ #default: object_type is the action,otherwise see the if list below action = object_type + artist_action_subtypes = [ + 'artist_albums','tag_albums','genre_albums','album'] + + album_action_subtypes = [ 'tag_artists','genre_artists','artist'] + + song_action_subtypes = [ 'tag_songs','genre_songs', 'playlist_songs', + 'album_songs', 'artist_songs','search_songs', 'podcast_episodes'] + #do not use action = object_subtype cause in tags it is used only to #discriminate between subtypes if object_type == 'albums': if object_subtype == 'artist_albums': - action = object_subtype addDir("All Songs",1,72, object_id=object_id) - elif object_subtype == 'tag_albums': - action = object_subtype - elif object_subtype == 'genre_albums': - action = object_subtype - elif object_subtype == 'album': + #do not use elif, artist_albums is checked two times + if object_subtype in artist_action_subtypes: action = object_subtype elif object_type == 'artists': - if object_subtype == 'tag_artists': - action = object_subtype - elif object_subtype == 'genre_artists': - action = object_subtype - elif object_subtype == 'artist': + if object_subtype in album_action_subtypes: action = object_subtype elif object_type == 'songs': - if object_subtype == 'tag_songs': - action = object_subtype - elif object_subtype == 'genre_songs': - action = object_subtype - elif object_subtype == 'playlist_songs': - action = object_subtype - elif object_subtype == 'album_songs': - action = object_subtype - elif object_subtype == 'artist_songs': - action = object_subtype - elif object_subtype == 'search_songs': - action = object_subtype - elif object_subtype == 'podcast_episodes': + if object_subtype in song_action_subtypes: action = object_subtype if object_id: @@ -825,7 +813,7 @@ def Main(): endDir = do_search("podcasts") #get all episodes elif submode == 71: - if(int(ampache.getSetting("api-version"))) > 440000: + if(int(ampache.getSetting("api-version"))) >= 440000: get_items(object_type="songs",object_id=object_id,object_subtype="podcast_episodes") #video From 82da0532e03c9261404f41d6123e15b8d16ee438 Mon Sep 17 00:00:00 2001 From: lusum Date: Thu, 18 Feb 2021 21:42:29 +0100 Subject: [PATCH 36/40] update translation --- resources/language/resource.language.it_it/strings.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/language/resource.language.it_it/strings.po b/resources/language/resource.language.it_it/strings.po index 3ffd121..22aaee2 100644 --- a/resources/language/resource.language.it_it/strings.po +++ b/resources/language/resource.language.it_it/strings.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: XBMC Addons\n" "Report-Msgid-Bugs-To: alanwww1@xbmc.org\n" "POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n" -"PO-Revision-Date: 2021-02-12 16:53+0100\n" +"PO-Revision-Date: 2021-02-18 21:42+0100\n" "Last-Translator: \n" "Language-Team: English (http://www.transifex.com/projects/p/xbmc-addons/" "language/en/)\n" @@ -428,7 +428,7 @@ msgstr "Album suonati recentemente..." msgctxt "#30192" msgid "Recently Played Songs..." -msgstr "Canzoni suonati recentemente..." +msgstr "Canzoni suonate recentemente..." msgctxt "#30193" msgid "Recently Played..." From 7f0a484102c3cb9499f6ff446eff28d55869bb9c Mon Sep 17 00:00:00 2001 From: lusum Date: Fri, 19 Feb 2021 19:40:14 +0100 Subject: [PATCH 37/40] fix --- resources/lib/ampache_plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index e48bdbf..eb24ee8 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -870,7 +870,7 @@ def Main(): if ampache.getSetting("videos"): addDir(ut.tString(30221) + " (" + ampache.getSetting("videos")+ ")",8,5) if ampache.getSetting("podcasts"): - ddDir(ut.tString(30226) + " (" + ampache.getSetting("podcasts")+ ")",5,5) + addDir(ut.tString(30226) + " (" + ampache.getSetting("podcasts")+ ")",5,5) apiVersion = int(ampache.getSetting("api-version")) if apiVersion >= 380001: #get all tags ( submode 5 ) From aa17b879e76a6161da997e3931bb8ce8024cc985 Mon Sep 17 00:00:00 2001 From: lusum Date: Wed, 3 Mar 2021 16:42:44 +0100 Subject: [PATCH 38/40] add sort method for movies and podcast episodes --- resources/lib/ampache_plugin.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index eb24ee8..380a907 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -291,9 +291,14 @@ def addPlayLinks(elem, object_type , object_subtype=None): if cm != []: liz.addContextMenuItems(cm) + #we don't use sort method for track cause songs are already sorted + #by the server and it make a mess in random playlists elif elem_type == "video": liz.setInfo( type="video", infoLabels=get_infolabels("videos", node) ) liz.setMimeType(node.findtext("mime")) + xbmcplugin.addSortMethod(int(sys.argv[1]),xbmcplugin.SORT_METHOD_TITLE) + elif elem_type == "podcast_episode": + xbmcplugin.addSortMethod(int(sys.argv[1]),xbmcplugin.SORT_METHOD_TITLE) track_parameters = { "mode": 200, "play_url" : play_url} url = sys.argv[0] + '?' + urllib.parse.urlencode(track_parameters) From a3864cbd8f81506b41db710b627860970e43b319 Mon Sep 17 00:00:00 2001 From: lusum Date: Wed, 3 Mar 2021 17:06:39 +0100 Subject: [PATCH 39/40] better, test only one time, use label for podcasts --- resources/lib/ampache_plugin.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 380a907..14b9e78 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -246,6 +246,13 @@ def addPlayLinks(elem, object_type , object_subtype=None): elem_type = ut.otype_to_type(object_type,object_subtype) + #we don't use sort method for track cause songs are already sorted + #by the server and it make a mess in random playlists + if elem_type == "video": + xbmcplugin.addSortMethod(int(sys.argv[1]),xbmcplugin.SORT_METHOD_TITLE) + elif elem_type == "podcast_episode": + xbmcplugin.addSortMethod(int(sys.argv[1]),xbmcplugin.SORT_METHOD_LABEL) + for node in elem.iter(elem_type): object_id = node.attrib["id"] if object_id is None or object_id == "": @@ -291,14 +298,9 @@ def addPlayLinks(elem, object_type , object_subtype=None): if cm != []: liz.addContextMenuItems(cm) - #we don't use sort method for track cause songs are already sorted - #by the server and it make a mess in random playlists elif elem_type == "video": liz.setInfo( type="video", infoLabels=get_infolabels("videos", node) ) liz.setMimeType(node.findtext("mime")) - xbmcplugin.addSortMethod(int(sys.argv[1]),xbmcplugin.SORT_METHOD_TITLE) - elif elem_type == "podcast_episode": - xbmcplugin.addSortMethod(int(sys.argv[1]),xbmcplugin.SORT_METHOD_TITLE) track_parameters = { "mode": 200, "play_url" : play_url} url = sys.argv[0] + '?' + urllib.parse.urlencode(track_parameters) From 296f34343410f924c95fa2bcc490887e91b2e23d Mon Sep 17 00:00:00 2001 From: lusum Date: Sun, 14 Mar 2021 21:28:01 +0100 Subject: [PATCH 40/40] raise limit to 500 --- resources/lib/ampache_plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/ampache_plugin.py b/resources/lib/ampache_plugin.py index 14b9e78..20694d8 100644 --- a/resources/lib/ampache_plugin.py +++ b/resources/lib/ampache_plugin.py @@ -363,7 +363,7 @@ def get_all(object_type, mode ,offset=None): except: return #to not overload servers - step = 100 + step = 500 newLimit = offset+step #load images in long list if (ut.strBool_to_bool(ampache.getSetting("images-long-list"))):