Compare commits
	
		
			6 Commits
		
	
	
		
			radio
			...
			leia-compa
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f6792e02aa | |||
| 2ae13c655e | |||
| fc49f29fae | |||
| 670bf0107b | |||
| 18f736d60d | |||
| f62f2b2236 | 
| @ -1,5 +1,8 @@ | |||||||
| # Changelog | # Changelog | ||||||
|  |  | ||||||
|  | ## v2.1.0 | ||||||
|  | Backport v3.0.2 to Kodi Leia for testing | ||||||
|  |  | ||||||
| ## v3.0.2 | ## v3.0.2 | ||||||
| Released 29th September 2021 (by warwickh) | Released 29th September 2021 (by warwickh) | ||||||
| * Removed dependency on future and dateutil  | * Removed dependency on future and dateutil  | ||||||
|  | |||||||
| @ -27,6 +27,7 @@ From GitHub | |||||||
| * Enable unknown sources and install from zip in Kodi | * Enable unknown sources and install from zip in Kodi | ||||||
|   |   | ||||||
| or | or | ||||||
|  |  | ||||||
| * Navigate to your `.kodi/addons/` folder | * Navigate to your `.kodi/addons/` folder | ||||||
| * Clone this repository: `git clone https://github.com/warwickh/plugin.audio.subsonic.git` | * Clone this repository: `git clone https://github.com/warwickh/plugin.audio.subsonic.git` | ||||||
| * (Re)start Kodi. | * (Re)start Kodi. | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8" standalone="yes"?> | <?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||||||
| <addon id="plugin.audio.subsonic" name="Subsonic" version="3.0.2" provider-name="BasilFX,warwickh"> | <addon id="plugin.audio.subsonic" name="Subsonic" version="2.1.0" provider-name="BasilFX,warwickh"> | ||||||
|     <requires> |     <requires> | ||||||
|         <import addon="xbmc.python" version="3.0.0"/> |         <import addon="xbmc.python" version="2.7.0"/> | ||||||
|     </requires> |     </requires> | ||||||
|     <extension point="xbmc.python.pluginsource" library="main.py"> |     <extension point="xbmc.python.pluginsource" library="main.py"> | ||||||
|         <provides>audio</provides> |         <provides>audio</provides> | ||||||
|  | |||||||
| @ -18,11 +18,10 @@ along with py-sonic.  If not, see <http://www.gnu.org/licenses/> | |||||||
| from libsonic.errors import * | from libsonic.errors import * | ||||||
| from netrc import netrc | from netrc import netrc | ||||||
| from hashlib import md5 | from hashlib import md5 | ||||||
| import urllib.request | import urllib2 | ||||||
| import urllib.error | import httplib | ||||||
| import urllib.parse | import urlparse | ||||||
| from http import client as http_client | from urllib import urlencode | ||||||
| from urllib.parse import urlencode |  | ||||||
| from io import StringIO | from io import StringIO | ||||||
|  |  | ||||||
| import json | import json | ||||||
| @ -37,7 +36,7 @@ API_VERSION = '1.16.1' | |||||||
|  |  | ||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
|  |  | ||||||
| class HTTPSConnectionChain(http_client.HTTPSConnection): | class HTTPSConnectionChain(httplib.HTTPSConnection): | ||||||
|     def _create_sock(self): |     def _create_sock(self): | ||||||
|         sock = socket.create_connection((self.host, self.port), self.timeout) |         sock = socket.create_connection((self.host, self.port), self.timeout) | ||||||
|         if self._tunnel_host: |         if self._tunnel_host: | ||||||
| @ -53,14 +52,14 @@ class HTTPSConnectionChain(http_client.HTTPSConnection): | |||||||
|         except: |         except: | ||||||
|             sock.close() |             sock.close() | ||||||
|  |  | ||||||
| class HTTPSHandlerChain(urllib.request.HTTPSHandler): | class HTTPSHandlerChain(urllib2.HTTPSHandler): | ||||||
|     def https_open(self, req): |     def https_open(self, req): | ||||||
|         return self.do_open(HTTPSConnectionChain, req, context=self._context) |         return self.do_open(HTTPSConnectionChain, req, context=self._context) | ||||||
|  |  | ||||||
| # install opener | # install opener | ||||||
| urllib.request.install_opener(urllib.request.build_opener(HTTPSHandlerChain())) | urllib2.install_opener(urllib2.build_opener(HTTPSHandlerChain())) | ||||||
|  |  | ||||||
| class PysHTTPRedirectHandler(urllib.request.HTTPRedirectHandler): | class PysHTTPRedirectHandler(urllib2.HTTPRedirectHandler): | ||||||
|     """ |     """ | ||||||
|     This class is used to override the default behavior of the |     This class is used to override the default behavior of the | ||||||
|     HTTPRedirectHandler, which does *not* redirect POST data |     HTTPRedirectHandler, which does *not* redirect POST data | ||||||
| @ -76,7 +75,7 @@ class PysHTTPRedirectHandler(urllib.request.HTTPRedirectHandler): | |||||||
|             data = None |             data = None | ||||||
|             if req.data: |             if req.data: | ||||||
|                 data = req.data |                 data = req.data | ||||||
|             return urllib.request.Request(newurl, |             return urllib2.Request(newurl, | ||||||
|                            data=data, |                            data=data, | ||||||
|                            headers=newheaders, |                            headers=newheaders, | ||||||
|                            origin_req_host=req.origin_req_host, |                            origin_req_host=req.origin_req_host, | ||||||
| @ -161,7 +160,7 @@ class Connection(object): | |||||||
|         if len(self._hostname.split('/'))>1: |         if len(self._hostname.split('/'))>1: | ||||||
|             print(len(self._hostname.split('/'))) |             print(len(self._hostname.split('/'))) | ||||||
|             xbmc.log("Got a folder %s"%(self._hostname.split('/')[1]),xbmc.LOGDEBUG) |             xbmc.log("Got a folder %s"%(self._hostname.split('/')[1]),xbmc.LOGDEBUG) | ||||||
|             parts = urllib.parse.urlparse(self._baseUrl) |             parts = urlparse.urlparse(self._baseUrl) | ||||||
|             self._baseUrl = "%s://%s" % (parts.scheme, parts.hostname) |             self._baseUrl = "%s://%s" % (parts.scheme, parts.hostname) | ||||||
|             self._hostname = parts.hostname |             self._hostname = parts.hostname | ||||||
|             self._serverPath = parts.path.strip('/') + '/rest' |             self._serverPath = parts.path.strip('/') + '/rest' | ||||||
| @ -240,7 +239,8 @@ class Connection(object): | |||||||
|         viewName = '%s.view' % methodName |         viewName = '%s.view' % methodName | ||||||
|  |  | ||||||
|         req = self._getRequest(viewName) |         req = self._getRequest(viewName) | ||||||
|         xbmc.log("Pinging %s"%str(req.full_url),xbmc.LOGDEBUG)        |         xbmc.log("Pinging %s"%str(req.get_full_url()),xbmc.LOGDEBUG)        | ||||||
|  |         #res = self._doInfoReq(req) | ||||||
|         try: |         try: | ||||||
|             res = self._doInfoReq(req) |             res = self._doInfoReq(req) | ||||||
|         except Exception as e: |         except Exception as e: | ||||||
| @ -906,8 +906,8 @@ class Connection(object): | |||||||
|             'converted': converted}) |             'converted': converted}) | ||||||
|  |  | ||||||
|         req = self._getRequest(viewName, q) |         req = self._getRequest(viewName, q) | ||||||
|         #xbmc.log("Requesting %s"%str(req.full_url),xbmc.LOGDEBUG) |         #xbmc.log("Requesting %s"%str(req.get_full_url()),xbmc.LOGDEBUG) | ||||||
|         return_url = req.full_url |         return_url = req.get_full_url() | ||||||
|         if self._insecure: |         if self._insecure: | ||||||
|             return_url += '&verifypeer=false' |             return_url += '&verifypeer=false' | ||||||
|             xbmc.log("Request is insecure %s"%return_url,level=xbmc.LOGDEBUG)    |             xbmc.log("Request is insecure %s"%return_url,level=xbmc.LOGDEBUG)    | ||||||
| @ -955,8 +955,8 @@ class Connection(object): | |||||||
|         q = self._getQueryDict({'id': aid, 'size': size}) |         q = self._getQueryDict({'id': aid, 'size': size}) | ||||||
|  |  | ||||||
|         req = self._getRequest(viewName, q) |         req = self._getRequest(viewName, q) | ||||||
|         #xbmc.log("Requesting %s"%str(req.full_url),xbmc.LOGDEBUG) |         #xbmc.log("Requesting %s"%str(req.get_full_url()),xbmc.LOGDEBUG) | ||||||
|         return_url = req.full_url |         return_url = req.get_full_url() | ||||||
|         if self._insecure: |         if self._insecure: | ||||||
|             return_url += '&verifypeer=false' |             return_url += '&verifypeer=false' | ||||||
|             xbmc.log("Request is insecure %s"%return_url,level=xbmc.LOGDEBUG)    |             xbmc.log("Request is insecure %s"%return_url,level=xbmc.LOGDEBUG)    | ||||||
| @ -2007,7 +2007,7 @@ class Connection(object): | |||||||
|             q['musicFolderId'] = musicFolderId |             q['musicFolderId'] = musicFolderId | ||||||
|  |  | ||||||
|         req = self._getRequest(viewName, q) |         req = self._getRequest(viewName, q) | ||||||
|         xbmc.log("Requesting %s"%str(req.full_url),xbmc.LOGDEBUG)         |         xbmc.log("Requesting %s"%str(req.get_full_url()),xbmc.LOGDEBUG)         | ||||||
|         res = self._doInfoReq(req) |         res = self._doInfoReq(req) | ||||||
|         self._checkStatus(res) |         self._checkStatus(res) | ||||||
|         return res |         return res | ||||||
| @ -2765,7 +2765,7 @@ class Connection(object): | |||||||
|  |  | ||||||
|         url = '%s:%d/%s/%s?%s' % (self._baseUrl, self._port, |         url = '%s:%d/%s/%s?%s' % (self._baseUrl, self._port, | ||||||
|             self._separateServerPath(), viewName, methodName) |             self._separateServerPath(), viewName, methodName) | ||||||
|         req = urllib.request.Request(url) |         req = urllib2.Request(url) | ||||||
|         res = self._opener.open(req) |         res = self._opener.open(req) | ||||||
|         res_msg = res.msg.lower() |         res_msg = res.msg.lower() | ||||||
|         return res_msg == 'ok' |         return res_msg == 'ok' | ||||||
| @ -2779,7 +2779,7 @@ class Connection(object): | |||||||
|         if sys.version_info[:3] >= (2, 7, 9) and self._insecure: |         if sys.version_info[:3] >= (2, 7, 9) and self._insecure: | ||||||
|             https_chain = HTTPSHandlerChain( |             https_chain = HTTPSHandlerChain( | ||||||
|                 context=ssl._create_unverified_context()) |                 context=ssl._create_unverified_context()) | ||||||
|         opener = urllib.request.build_opener( |         opener = urllib2.build_opener( | ||||||
|             PysHTTPRedirectHandler, |             PysHTTPRedirectHandler, | ||||||
|             https_chain, |             https_chain, | ||||||
|         ) |         ) | ||||||
| @ -2821,11 +2821,11 @@ class Connection(object): | |||||||
|             viewName) |             viewName) | ||||||
|         #xbmc.log("Standard URL %s"%url,level=xbmc.LOGDEBUG) |         #xbmc.log("Standard URL %s"%url,level=xbmc.LOGDEBUG) | ||||||
|         #xbmc.log("Qdict %s"%str(qdict),level=xbmc.LOGDEBUG) |         #xbmc.log("Qdict %s"%str(qdict),level=xbmc.LOGDEBUG) | ||||||
|         req = urllib.request.Request(url, urlencode(qdict).encode('utf-8')) |         req = urllib2.Request(url, urlencode(qdict).encode('utf-8')) | ||||||
|         if(self._useGET or ('getCoverArt' in viewName) or ('stream' in viewName)): |         if(self._useGET or ('getCoverArt' in viewName) or ('stream' in viewName)): | ||||||
|             url += '?%s' % urlencode(qdict) |             url += '?%s' % urlencode(qdict) | ||||||
|             #xbmc.log("UseGET URL %s"%(url),xbmc.LOGDEBUG) |             #xbmc.log("UseGET URL %s"%(url),xbmc.LOGDEBUG) | ||||||
|             req = urllib.request.Request(url) |             req = urllib2.Request(url) | ||||||
|         return req |         return req | ||||||
|  |  | ||||||
|     def _getRequestWithList(self, viewName, listName, alist, query={}): |     def _getRequestWithList(self, viewName, listName, alist, query={}): | ||||||
| @ -2841,7 +2841,7 @@ class Connection(object): | |||||||
|         data.write(urlencode(qdict)) |         data.write(urlencode(qdict)) | ||||||
|         for i in alist: |         for i in alist: | ||||||
|             data.write('&%s' % urlencode({listName: i})) |             data.write('&%s' % urlencode({listName: i})) | ||||||
|         req = urllib.request.Request(url, data.getvalue().encode('utf-8')) |         req = urllib2.Request(url, data.getvalue().encode('utf-8')) | ||||||
|  |  | ||||||
|         if self._useGET: |         if self._useGET: | ||||||
|             url += '?%s' % data.getvalue() |             url += '?%s' % data.getvalue() | ||||||
| @ -2868,7 +2868,7 @@ class Connection(object): | |||||||
|         for k, l in listMap.items(): |         for k, l in listMap.items(): | ||||||
|             for i in l: |             for i in l: | ||||||
|                 data.write('&%s' % urlencode({k: i})) |                 data.write('&%s' % urlencode({k: i})) | ||||||
|         req = urllib.request.Request(url, data.getvalue().encode('utf-8')) |         req = urllib2.Request(url, data.getvalue().encode('utf-8')) | ||||||
|  |  | ||||||
|         if self._useGET: |         if self._useGET: | ||||||
|             url += '?%s' % data.getvalue() |             url += '?%s' % data.getvalue() | ||||||
| @ -2929,7 +2929,7 @@ class Connection(object): | |||||||
|         """ |         """ | ||||||
|         separate REST portion of URL from base server path. |         separate REST portion of URL from base server path. | ||||||
|         """ |         """ | ||||||
|         return urllib.parse.splithost(self._serverPath)[1].split('/')[0] |         return urlparse.splithost(self._serverPath)[1].split('/')[0] | ||||||
|  |  | ||||||
|     def _fixLastModified(self, data): |     def _fixLastModified(self, data): | ||||||
|         """ |         """ | ||||||
|  | |||||||
| @ -19,7 +19,7 @@ import inspect | |||||||
| import time | import time | ||||||
| import hashlib | import hashlib | ||||||
| import pickle | import pickle | ||||||
| from collections.abc import MutableMapping | from collections import MutableMapping | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| from copy import deepcopy | from copy import deepcopy | ||||||
| from functools import wraps | from functools import wraps | ||||||
| @ -27,7 +27,9 @@ from shutil import copyfile | |||||||
| from contextlib import contextmanager | from contextlib import contextmanager | ||||||
| from pprint import pformat | from pprint import pformat | ||||||
| from platform import uname | from platform import uname | ||||||
| from urllib.parse import urlencode, quote_plus, urlparse, unquote_plus, parse_qs | #from urllib.parse import urlencode, quote_plus, urlparse, unquote_plus, parse_qs | ||||||
|  | from urlparse import parse_qs | ||||||
|  | from urllib import urlencode | ||||||
| import xbmcaddon | import xbmcaddon | ||||||
| import xbmc | import xbmc | ||||||
| import xbmcgui | import xbmcgui | ||||||
| @ -36,7 +38,7 @@ import xbmcvfs | |||||||
| __all__ = ['SimplePluginError', 'Storage', 'MemStorage', 'Addon', 'Plugin', | __all__ = ['SimplePluginError', 'Storage', 'MemStorage', 'Addon', 'Plugin', | ||||||
|            'RoutedPlugin', 'Params', 'log_exception', 'translate_path'] |            'RoutedPlugin', 'Params', 'log_exception', 'translate_path'] | ||||||
|  |  | ||||||
| getargspec = inspect.getfullargspec | getargspec = inspect.getargspec | ||||||
|  |  | ||||||
| Route = namedtuple('Route', ['pattern', 'func']) | Route = namedtuple('Route', ['pattern', 'func']) | ||||||
|  |  | ||||||
| @ -1086,7 +1088,6 @@ class Plugin(Addon): | |||||||
|                     return action_callable(self._params) |                     return action_callable(self._params) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class RoutedPlugin(Plugin): | class RoutedPlugin(Plugin): | ||||||
|     """ |     """ | ||||||
|     Plugin class that implements "pretty URL" routing similar to Flask and Bottle |     Plugin class that implements "pretty URL" routing similar to Flask and Bottle | ||||||
|  | |||||||
							
								
								
									
										90
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										90
									
								
								main.py
									
									
									
									
									
								
							| @ -12,11 +12,11 @@ import time | |||||||
