* New setting 'albums_per_page'

* New menu structure
* Albums : Newest / Most played / Rencently played / by Genre
* Tracks : Starred / Random by genre / Random by year
* Code cleanup
This commit is contained in:
gordielachance 2016-09-20 16:26:32 +02:00
parent 2580050353
commit 7be23bfd8d
5 changed files with 183 additions and 99 deletions

View File

@ -1,5 +1,13 @@
# Changelog # Changelog
## v2.0.1
* New setting 'albums_per_page'
* New menu structure
* Albums : Newest / Most played / Rencently played / by Genre
* Tracks : Starred / Random by genre / Random by year
* Upgraded: libsonic to v.0.5.0 (https://github.com/crustymonkey/py-sonic)
* Code cleanup
## v2.0.0 ## v2.0.0
Released 14 September 2015 Released 14 September 2015

205
addon.py
View File

@ -9,7 +9,7 @@ import xbmcaddon
import xbmcplugin import xbmcplugin
# Make sure library folder is on the path # Make sure library folder is on the path
addon = xbmcaddon.Addon("plugin.audio.subsonic") addon = xbmcaddon.Addon()
sys.path.append(xbmc.translatePath(os.path.join( sys.path.append(xbmc.translatePath(os.path.join(
addon.getAddonInfo("path"), "lib"))) addon.getAddonInfo("path"), "lib")))
@ -31,8 +31,9 @@ class Plugin(object):
self.username = addon.getSetting("username") self.username = addon.getSetting("username")
self.password = addon.getSetting("password") self.password = addon.getSetting("password")
self.random_count = int(addon.getSetting("random_count")) self.albums_per_page = int(addon.getSetting("albums_per_page"))
self.album_list_size = int(addon.getSetting("album_list_size")) self.tracks_per_page = int(addon.getSetting("tracks_per_page"))
self.bitrate = int(addon.getSetting("bitrate")) self.bitrate = int(addon.getSetting("bitrate"))
self.transcode_format = addon.getSetting("transcode_format") self.transcode_format = addon.getSetting("transcode_format")
@ -56,7 +57,7 @@ class Plugin(object):
parameter and executed the function in this instance with that name. parameter and executed the function in this instance with that name.
""" """
mode = self.addon_args.get("mode", ["main_page"])[0] mode = self.addon_args.get("mode", ["main_menu"])[0]
if not mode.startswith("_"): if not mode.startswith("_"):
getattr(self, mode)() getattr(self, mode)()
@ -145,18 +146,17 @@ class Plugin(object):
xbmcplugin.addDirectoryItem( xbmcplugin.addDirectoryItem(
handle=self.addon_handle, url=url, listitem=li, isFolder=True) handle=self.addon_handle, url=url, listitem=li, isFolder=True)
def main_page(self): def main_menu(self):
""" """
Display main menu. Display main menu.
""" """
menu = [ menu = [
{"mode": "starred_list", "foldername": "Starred"}, {"mode": "list_artists", "foldername": "Artists"},
{"mode": "playlists_list", "foldername": "Playlists"}, {"mode": "menu_albums", "foldername": "Albums"},
{"mode": "artist_list", "foldername": "Artists"}, {"mode": "list_playlists", "foldername": "Playlists"},
{"mode": "newest_albums_list", "foldername": "Recently Added Albums"}, {"mode": "menu_tracks", "foldername": "Tracks"}
{"mode": "genre_list", "foldername": "Genres"}, ]
{"mode": "random_list", "foldername": "Random songs"}]
for entry in menu: for entry in menu:
url = self.build_url(entry) url = self.build_url(entry)
@ -167,19 +167,48 @@ class Plugin(object):
xbmcplugin.endOfDirectory(self.addon_handle) xbmcplugin.endOfDirectory(self.addon_handle)
def starred_list(self): def menu_tracks(self):
""" """
Display starred songs. Display main menu.
""" """
xbmcplugin.setContent(self.addon_handle, "songs") menu = [
{"mode": "list_tracks_starred", "foldername": "Starred tracks"},
{"mode": "list_tracks_random_genre", "foldername": "Random tracks by genre"},
{"mode": "list_tracks_random_year", "foldername": "Random tracks by year"}
]
for starred in self.connection.walk_starred(): for entry in menu:
self.add_track(starred, show_artist=True) url = self.build_url(entry)
li = xbmcgui.ListItem(entry["foldername"])
xbmcplugin.addDirectoryItem(
handle=self.addon_handle, url=url, listitem=li, isFolder=True)
xbmcplugin.endOfDirectory(self.addon_handle) xbmcplugin.endOfDirectory(self.addon_handle)
def playlists_list(self): def menu_albums(self):
"""
Display main menu.
"""
menu = [
{"mode": "list_albums_newest", "foldername": "Newest albums"},
{"mode": "list_albums_frequent", "foldername": "Most played albums"},
{"mode": "list_albums_recent", "foldername": "Recently played albums"},
{"mode": "list_albums_genre", "foldername": "Albums by Genre"}
]
for entry in menu:
url = self.build_url(entry)
li = xbmcgui.ListItem(entry["foldername"])
xbmcplugin.addDirectoryItem(
handle=self.addon_handle, url=url, listitem=li, isFolder=True)
xbmcplugin.endOfDirectory(self.addon_handle)
def list_playlists(self):
""" """
Display playlists. Display playlists.
""" """
@ -188,7 +217,7 @@ class Plugin(object):
cover_art_url = self.connection.getCoverArtUrl( cover_art_url = self.connection.getCoverArtUrl(
playlist["coverArt"]) playlist["coverArt"])
url = self.build_url({ url = self.build_url({
"mode": "playlist_list", "playlist_id": playlist["id"]}) "mode": "list_playlist_songs", "playlist_id": playlist["id"]})
li = xbmcgui.ListItem(playlist["name"], iconImage=cover_art_url) li = xbmcgui.ListItem(playlist["name"], iconImage=cover_art_url)
xbmcplugin.addDirectoryItem( xbmcplugin.addDirectoryItem(
@ -196,67 +225,116 @@ class Plugin(object):
xbmcplugin.endOfDirectory(self.addon_handle) xbmcplugin.endOfDirectory(self.addon_handle)
def genre_list(self): def list_playlist_songs(self):
""" """
Display list of genres menu. Display playlist tracks.
""" """
for genre in self.connection.walk_genres(): playlist_id = self.addon_args["playlist_id"][0]
url = self.build_url({
"mode": "albums_by_genre_list",
"foldername": genre["value"].encode("utf-8")})
li = xbmcgui.ListItem(genre["value"]) xbmcplugin.setContent(self.addon_handle, "songs")
xbmcplugin.addDirectoryItem(
handle=self.addon_handle, url=url, listitem=li, isFolder=True) for track in self.connection.walk_playlist(playlist_id):
self.add_track(track, show_artist=True)
xbmcplugin.endOfDirectory(self.addon_handle) xbmcplugin.endOfDirectory(self.addon_handle)
def newest_albums_list(self): def list_albums_genre(self):
"""
Display albums by genre list.
"""
genres = self.connection.walk_genres()
genres_sorted = sorted(genres, key=lambda k: k['value'])
for genre in genres_sorted:
try:
genre_slug = genre["value"]
genre_name = genre_slug.replace(';',' / ')
genre_count = int(genre["albumCount"])
if genre_count == 0:
continue
genre_name += ' (' + str(genre_count) + ')'
url = self.build_url({
"mode": 'album_list_genre',
"foldername": genre_slug.encode("utf-8")})
li = xbmcgui.ListItem(genre_name)
xbmcplugin.addDirectoryItem(
handle=self.addon_handle, url=url, listitem=li, isFolder=True)
except:
pass
xbmcplugin.endOfDirectory(self.addon_handle)
def list_albums_newest(self):
""" """
Display newest album list. Display newest album list.
""" """
size = self.album_list_size size = self.albums_per_page
xbmcplugin.setContent(self.addon_handle, "albums") xbmcplugin.setContent(self.addon_handle, "albums")
for album in self.connection.walk_album_list('newest',size): for album in self.connection.walk_albums(ltype='newest',size=size):
self.add_album(album, show_artist=True) self.add_album(album, show_artist=True)
xbmcplugin.endOfDirectory(self.addon_handle) xbmcplugin.endOfDirectory(self.addon_handle)
def albums_by_genre_list(self): def list_albums_frequent(self):
"""
Display most played albums list.
"""
size = self.albums_per_page
xbmcplugin.setContent(self.addon_handle, "albums")
for album in self.connection.walk_albums(ltype='frequent',size=size):
self.add_album(album, show_artist=True)
xbmcplugin.endOfDirectory(self.addon_handle)
def list_albums_recent(self):
"""
Display recently played album list.
"""
size = self.albums_per_page
xbmcplugin.setContent(self.addon_handle, "albums")
for album in self.connection.walk_albums(ltype='recent',size=size):
self.add_album(album, show_artist=True)
xbmcplugin.endOfDirectory(self.addon_handle)
def album_list_genre(self):
""" """
Display album list by genre menu. Display album list by genre menu.
""" """
size = self.album_list_size
genre = self.addon_args["foldername"][0].decode("utf-8") genre = self.addon_args["foldername"][0].decode("utf-8")
size = self.albums_per_page
xbmcplugin.setContent(self.addon_handle, "albums") xbmcplugin.setContent(self.addon_handle, "albums")
for album in self.connection.walk_album_list('byGenre',size,genre=genre): for album in self.connection.walk_albums(ltype='byGenre',size=size,genre=genre):
self.add_album(album, show_artist=True) self.add_album(album, show_artist=True)
xbmcplugin.endOfDirectory(self.addon_handle) xbmcplugin.endOfDirectory(self.addon_handle)
def albums_by_genre_list(self): def list_artists(self):
"""
Display album list by genre menu.
"""
size = self.album_list_size
genre = self.addon_args["foldername"][0].decode("utf-8")
xbmcplugin.setContent(self.addon_handle, "albums")
for album in self.connection.walk_album_list('byGenre',size,None,None,genre):
self.add_album(album, show_artist=True)
xbmcplugin.endOfDirectory(self.addon_handle)
def artist_list(self):
""" """
Display artist list Display artist list
""" """
@ -315,25 +393,20 @@ class Plugin(object):
xbmcplugin.endOfDirectory(self.addon_handle) xbmcplugin.endOfDirectory(self.addon_handle)
def random_list(self):
def list_tracks_starred(self):
""" """
Display random options. Display starred songs.
""" """
menu = [ xbmcplugin.setContent(self.addon_handle, "songs")
{"mode": "random_by_genre_list", "foldername": "By genre"},
{"mode": "random_by_year_list", "foldername": "By year"}]
for entry in menu: for starred in self.connection.walk_tracks_starred():
url = self.build_url(entry) self.add_track(starred, show_artist=True)
li = xbmcgui.ListItem(entry["foldername"])
xbmcplugin.addDirectoryItem(
handle=self.addon_handle, url=url, listitem=li, isFolder=True)
xbmcplugin.endOfDirectory(self.addon_handle) xbmcplugin.endOfDirectory(self.addon_handle)
def random_by_genre_list(self): def list_tracks_random_genre(self):
""" """
Display random genre list. Display random genre list.
""" """
@ -358,13 +431,13 @@ class Plugin(object):
xbmcplugin.setContent(self.addon_handle, "songs") xbmcplugin.setContent(self.addon_handle, "songs")
for track in self.connection.walk_random_songs( for track in self.connection.walk_tracks_random(
size=self.random_count, genre=genre): size=self.tracks_per_page, genre=genre):
self.add_track(track, show_artist=True) self.add_track(track, show_artist=True)
xbmcplugin.endOfDirectory(self.addon_handle) xbmcplugin.endOfDirectory(self.addon_handle)
def random_by_year_list(self): def list_tracks_random_year(self):
""" """
Display random tracks by year. Display random tracks by year.
""" """
@ -376,8 +449,8 @@ class Plugin(object):
xbmcplugin.setContent(self.addon_handle, "songs") xbmcplugin.setContent(self.addon_handle, "songs")
for track in self.connection.walk_random_songs( for track in self.connection.walk_tracks_random(
size=self.random_count, from_year=from_year, to_year=to_year): size=self.tracks_per_page, from_year=from_year, to_year=to_year):
self.add_track(track, show_artist=True) self.add_track(track, show_artist=True)
xbmcplugin.endOfDirectory(self.addon_handle) xbmcplugin.endOfDirectory(self.addon_handle)

View File

@ -1,5 +1,5 @@
<?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="2.0.1" provider-name="BasilFX"> <addon id="plugin.audio.subsonic" name="Subsonic" version="2.0.1" provider-name="BasilFX,grosbouff">
<requires> <requires>
<import addon="xbmc.python" version="2.19.0"/> <import addon="xbmc.python" version="2.19.0"/>
</requires> </requires>

View File

@ -2,7 +2,6 @@ import urllib
import urlparse import urlparse
import libsonic import libsonic
def force_list(value): def force_list(value):
""" """
Coerce the input value to a list. Coerce the input value to a list.
@ -336,16 +335,6 @@ class SubsonicClient(libsonic.Connection):
for child in response["playlist"]["entry"]: for child in response["playlist"]["entry"]:
yield child yield child
def walk_starred(self):
"""
Request Subsonic's starred songs and iterate over each item.
"""
response = self.getStarred()
for song in response["starred"]["song"]:
yield song
def walk_directory(self, directory_id): def walk_directory(self, directory_id):
""" """
Request a Subsonic music directory and iterate over each item. Request a Subsonic music directory and iterate over each item.
@ -391,7 +380,7 @@ class SubsonicClient(libsonic.Connection):
for genre in response["genres"]["genre"]: for genre in response["genres"]["genre"]:
yield genre yield genre
def walk_album_list(self, ltype, size=10, from_year=None,to_year=None, genre=None): def walk_albums(self, ltype, size=None, from_year=None,to_year=None, genre=None):
""" """
Request all albums for a given genre and iterate over each album. Request all albums for a given genre and iterate over each album.
""" """
@ -406,7 +395,7 @@ class SubsonicClient(libsonic.Connection):
while True: while True:
response = self.getAlbumList2( response = self.getAlbumList2(
ltype=ltype, size=size, offset=offset, fromYear=from_year, toYear=to_year, genre=genre) ltype=ltype, genre=genre, size=size, offset=offset)
if not response["albumList2"]["album"]: if not response["albumList2"]["album"]:
break break
@ -426,8 +415,7 @@ class SubsonicClient(libsonic.Connection):
for song in response["album"]["song"]: for song in response["album"]["song"]:
yield song yield song
def walk_random_songs(self, size, genre=None, from_year=None, def walk_tracks_random(self, size, genre=None, from_year=None,to_year=None):
to_year=None):
""" """
Request random songs by genre and/or year and iterate over each song. Request random songs by genre and/or year and iterate over each song.
""" """
@ -437,3 +425,14 @@ class SubsonicClient(libsonic.Connection):
for song in response["randomSongs"]["song"]: for song in response["randomSongs"]["song"]:
yield song yield song
def walk_tracks_starred(self):
"""
Request Subsonic's starred songs and iterate over each item.
"""
response = self.getStarred()
for song in response["starred"]["song"]:
yield song

View File

@ -1,10 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<settings> <settings>
<setting id="subsonic_url" type="text" label="URL" default="http://demo.subsonic.org"/> <category label="Server">
<setting id="subsonic_url" type="text" label="Server URL" default="http://demo.subsonic.org"/>
<setting id="username" type="text" label="Username" default="guest3"/> <setting id="username" type="text" label="Username" default="guest3"/>
<setting id="password" type="text" option="hidden" label="Password" default="guest"/> <setting id="password" type="text" option="hidden" label="Password" default="guest"/>
<setting id="random_count" type="labelenum" label="Random songs" values="10|15|20|25"/> <setting type="sep" />
<setting id="album_list_size" type="labelenum" label="Albums list items" default="50" values="50|100|200|250|500"/> <setting id="albums_per_page" type="labelenum" label="Albums per page" default="50" values="10|25|50|100|250|500"/>
<setting id="tracks_per_page" type="labelenum" label="Tracks per page" default="100" values="10|25|50|100|250|500"/>
<setting type="sep" />
<setting id="transcode_format" type="labelenum" label="Transcode format" values="mp3|raw|flv|ogg"/> <setting id="transcode_format" type="labelenum" label="Transcode format" values="mp3|raw|flv|ogg"/>
<setting id="bitrate" type="labelenum" label="Bitrate" values="320|256|224|192|160|128|112|96|80|64|56|48|40|32"/> <setting id="bitrate" type="labelenum" label="Bitrate" values="320|256|224|192|160|128|112|96|80|64|56|48|40|32"/>
</category>
</settings> </settings>