| import hashlib | import hashlib | ||||||
| import random | import random | ||||||
| from datetime import datetime | from datetime import datetime | ||||||
| from collections.abc import MutableMapping | from collections import MutableMapping | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
|  |  | ||||||
| # Add the /lib folder to sys | # Add the /lib folder to sys | ||||||
| sys.path.append(xbmcvfs.translatePath(os.path.join(xbmcaddon.Addon("plugin.audio.subsonic").getAddonInfo("path"), "lib"))) | sys.path.append(xbmc.translatePath(os.path.join(xbmcaddon.Addon("plugin.audio.subsonic").getAddonInfo("path"), "lib"))) | ||||||
|  |  | ||||||
| import libsonic | import libsonic | ||||||
|  |  | ||||||
| @ -61,6 +61,7 @@ def get_connection(): | |||||||
|  |  | ||||||
|         if connected==False: |         if connected==False: | ||||||
|             popup('Connection error') |             popup('Connection error') | ||||||
|  | 	    plugin.log('Connection error') | ||||||
|             return False |             return False | ||||||
|  |  | ||||||
|     return connection |     return connection | ||||||
| @ -112,11 +113,6 @@ def root(params): | |||||||
|             'callback': 'search_album', |             'callback': 'search_album', | ||||||
|             'thumb': None |             'thumb': None | ||||||
|         },   |         },   | ||||||
|         'radio': { |  | ||||||
|             'name':     Addon().get_localized_string(30046), |  | ||||||
|             'callback': 'browse_radio', |  | ||||||
|             'thumb': None |  | ||||||
|         },   |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     # Iterate through categories |     # Iterate through categories | ||||||
| @ -248,31 +244,6 @@ def menu_tracks(params): | |||||||
|         listing, |         listing, | ||||||
|     )) |     )) | ||||||
|  |  | ||||||
| @plugin.action() |  | ||||||
| def browse_radio(params): |  | ||||||
|     # get connection |  | ||||||
|     connection = get_connection() |  | ||||||
|      |  | ||||||
|     if connection==False: |  | ||||||
|         return |  | ||||||
|  |  | ||||||
|     listing = [] |  | ||||||
|  |  | ||||||
|     # Get items |  | ||||||
|     items = walk_radio() |  | ||||||
|  |  | ||||||
|     # Iterate through items |  | ||||||
|     for item in items: |  | ||||||
|         print(item) |  | ||||||
|         entry = get_entry_radio(item,params) |  | ||||||
|         listing.append(entry) |  | ||||||
|          |  | ||||||
|     add_directory_items(create_listing( |  | ||||||
|         listing, |  | ||||||
|         sort_methods = get_sort_methods('playlists',params), #he list of integer constants representing virtual folder sort methods. |  | ||||||
|     )) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @plugin.action() | @plugin.action() | ||||||
| def browse_folders(params): | def browse_folders(params): | ||||||
|     # get connection |     # get connection | ||||||
| @ -910,17 +881,6 @@ def get_entry_album(item, params): | |||||||
|  |  | ||||||
|     return entry |     return entry | ||||||
|  |  | ||||||
| def get_entry_radio(item,params): |  | ||||||
|     menu_id = params.get('menu_id') |  | ||||||
|     entry = { |  | ||||||
|         'label':    item.get('name'), |  | ||||||
|         'url':      item.get('streamUrl'), |  | ||||||
|         'is_playable':  True |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     return entry |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def get_entry_track(item,params): | def get_entry_track(item,params): | ||||||
|     menu_id = params.get('menu_id') |     menu_id = params.get('menu_id') | ||||||
|     image = connection.getCoverArtUrl(item.get('coverArt')) |     image = connection.getCoverArtUrl(item.get('coverArt')) | ||||||
| @ -1453,7 +1413,8 @@ def walk_index(folder_id=None): | |||||||
|                 plugin.log("artist: %s"%artist) |                 plugin.log("artist: %s"%artist) | ||||||
|                 yield artist |                 yield artist | ||||||
|     except KeyError: |     except KeyError: | ||||||
|         yield from ()             |         for emp in (): | ||||||
|  | 		yield emp             | ||||||
|  |  | ||||||
| def walk_playlists(): | def walk_playlists(): | ||||||
|     """ |     """ | ||||||
| @ -1464,7 +1425,8 @@ def walk_playlists(): | |||||||
|         for child in response["playlists"]["playlist"]: |         for child in response["playlists"]["playlist"]: | ||||||
|             yield child |             yield child | ||||||
|     except KeyError: |     except KeyError: | ||||||
|         yield from () |         for emp in (): | ||||||
|  | 		yield emp  | ||||||
|  |  | ||||||
| def walk_playlist(playlist_id): | def walk_playlist(playlist_id): | ||||||
|     """ |     """ | ||||||
| @ -1475,7 +1437,8 @@ def walk_playlist(playlist_id): | |||||||
|         for child in response["playlist"]["entry"]: |         for child in response["playlist"]["entry"]: | ||||||
|             yield child |             yield child | ||||||
|     except KeyError: |     except KeyError: | ||||||
|         yield from () |         for emp in (): | ||||||
|  | 		yield emp  | ||||||
|  |  | ||||||
| def walk_folders(): | def walk_folders(): | ||||||
|     response = connection.getMusicFolders() |     response = connection.getMusicFolders() | ||||||
| @ -1483,7 +1446,8 @@ def walk_folders(): | |||||||
|         for child in response["musicFolders"]["musicFolder"]: |         for child in response["musicFolders"]["musicFolder"]: | ||||||
|             yield child |             yield child | ||||||
|     except KeyError: |     except KeyError: | ||||||
|         yield from () |         for emp in (): | ||||||
|  | 		yield emp  | ||||||
|  |  | ||||||
| def walk_directory(directory_id, merge_artist = True): | def walk_directory(directory_id, merge_artist = True): | ||||||
|     """ |     """ | ||||||
| @ -1499,7 +1463,8 @@ def walk_directory(directory_id, merge_artist = True): | |||||||
|             else: |             else: | ||||||
|                 yield child |                 yield child | ||||||
|     except KeyError: |     except KeyError: | ||||||
|         yield from () |         for emp in (): | ||||||
|  | 		yield emp  | ||||||
|  |  | ||||||
| def walk_artist(artist_id): | def walk_artist(artist_id): | ||||||
|     """ |     """ | ||||||
| @ -1511,7 +1476,8 @@ def walk_artist(artist_id): | |||||||
|         for child in response["artist"]["album"]: |         for child in response["artist"]["album"]: | ||||||
|             yield child |             yield child | ||||||
|     except KeyError: |     except KeyError: | ||||||
|         yield from () |         for emp in (): | ||||||
|  | 		yield emp  | ||||||
|  |  | ||||||
| def walk_artists(): | def walk_artists(): | ||||||
|     """ |     """ | ||||||
| @ -1524,7 +1490,8 @@ def walk_artists(): | |||||||
|             for artist in index["artist"]: |             for artist in index["artist"]: | ||||||
|                 yield artist |                 yield artist | ||||||
|     except KeyError: |     except KeyError: | ||||||
|         yield from () |         for emp in (): | ||||||
|  | 		yield emp  | ||||||
|  |  | ||||||
| def walk_genres(): | def walk_genres(): | ||||||
|     """ |     """ | ||||||
| @ -1536,7 +1503,8 @@ def walk_genres(): | |||||||
|         for genre in response["genres"]["genre"]: |         for genre in response["genres"]["genre"]: | ||||||
|             yield genre |             yield genre | ||||||
|     except KeyError: |     except KeyError: | ||||||
|         yield from () |         for emp in (): | ||||||
|  | 		yield emp  | ||||||
|  |  | ||||||
| def walk_albums(ltype, size=None, fromYear=None,toYear=None, genre=None, offset=None): | def walk_albums(ltype, size=None, fromYear=None,toYear=None, genre=None, offset=None): | ||||||
|     """ |     """ | ||||||
| @ -1570,7 +1538,8 @@ def walk_album(album_id): | |||||||
|         for song in response["album"]["song"]: |         for song in response["album"]["song"]: | ||||||
|             yield song |             yield song | ||||||
|     except KeyError: |     except KeyError: | ||||||
|         yield from () |         for emp in (): | ||||||
|  | 		yield emp | ||||||
|  |  | ||||||
| def walk_tracks_random(size=None, genre=None, fromYear=None,toYear=None): | def walk_tracks_random(size=None, genre=None, fromYear=None,toYear=None): | ||||||
|     """ |     """ | ||||||
| @ -1582,18 +1551,8 @@ def walk_tracks_random(size=None, genre=None, fromYear=None,toYear=None): | |||||||
|         for song in response["randomSongs"]["song"]: |         for song in response["randomSongs"]["song"]: | ||||||
|             yield song |             yield song | ||||||
|     except KeyError: |     except KeyError: | ||||||
|         yield from ()         |         for emp in (): | ||||||
|  | 		yield emp        | ||||||
| def walk_radio(): |  | ||||||
|     """ |  | ||||||
|     Request Subsonic's radio stations and iterate over each item. |  | ||||||
|     """ |  | ||||||
|     response = connection.getInternetRadioStations() |  | ||||||
|     try: |  | ||||||
|         for station in response["internetRadioStations"]["internetRadioStation"]: |  | ||||||
|             yield station |  | ||||||
|     except KeyError: |  | ||||||
|         yield from () |  | ||||||
|  |  | ||||||
| def walk_tracks_starred(): | def walk_tracks_starred(): | ||||||
|     """ |     """ | ||||||
| @ -1604,7 +1563,8 @@ def walk_tracks_starred(): | |||||||
|         for song in response["starred"]["song"]: |         for song in response["starred"]["song"]: | ||||||
|             yield song |             yield song | ||||||
|     except KeyError: |     except KeyError: | ||||||
|         yield from () |         for emp in (): | ||||||
|  | 		yield emp  | ||||||
|  |  | ||||||
| # Start plugin from within Kodi. | # Start plugin from within Kodi. | ||||||
| if __name__ == "__main__": | if __name__ == "__main__": | ||||||
|  | |||||||
| @ -180,7 +180,3 @@ msgstr "" | |||||||
| msgctxt "#30045" | msgctxt "#30045" | ||||||
| msgid "Search Albums" | msgid "Search Albums" | ||||||
| msgstr "" | msgstr "" | ||||||
|  |  | ||||||
| msgctxt "#30046" |  | ||||||
| msgid "Radio" |  | ||||||
| msgstr "Radio" |  | ||||||
|  | |||||||
| @ -180,7 +180,3 @@ msgstr "" | |||||||
| msgctxt "#30045" | msgctxt "#30045" | ||||||
| msgid "Search Albums" | msgid "Search Albums" | ||||||
| msgstr "Rechercher Albums" | msgstr "Rechercher Albums" | ||||||
|  |  | ||||||
| msgctxt "#30046" |  | ||||||
| msgid "Radio" |  | ||||||
| msgstr "Radio" |  | ||||||
|  | |||||||
| @ -179,7 +179,3 @@ msgstr "" | |||||||
| msgctxt "#30045" | msgctxt "#30045" | ||||||
| msgid "Search Albums" | msgid "Search Albums" | ||||||
| msgstr "Suche Albums" | msgstr "Suche Albums" | ||||||
|  |  | ||||||
| msgctxt "#30046" |  | ||||||
| msgid "Radio" |  | ||||||
| msgstr "Radio" |  | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ import xbmcvfs | |||||||
| import os | import os | ||||||
| import xbmcaddon | import xbmcaddon | ||||||
| # Add the /lib folder to sys | # Add the /lib folder to sys | ||||||
| sys.path.append(xbmcvfs.translatePath(os.path.join(xbmcaddon.Addon("plugin.audio.subsonic").getAddonInfo("path"), "lib"))) | sys.path.append(xbmc.translatePath(os.path.join(xbmcaddon.Addon("plugin.audio.subsonic").getAddonInfo("path"), "lib"))) | ||||||
|  |  | ||||||
| import libsonic | import libsonic | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	