diff --git a/README.txt b/README.txt index 07a9ec2..9096b6d 100644 --- a/README.txt +++ b/README.txt @@ -1,5 +1,5 @@ INFORMATION FOR SKINNERS ------------------------ -http://wiki.xbmc.org/index.php?title=Add-on:Skin_Widgets +https://kodi.wiki/view/Add-on:Skin_Widgets diff --git a/addon.xml b/addon.xml index 7e16861..1c7c3a0 100644 --- a/addon.xml +++ b/addon.xml @@ -1,72 +1,74 @@ - + - - - - + + + - + - Skin widgets - Widgets til Skins - Skin Widgets - Widgets κελύφους - Skin widgets - Skin widgets - Skin widgets - Widgets do Tema - Dodaci za presvlaku - Kinézet miniprogram - Skin widgets - 스킨 위젯 - Skin widgets - Dodatki Skóry - Widgets para Temas + Skin widgets + Widgets til Skins + Skin Widgets + Widgets κελύφους + Skin widgets + Skin widgets + Skin widgets + Widgets do Tema + Dodaci za presvlaku + Kinézet miniprogram + Skin widgets + 스킨 위젯 + Skin widgets + Dodatki Skóry + Widgets para Temas Skin widgets - Widgety Vzhľadov - Skal widgetar - 皮肤微件 - Skin widgets - Widgets til Skins - Skin Widgets - Widgets κελύφους - Skin widgets - Skin widgets - Skin widgets - Widgets do Tema - Dodaci za presvlaku - Kinézet miniprogram - Skin widgets - 스킨 위젯 - Skin widgets - Dodatki Skóry - Widgets para Temas + Widgety Vzhľadov + Skal widgetar + 皮肤微件 + Skin widgets + Widgets til Skins + Skin Widgets + Widgets κελύφους + Skin widgets + Skin widgets + Skin widgets + Widgets do Tema + Dodaci za presvlaku + Kinézet miniprogram + Skin widgets + 스킨 위젯 + Skin widgets + Dodatki Skóry + Widgets para Temas Skin widgets - Widgety Vzhľadov - Skal widgetar - 皮肤微件 - For information visit the wiki page or XBMC forum. - Besuche für mehr Informationen die Wiki-Seite oder das XBMC-Forum - Για πληροφορίες επισκεφθείτε τη σελίδα wiki ή το forum του XBMC. - For information visit the wiki page or XBMC forum. - Para más información, visite el wiki o los foros de XBMC. - Pour plus d'information, visitez la page du Wiki ou dur forum XBMC. - Para máis información visite a páxina wiki ou o foro do XBMC. - Za više informacija posjetite wiki stranicu ili XBMC forum. - Per le informazioni visita la pagina wiki o il forum - 위키 페이지나 XBMC 포럼에서 추가 정보를 확인하세요. - Bezoek voor informatie de wiki pagina of het XBMC forum. - Odwiedź stronę wiki lub forum XBMC by znaleźć więcej informacji. - Para mais informação, visite a página wiki ou o fórum do XBMC. + Widgety Vzhľadov + Skal widgetar + 皮肤微件 + For information visit the wiki page or XBMC forum. + Besuche für mehr Informationen die Wiki-Seite oder das XBMC-Forum + Για πληροφορίες επισκεφθείτε τη σελίδα wiki ή το forum του XBMC. + For information visit the wiki page or XBMC forum. + Para más información, visite el wiki o los foros de XBMC. + Pour plus d'information, visitez la page du Wiki ou dur forum XBMC. + Para máis información visite a páxina wiki ou o foro do XBMC. + Za više informacija posjetite wiki stranicu ili XBMC forum. + Per le informazioni visita la pagina wiki o il forum + 위키 페이지나 XBMC 포럼에서 추가 정보를 확인하세요. + Bezoek voor informatie de wiki pagina of het XBMC forum. + Odwiedź stronę wiki lub forum XBMC by znaleźć więcej informacji. + Para mais informação, visite a página wiki ou o fórum do XBMC. Para informações visite o página do wiki ou fórum XBMC.org. - För information, besök wiki-sidan eller XBMC forumet. - 访问wiki页或XBMC论坛了解更多信息 + För information, besök wiki-sidan eller XBMC forumet. + 访问wiki页或XBMC论坛了解更多信息 all - GNU GENERAL PUBLIC LICENSE. Version 2, June 1991 - - http://forum.xbmc.org/showthread.php?tid=142389 + GPL-2.0 + https://forum.kodi.tv/showthread.php?tid=142389 https://github.com/XBMC-Addons/service.skin.widgets + Updated with changes required for Kodi 19 / Python 3 by scott967 + + resources/icon.png + diff --git a/changelog.txt b/changelog.txt index c036088..e1aee15 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,13 +1,24 @@ +v0.0.33+matrix.1 +- Refactored languages +- Refactored settings +- Update addon.xml with assets +- Update code to python3 + +v0.0.33 +- Fix undefined variables + +v0.0.32 +- Remove unneeded dependency + +v0.0.31 +- Fix circular reference warnings on shutdown + v0.0.30 -- Refactor -- Fix item2 could be undefined +- Fix possible script error on recommended episodes v0.0.29 - Fix script error on XBMC Helix due to empty array -v0.0.28 -- fix studio and country properties - v0.0.27 - Fix setting properties reload on settings change diff --git a/default.py b/default.py index 8716440..22426b3 100644 --- a/default.py +++ b/default.py @@ -1,11 +1,11 @@ #!/usr/bin/python # -*- coding: utf-8 -*- # -# Copyright (C) 2012-2013 Team-XBMC +# Copyright (C) 2012 Team-Kodi # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or +# the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, @@ -19,25 +19,26 @@ # This script is based on script.randomitems & script.wacthlist # Thanks to their original authors +import os import sys import xbmc import xbmcgui +import xbmcaddon +import random import datetime -import lib.common -from lib.common import log -from lib.utils import media_path, media_streamdetails -from lib.properties import gui -from lib.requests import req - -GUI = gui() -REQ = req() -WINDOW = xbmcgui.Window(10000) -LIMIT = 20 - -### get addon info -__addon__ = lib.common.__addon__ -__addonprofile__ = lib.common.__addonprofile__ -__version__ = lib.common.__version__ +import _strptime +import urllib.request +import json as simplejson + +__addon__ = xbmcaddon.Addon() +__addonversion__ = __addon__.getAddonInfo('version') +__addonid__ = __addon__.getAddonInfo('id') +__addonname__ = __addon__.getAddonInfo('name') +__localize__ = __addon__.getLocalizedString + +def log(txt): + message = '%s: %s' % (__addonname__, txt) + xbmc.log(msg=message, level=xbmc.LOGDEBUG) class Main: def __init__(self): @@ -57,37 +58,48 @@ def __init__(self): self._init_vars() self._init_property() # clear our property, if another instance is already running it should stop now - WINDOW.clearProperty('SkinWidgets_Running') - #a_total = datetime.datetime.now() + self.WINDOW.clearProperty('SkinWidgets_Running') + a_total = datetime.datetime.now() self._fetch_info_randomitems() self._fetch_info_recommended() self._fetch_info_recentitems() - #b_total = datetime.datetime.now() - #c_total = b_total - a_total - #log('Total time needed for all queries: %s' % c_total) + b_total = datetime.datetime.now() + c_total = b_total - a_total + log('Total time needed for all queries: %s' % c_total) # give a possible other instance some time to notice the empty property - WINDOW.setProperty('SkinWidgets_Running', 'true') + self.WINDOW.setProperty('SkinWidgets_Running', 'true') self._daemon() def _init_vars(self): + self.WINDOW = xbmcgui.Window(10000) self.Player = Widgets_Player(action = self._update) self.Monitor = Widgets_Monitor(update_listitems = self._update, update_settings = self._on_change) + self.LIMIT = 20 + self.RANDOMITEMS_UNPLAYED = False + self.RECENTITEMS_UNPLAYED = False def _on_change(self): + clearlist_groups = ['Recommended','Random','Recent'] + clearlist_types = ['Movie','Episode','MusicVideo','Album', 'Artist','Song','Addon'] + for item_group in clearlist_groups: + for item_type in clearlist_types: + clear = item_group + item_type + self._clear_properties(clear) self._init_property() self._fetch_info_randomitems() self._fetch_info_recommended() self._fetch_info_recentitems() def _init_property(self): - WINDOW.setProperty('SkinWidgets_Recommended', '%s' % __addon__.getSetting("recommended_enable")) - WINDOW.setProperty('SkinWidgets_RandomItems', '%s' % __addon__.getSetting("randomitems_enable")) - WINDOW.setProperty('SkinWidgets_RecentItems', '%s' % __addon__.getSetting("recentitems_enable")) - WINDOW.setProperty('SkinWidgets_RandomItems_Update', 'false') - self.RANDOMITEMS_UPDATE_METHOD = int(__addon__.getSetting("randomitems_method")) + self.WINDOW.setProperty('SkinWidgets_Recommended', '%s' % __addon__.getSetting("recommended_enable")) + self.WINDOW.setProperty('SkinWidgets_RandomItems', '%s' % __addon__.getSetting("randomitems_enable")) + self.WINDOW.setProperty('SkinWidgets_RecentItems', '%s' % __addon__.getSetting("recentitems_enable")) + self.WINDOW.setProperty('SkinWidgets_RandomItems_Update', 'false') + self.RANDOMITEMS_UPDATE_METHOD = __addon__.getSetting("randomitems_method") self.RECENTITEMS_HOME_UPDATE = __addon__.getSetting("recentitems_homeupdate") + self.PLOT_ENABLE = __addon__.getSetting("plot_enable") == 'true' # convert time to seconds, times 2 for 0,5 second sleep compensation - self.RANDOMITEMS_TIME = int(float(__addon__.getSetting("randomitems_time"))) * 60 * 2 + self.RANDOMITEMS_TIME = __addon__.getSetting("randomitems_time") * 60 * 2 def _parse_argv( self ): try: @@ -107,102 +119,518 @@ def _parse_argv( self ): self.RESUME = "false" def _fetch_info_recommended(self): - #a = datetime.datetime.now() + a = datetime.datetime.now() if __addon__.getSetting("recommended_enable") == 'true': self._fetch_movies('RecommendedMovie') - self._fetch_episodes_recommended('RecommendedEpisode') + self._fetch_tvshows_recommended('RecommendedEpisode') self._fetch_albums('RecommendedAlbum') - self._fetch_musicvideos('RecommendedMusicVideo') - #b = datetime.datetime.now() - #c = b - a - #log('Total time needed to request recommended queries: %s' % c) + self._fetch_musicvideo('RecommendedMusicVideo') + b = datetime.datetime.now() + c = b - a + log('Total time needed to request recommended queries: %s' % c) def _fetch_info_randomitems(self): - #a = datetime.datetime.now() + a = datetime.datetime.now() if __addon__.getSetting("randomitems_enable") == 'true': + self.RANDOMITEMS_UNPLAYED = __addon__.getSetting("randomitems_unplayed") == 'true' self._fetch_movies('RandomMovie') self._fetch_tvshows('RandomEpisode') - self._fetch_musicvideos('RandomMusicVideo') + self._fetch_musicvideo('RandomMusicVideo') self._fetch_albums('RandomAlbum') - self._fetch_artists('RandomArtist') - self._fetch_songs('RandomSong') - self._fetch_addons('RandomAddon') - #b = datetime.datetime.now() - #c = b - a - #log('Total time needed to request random queries: %s' % c) + self._fetch_artist('RandomArtist') + self._fetch_song('RandomSong') + self._fetch_addon('RandomAddon') + b = datetime.datetime.now() + c = b - a + log('Total time needed to request random queries: %s' % c) + + def _fetch_info_recentitems(self): - #a = datetime.datetime.now() + a = datetime.datetime.now() if __addon__.getSetting("recentitems_enable") == 'true': + self.RECENTITEMS_UNPLAYED = __addon__.getSetting("recentitems_unplayed") == 'true' self._fetch_movies('RecentMovie') self._fetch_tvshows('RecentEpisode') - self._fetch_musicvideos('RecentMusicVideo') + self._fetch_musicvideo('RecentMusicVideo') self._fetch_albums('RecentAlbum') - #b = datetime.datetime.now() - #c = b - a - #log('Total time needed to request recent items queries: %s' % c) + b = datetime.datetime.now() + c = b - a + log('Total time needed to request recent items queries: %s' % c) def _fetch_movies(self, request): - if not xbmc.abortRequested: - data = REQ.movies(request) - GUI.movies(request, data) + if not self.Monitor.abortRequested(): + json_string = '{"jsonrpc": "2.0", "id": 1, "method": "VideoLibrary.GetMovies", "params": {"properties": ["title", "originaltitle", "playcount", "year", "genre", "studio", "country", "tagline", "plot", "runtime", "file", "plotoutline", "lastplayed", "trailer", "rating", "userrating", "resume", "art", "streamdetails", "mpaa", "director"], "limits": {"end": %d},' %self.LIMIT + if request == 'RecommendedMovie': + json_query = xbmc.executeJSONRPC('%s "sort": {"order": "descending", "method": "lastplayed"}, "filter": {"field": "inprogress", "operator": "true", "value": ""}}}' %json_string) + elif request == 'RecentMovie' and self.RECENTITEMS_UNPLAYED: + json_query = xbmc.executeJSONRPC('%s "sort": {"order": "descending", "method": "dateadded"}, "filter": {"field": "playcount", "operator": "is", "value": "0"}}}' %json_string) + elif request == 'RecentMovie': + json_query = xbmc.executeJSONRPC('%s "sort": {"order": "descending", "method": "dateadded"}}}' %json_string) + elif request == "RandomMovie" and self.RANDOMITEMS_UNPLAYED: + json_query = xbmc.executeJSONRPC('%s "sort": {"method": "random" }, "filter": {"field": "playcount", "operator": "lessthan", "value": "1"}}}' %json_string) + else: + json_query = xbmc.executeJSONRPC('%s "sort": {"method": "random" } }}' %json_string) + json_query = simplejson.loads(json_query) + if 'result' in json_query and 'movies' in json_query['result']: + self._clear_properties(request) + count = 0 + for item in json_query['result']['movies']: + count += 1 + if (item['resume']['position'] and item['resume']['total'])> 0: + resume = "true" + played = '%s%%'%int((float(item['resume']['position']) / float(item['resume']['total'])) * 100) + else: + resume = "false" + played = '0%' + if item['playcount'] >= 1: + watched = "true" + else: + watched = "false" + if not self.PLOT_ENABLE and watched == "false": + plot = __localize__(32014) + else: + plot = item['plot'] + art = item['art'] + path = media_path(item['file']) + play = 'XBMC.RunScript(' + __addonid__ + ',movieid=' + str(item.get('movieid')) + ')' + streaminfo = media_streamdetails(item['file'].lower(), + item['streamdetails']) + if len(item['studio']) > 0: + studio = item['studio'][0] + else: + studio = "" + if len(item['country']) > 0: + country = item['country'][0] + else: + country = "" + self.WINDOW.setProperty("%s.%d.DBID" % (request, count), str(item.get('movieid'))) + self.WINDOW.setProperty("%s.%d.Title" % (request, count), item['title']) + self.WINDOW.setProperty("%s.%d.OriginalTitle" % (request, count), item['originaltitle']) + self.WINDOW.setProperty("%s.%d.Year" % (request, count), str(item['year'])) + self.WINDOW.setProperty("%s.%d.Genre" % (request, count), " / ".join(item['genre'])) + self.WINDOW.setProperty("%s.%d.Studio" % (request, count), studio) + self.WINDOW.setProperty("%s.%d.Country" % (request, count), country) + self.WINDOW.setProperty("%s.%d.Plot" % (request, count), plot) + self.WINDOW.setProperty("%s.%d.PlotOutline" % (request, count), item['plotoutline']) + self.WINDOW.setProperty("%s.%d.Tagline" % (request, count), item['tagline']) + self.WINDOW.setProperty("%s.%d.Runtime" % (request, count), str(int((item['runtime'] / 60) + 0.5))) + self.WINDOW.setProperty("%s.%d.Rating" % (request, count), str(round(float(item['rating']),1))) + self.WINDOW.setProperty("%s.%d.Userrating" % (request, count), str(item['userrating'])) + self.WINDOW.setProperty("%s.%d.mpaa" % (request, count), item['mpaa']) + self.WINDOW.setProperty("%s.%d.Director" % (request, count), " / ".join(item['director'])) + self.WINDOW.setProperty("%s.%d.Trailer" % (request, count), item['trailer']) + self.WINDOW.setProperty("%s.%d.Art(poster)" % (request, count), art.get('poster','')) + self.WINDOW.setProperty("%s.%d.Art(fanart)" % (request, count), art.get('fanart','')) + self.WINDOW.setProperty("%s.%d.Art(clearlogo)" % (request, count), art.get('clearlogo','')) + self.WINDOW.setProperty("%s.%d.Art(clearart)" % (request, count), art.get('clearart','')) + self.WINDOW.setProperty("%s.%d.Art(landscape)" % (request, count), art.get('landscape','')) + self.WINDOW.setProperty("%s.%d.Art(banner)" % (request, count), art.get('banner','')) + self.WINDOW.setProperty("%s.%d.Art(discart)" % (request, count), art.get('discart','')) + self.WINDOW.setProperty("%s.%d.Resume" % (request, count), resume) + self.WINDOW.setProperty("%s.%d.PercentPlayed" % (request, count), played) + self.WINDOW.setProperty("%s.%d.Watched" % (request, count), watched) + self.WINDOW.setProperty("%s.%d.File" % (request, count), item['file']) + self.WINDOW.setProperty("%s.%d.Path" % (request, count), path) + self.WINDOW.setProperty("%s.%d.Play" % (request, count), play) + self.WINDOW.setProperty("%s.%d.VideoCodec" % (request, count), streaminfo['videocodec']) + self.WINDOW.setProperty("%s.%d.VideoResolution" % (request, count), streaminfo['videoresolution']) + self.WINDOW.setProperty("%s.%d.VideoAspect" % (request, count), streaminfo['videoaspect']) + self.WINDOW.setProperty("%s.%d.AudioCodec" % (request, count), streaminfo['audiocodec']) + self.WINDOW.setProperty("%s.%d.AudioChannels" % (request, count), str(streaminfo['audiochannels'])) + del json_query + + def _fetch_tvshows_recommended(self, request): + if not self.Monitor.abortRequested(): + # First unplayed episode of recent played tvshows + json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": {"properties": ["title", "studio", "mpaa", "file", "art"], "sort": {"order": "descending", "method": "lastplayed"}, "filter": {"field": "inprogress", "operator": "true", "value": ""}, "limits": {"end": %d}}, "id": 1}' %self.LIMIT) + json_query = simplejson.loads(json_query) + if 'result' in json_query and 'tvshows' in json_query['result']: + self._clear_properties(request) + count = 0 + for item in json_query['result']['tvshows']: + if self.Monitor.abortRequested(): + break + count += 1 + json_query2 = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": {"tvshowid": %d, "properties": ["title", "playcount", "plot", "season", "episode", "showtitle", "file", "lastplayed", "rating", "userrating", "resume", "art", "streamdetails", "firstaired", "runtime"], "sort": {"method": "episode"}, "filter": {"field": "playcount", "operator": "is", "value": "0"}, "limits": {"end": 1}}, "id": 1}' %item['tvshowid']) + json_query2 = simplejson.loads(json_query2) + if 'result' in json_query2 and json_query2['result'] != None and 'episodes' in json_query2['result']: + for item2 in json_query2['result']['episodes']: + episode = ("%.2d" % float(item2['episode'])) + season = "%.2d" % float(item2['season']) + rating = str(round(float(item2['rating']),1)) + episodeno = "s%se%s" %(season,episode) + art2 = item2['art'] - def _fetch_episodes_recommended(self, request): - if not xbmc.abortRequested: - data = REQ.episodes_recommended(request) - GUI.episodes_recommended(request, data) + #seasonthumb = '' + if (item2['resume']['position'] and item2['resume']['total']) > 0: + resume = "true" + played = '%s%%'%int((float(item2['resume']['position']) / float(item2['resume']['total'])) * 100) + else: + resume = "false" + played = '0%' + if item2['playcount'] >= 1: + watched = "true" + else: + watched = "false" + if not self.PLOT_ENABLE and watched == "false": + plot = __localize__(32014) + else: + plot = item2['plot'] + art = item['art'] + path = media_path(item['file']) + play = 'XBMC.RunScript(' + __addonid__ + ',episodeid=' + str(item2.get('episodeid')) + ')' + streaminfo = media_streamdetails(item['file'].lower(), + item2['streamdetails']) + if len(item['studio']) > 0: + studio = item['studio'][0] + else: + studio = "" + self.WINDOW.setProperty("%s.%d.DBID" % (request, count), str(item2.get('episodeid'))) + self.WINDOW.setProperty("%s.%d.Title" % (request, count), item2['title']) + self.WINDOW.setProperty("%s.%d.Episode" % (request, count), episode) + self.WINDOW.setProperty("%s.%d.EpisodeNo" % (request, count), episodeno) + self.WINDOW.setProperty("%s.%d.Season" % (request, count), season) + self.WINDOW.setProperty("%s.%d.Plot" % (request, count), plot) + self.WINDOW.setProperty("%s.%d.TVshowTitle" % (request, count), item2['showtitle']) + self.WINDOW.setProperty("%s.%d.Rating" % (request, count), rating) + self.WINDOW.setProperty("%s.%d.Runtime" % (request, count), str(int((item2['runtime'] / 60) + 0.5))) + self.WINDOW.setProperty("%s.%d.Premiered" % (request, count), item2['firstaired']) + self.WINDOW.setProperty("%s.%d.Art(thumb)" % (request, count), art2.get('thumb','')) + self.WINDOW.setProperty("%s.%d.Art(tvshow.fanart)" % (request, count), art2.get('tvshow.fanart','')) + self.WINDOW.setProperty("%s.%d.Art(tvshow.poster)" % (request, count), art2.get('tvshow.poster','')) + self.WINDOW.setProperty("%s.%d.Art(tvshow.banner)" % (request, count), art2.get('tvshow.banner','')) + self.WINDOW.setProperty("%s.%d.Art(tvshow.clearlogo)"% (request, count), art2.get('tvshow.clearlogo','')) + self.WINDOW.setProperty("%s.%d.Art(tvshow.clearart)" % (request, count), art2.get('tvshow.clearart','')) + self.WINDOW.setProperty("%s.%d.Art(tvshow.landscape)"% (request, count), art2.get('tvshow.landscape','')) + self.WINDOW.setProperty("%s.%d.Art(tvshow.characterart)"% (request, count), art2.get('tvshow.characterart','')) + #self.WINDOW.setProperty("%s.%d.Art(season.poster)" % (request, count), seasonthumb) + self.WINDOW.setProperty("%s.%d.Studio" % (request, count), studio) + self.WINDOW.setProperty("%s.%d.mpaa" % (request, count), item['mpaa']) + self.WINDOW.setProperty("%s.%d.Resume" % (request, count), resume) + self.WINDOW.setProperty("%s.%d.PercentPlayed" % (request, count), played) + self.WINDOW.setProperty("%s.%d.Watched" % (request, count), watched) + self.WINDOW.setProperty("%s.%d.File" % (request, count), item2['file']) + self.WINDOW.setProperty("%s.%d.Path" % (request, count), path) + self.WINDOW.setProperty("%s.%d.Play" % (request, count), play) + self.WINDOW.setProperty("%s.%d.VideoCodec" % (request, count), streaminfo['videocodec']) + self.WINDOW.setProperty("%s.%d.VideoResolution" % (request, count), streaminfo['videoresolution']) + self.WINDOW.setProperty("%s.%d.VideoAspect" % (request, count), streaminfo['videoaspect']) + self.WINDOW.setProperty("%s.%d.AudioCodec" % (request, count), streaminfo['audiocodec']) + self.WINDOW.setProperty("%s.%d.AudioChannels" % (request, count), str(streaminfo['audiochannels'])) + del json_query2 + del json_query def _fetch_tvshows(self, request): - if not xbmc.abortRequested: - data = REQ.episodes(request) - GUI.episodes(request, data) + if not self.Monitor.abortRequested(): + season_folders = __addon__.getSetting("randomitems_seasonfolders") + json_string = '{"jsonrpc": "2.0", "id": 1, "method": "VideoLibrary.GetEpisodes", "params": { "properties": ["title", "playcount", "season", "episode", "showtitle", "plot", "file", "rating", "userrating", "resume", "tvshowid", "art", "streamdetails", "firstaired", "runtime"], "limits": {"end": %d},' %self.LIMIT + if request == 'RecentEpisode' and self.RECENTITEMS_UNPLAYED: + json_query = xbmc.executeJSONRPC('%s "sort": {"order": "descending", "method": "dateadded"}, "filter": {"field": "playcount", "operator": "lessthan", "value": "1"}}}' %json_string) + elif request == 'RecentEpisode': + json_query = xbmc.executeJSONRPC('%s "sort": {"order": "descending", "method": "dateadded"}}}' %json_string) + elif request == 'RandomEpisode' and self.RANDOMITEMS_UNPLAYED: + json_query = xbmc.executeJSONRPC('%s "sort": {"method": "random" }, "filter": {"field": "playcount", "operator": "lessthan", "value": "1"}}}' %json_string) + else: + json_query = xbmc.executeJSONRPC('%s "sort": {"method": "random" }}}' %json_string) + json_query = simplejson.loads(json_query) + if 'result' in json_query and 'episodes' in json_query['result']: + self._clear_properties(request) + count = 0 + for item in json_query['result']['episodes']: + count += 1 + ''' + # This part is commented out because it takes 1.5second extra on my system to request these which doubles the total time. + # Hence the ugly path hack that will require users to have season folders. + json_query2 = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShowDetails", "params": {"properties": ["file", "studio"], "tvshowid":%s}, "id": 1}' %item['tvshowid']) + json_query2 = simplejson.loads(json_query2) + path = json_query2['result']['tvshowdetails']['file'] + studio = json_query2['result']['tvshowdetails']['studio'][0] + ''' + if season_folders == 'true': + path = os.path.split(media_path(item['file']))[0] + else: + path = media_path(item['file']) + episode = ("%.2d" % float(item['episode'])) + season = "%.2d" % float(item['season']) + episodeno = "s%se%s" %(season,episode) + #seasonthumb = '' + rating = str(round(float(item['rating']),1)) + if (item['resume']['position'] and item['resume']['total']) > 0: + resume = "true" + played = '%s%%'%int((float(item['resume']['position']) / float(item['resume']['total'])) * 100) + else: + resume = "false" + played = '0%' + if item['playcount'] >= 1: + watched = "true" + else: + watched = "false" + if not self.PLOT_ENABLE and watched == "false": + plot = __localize__(32014) + else: + plot = item['plot'] + art = item['art'] + path = media_path(item['file']) + play = 'XBMC.RunScript(' + __addonid__ + ',episodeid=' + str(item.get('episodeid')) + ')' + streaminfo = media_streamdetails(item['file'].lower(), + item['streamdetails']) + self.WINDOW.setProperty("%s.%d.DBID" % (request, count), str(item.get('episodeid'))) + self.WINDOW.setProperty("%s.%d.Title" % (request, count), item['title']) + self.WINDOW.setProperty("%s.%d.Episode" % (request, count), episode) + self.WINDOW.setProperty("%s.%d.EpisodeNo" % (request, count), episodeno) + self.WINDOW.setProperty("%s.%d.Season" % (request, count), season) + self.WINDOW.setProperty("%s.%d.Plot" % (request, count), plot) + self.WINDOW.setProperty("%s.%d.TVshowTitle" % (request, count), item['showtitle']) + self.WINDOW.setProperty("%s.%d.Rating" % (request, count), rating) + self.WINDOW.setProperty("%s.%d.Runtime" % (request, count), str(int((item['runtime'] / 60) + 0.5))) + self.WINDOW.setProperty("%s.%d.Premiered" % (request, count), item['firstaired']) + self.WINDOW.setProperty("%s.%d.Art(thumb)" % (request, count), art.get('thumb','')) + self.WINDOW.setProperty("%s.%d.Art(tvshow.fanart)" % (request, count), art.get('tvshow.fanart','')) + self.WINDOW.setProperty("%s.%d.Art(tvshow.poster)" % (request, count), art.get('tvshow.poster','')) + self.WINDOW.setProperty("%s.%d.Art(tvshow.banner)" % (request, count), art.get('tvshow.banner','')) + self.WINDOW.setProperty("%s.%d.Art(tvshow.clearlogo)"% (request, count), art.get('tvshow.clearlogo','')) + self.WINDOW.setProperty("%s.%d.Art(tvshow.clearart)" % (request, count), art.get('tvshow.clearart','')) + self.WINDOW.setProperty("%s.%d.Art(tvshow.landscape)"% (request, count), art.get('tvshow.landscape','')) + self.WINDOW.setProperty("%s.%d.Art(tvshow.characterart)"% (request, count), art.get('tvshow.characterart','')) + self.WINDOW.setProperty("%s.%d.Resume" % (request, count), resume) + self.WINDOW.setProperty("%s.%d.PercentPlayed" % (request, count), played) + self.WINDOW.setProperty("%s.%d.Watched" % (request, count), watched) + self.WINDOW.setProperty("%s.%d.File" % (request, count), item['file']) + self.WINDOW.setProperty("%s.%d.Path" % (request, count), path) + self.WINDOW.setProperty("%s.%d.Play" % (request, count), play) + self.WINDOW.setProperty("%s.%d.VideoCodec" % (request, count), streaminfo['videocodec']) + self.WINDOW.setProperty("%s.%d.VideoResolution" % (request, count), streaminfo['videoresolution']) + self.WINDOW.setProperty("%s.%d.VideoAspect" % (request, count), streaminfo['videoaspect']) + self.WINDOW.setProperty("%s.%d.AudioCodec" % (request, count), streaminfo['audiocodec']) + self.WINDOW.setProperty("%s.%d.AudioChannels" % (request, count), str(streaminfo['audiochannels'])) + del json_query - def _fetch_musicvideos(self, request): - if not xbmc.abortRequested: - data = REQ.musicvideos(request) - GUI.musicvideos(request, data) + def _fetch_seasonthumb(self, tvshowid, seasonnumber): + json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetSeasons", "params": {"properties": ["season", "thumbnail"], "tvshowid":%s }, "id": 1}' % tvshowid) + json_query = simplejson.loads(json_query) + if 'result' in json_query and 'seasons' in json_query['result']: + for item in json_query['result']['seasons']: + season = "%.2d" % float(item['season']) + if season == seasonnumber: + thumbnail = item['thumbnail'] + return thumbnail + + def _fetch_musicvideo(self, request): + if not self.Monitor.abortRequested(): + json_string = '{"jsonrpc": "2.0", "id": 1, "method": "VideoLibrary.GetMusicVideos", "params": {"properties": ["title", "artist", "playcount", "year", "plot", "genre", "runtime", "userrating", "fanart", "thumbnail", "file", "streamdetails", "resume"], "limits": {"end": %d},' %self.LIMIT + if request == 'RecommendedMusicVideo': + json_query = xbmc.executeJSONRPC('%s "sort": {"order": "descending", "method": "playcount" }}}' %json_string) + elif request == 'RecentMusicVideo': + json_query = xbmc.executeJSONRPC('%s "sort": {"order": "descending", "method": "dateadded"}}}' %json_string) + else: + json_query = xbmc.executeJSONRPC('%s "sort": {"method": "random"}}}' %json_string) + json_query = simplejson.loads(json_query) + if 'result' in json_query and 'musicvideos' in json_query['result']: + self._clear_properties(request) + count = 0 + for item in json_query['result']['musicvideos']: + count += 1 + if (item['resume']['position'] and item['resume']['total'])> 0: + resume = "true" + played = '%s%%'%int((float(item['resume']['position']) / float(item['resume']['total'])) * 100) + else: + resume = "false" + played = '0%' + if item['playcount'] >= 1: + watched = "true" + else: + watched = "false" + play = 'XBMC.RunScript(' + __addonid__ + ',musicvideoid=' + str(item.get('musicvideoid')) + ')' + path = media_path(item['file']) + streaminfo = media_streamdetails(item['file'].lower(), + item['streamdetails']) + self.WINDOW.setProperty("%s.%d.DBID" % (request, count), str(item.get('musicvideoid'))) + self.WINDOW.setProperty("%s.%d.Title" % (request, count), item['title']) + self.WINDOW.setProperty("%s.%d.Artist" % (request, count), " / ".join(item['artist'])) + self.WINDOW.setProperty("%s.%d.Year" % (request, count), str(item['year'])) + self.WINDOW.setProperty("%s.%d.Plot" % (request, count), item['plot']) + self.WINDOW.setProperty("%s.%d.Genre" % (request, count), " / ".join(item['genre'])) + self.WINDOW.setProperty("%s.%d.Userrating" % (request, count), str(item['userrating'])) + self.WINDOW.setProperty("%s.%d.Runtime" % (request, count), str(int((item['runtime'] / 60) + 0.5))) + self.WINDOW.setProperty("%s.%d.Thumb" % (request, count), item['thumbnail']) #remove + self.WINDOW.setProperty("%s.%d.Fanart" % (request, count), item['fanart']) #remove + self.WINDOW.setProperty("%s.%d.Art(thumb)" % (request, count), item['thumbnail']) + self.WINDOW.setProperty("%s.%d.Art(fanart)" % (request, count), item['fanart']) + self.WINDOW.setProperty("%s.%d.File" % (request, count), item['file']) + self.WINDOW.setProperty("%s.%d.Path" % (request, count), path) + self.WINDOW.setProperty("%s.%d.Resume" % (request, count), resume) + self.WINDOW.setProperty("%s.%d.PercentPlayed" % (request, count), played) + self.WINDOW.setProperty("%s.%d.Watched" % (request, count), watched) + self.WINDOW.setProperty("%s.%d.Play" % (request, count), play) + self.WINDOW.setProperty("%s.%d.VideoCodec" % (request, count), streaminfo['videocodec']) + self.WINDOW.setProperty("%s.%d.VideoResolution" % (request, count), streaminfo['videoresolution']) + self.WINDOW.setProperty("%s.%d.VideoAspect" % (request, count), streaminfo['videoaspect']) + self.WINDOW.setProperty("%s.%d.AudioCodec" % (request, count), streaminfo['audiocodec']) + self.WINDOW.setProperty("%s.%d.AudioChannels" % (request, count), str(streaminfo['audiochannels'])) + del json_query def _fetch_albums(self, request): - if not xbmc.abortRequested: - data = REQ.albums(request) - GUI.albums(request, data) + if not self.Monitor.abortRequested(): + json_string = '{"jsonrpc": "2.0", "id": 1, "method": "AudioLibrary.GetAlbums", "params": {"properties": ["title", "description", "albumlabel", "theme", "mood", "style", "type", "artist", "genre", "year", "thumbnail", "fanart", "rating", "userrating", "playcount"], "limits": {"end": %d},' %self.LIMIT + if request == 'RecommendedAlbum': + json_query = xbmc.executeJSONRPC('%s "sort": {"order": "descending", "method": "playcount" }}}' %json_string) + elif request == 'RecentAlbum': + json_query = xbmc.executeJSONRPC('%s "sort": {"order": "descending", "method": "dateadded" }}}' %json_string) + else: + json_query = xbmc.executeJSONRPC('%s "sort": {"method": "random"}}}' %json_string) + json_query = simplejson.loads(json_query) + if 'result' in json_query and 'albums' in json_query['result']: + self._clear_properties(request) + count = 0 + for item in json_query['result']['albums']: + count += 1 + rating = str(item['rating']) + if rating == '48': + rating = '' + play = 'XBMC.RunScript(' + __addonid__ + ',albumid=' + str(item.get('albumid')) + ')' + self.WINDOW.setProperty("%s.%d.Title" % (request, count), item['title']) + self.WINDOW.setProperty("%s.%d.Label" % (request, count), item['title']) #needs to be removed + self.WINDOW.setProperty("%s.%d.Artist" % (request, count), " / ".join(item['artist'])) + self.WINDOW.setProperty("%s.%d.Genre" % (request, count), " / ".join(item['genre'])) + self.WINDOW.setProperty("%s.%d.Theme" % (request, count), " / ".join(item['theme'])) + self.WINDOW.setProperty("%s.%d.Mood" % (request, count), " / ".join(item['mood'])) + self.WINDOW.setProperty("%s.%d.Style" % (request, count), " / ".join(item['style'])) + self.WINDOW.setProperty("%s.%d.Type" % (request, count), " / ".join(item['type'])) + self.WINDOW.setProperty("%s.%d.Year" % (request, count), str(item['year'])) + self.WINDOW.setProperty("%s.%d.RecordLabel" % (request, count), item['albumlabel']) + self.WINDOW.setProperty("%s.%d.Description" % (request, count), item['description']) + self.WINDOW.setProperty("%s.%d.Rating" % (request, count), rating) + self.WINDOW.setProperty("%s.%d.Userrating" % (request, count), str(item['userrating'])) + self.WINDOW.setProperty("%s.%d.Thumb" % (request, count), item['thumbnail']) #remove + self.WINDOW.setProperty("%s.%d.Fanart" % (request, count), item['fanart']) #remove + self.WINDOW.setProperty("%s.%d.Art(thumb)" % (request, count), item['thumbnail']) + self.WINDOW.setProperty("%s.%d.Art(fanart)" % (request, count), item['fanart']) + self.WINDOW.setProperty("%s.%d.Play" % (request, count), play) + del json_query - def _fetch_artists(self, request): - if not xbmc.abortRequested: - data = REQ.artist(request) - GUI.artists(request, data) + def _fetch_artist(self, request): + if not self.Monitor.abortRequested(): + # Random artist + json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "AudioLibrary.GetArtists", "params": {"properties": ["genre", "description", "mood", "style", "born", "died", "formed", "disbanded", "yearsactive", "instrument", "fanart", "thumbnail"], "sort": {"method": "random"}, "limits": {"end": %d}}, "id": 1}' %self.LIMIT) + json_query = simplejson.loads(json_query) + if 'result' in json_query and 'artists' in json_query['result']: + self._clear_properties(request) + count = 0 + for item in json_query['result']['artists']: + count += 1 + path = 'musicdb://2/' + str(item['artistid']) + '/' + self.WINDOW.setProperty("%s.%d.Title" % (request, count), item['label']) + self.WINDOW.setProperty("%s.%d.Genre" % (request, count), " / ".join(item['genre'])) + self.WINDOW.setProperty("%s.%d.Thumb" % (request, count), item['thumbnail']) #remove + self.WINDOW.setProperty("%s.%d.Fanart" % (request, count), item['fanart']) #remove + self.WINDOW.setProperty("%s.%d.Art(thumb)" % (request, count), item['thumbnail']) + self.WINDOW.setProperty("%s.%d.Art(fanart)" % (request, count), item['fanart']) + self.WINDOW.setProperty("%s.%d.Description" % (request, count), item['description']) + self.WINDOW.setProperty("%s.%d.Born" % (request, count), item['born']) + self.WINDOW.setProperty("%s.%d.Died" % (request, count), item['died']) + self.WINDOW.setProperty("%s.%d.Formed" % (request, count), item['formed']) + self.WINDOW.setProperty("%s.%d.Disbanded" % (request, count), item['disbanded']) + self.WINDOW.setProperty("%s.%d.YearsActive" % (request, count), " / ".join(item['yearsactive'])) + self.WINDOW.setProperty("%s.%d.Style" % (request, count), " / ".join(item['style'])) + self.WINDOW.setProperty("%s.%d.Mood" % (request, count), " / ".join(item['mood'])) + self.WINDOW.setProperty("%s.%d.Instrument" % (request, count), " / ".join(item['instrument'])) + self.WINDOW.setProperty("%s.%d.LibraryPath" % (request, count), path) - def _fetch_songs(self, request): - if not xbmc.abortRequested: - data = REQ.songs(request) - GUI.songs(request, data) + def _fetch_song(self, request): + if not self.Monitor.abortRequested(): + json_string = '{"jsonrpc": "2.0", "id": 1, "method": "AudioLibrary.GetSongs", "params": {"properties": ["title", "playcount", "artist", "album", "year", "file", "thumbnail", "fanart", "rating", "userrating"], "filter": {"field": "playcount", "operator": "lessthan", "value": "1"}, "limits": {"end": %d},' %self.LIMIT + if request == 'RandomSong' and self.RANDOMITEMS_UNPLAYED == "True": + json_query = xbmc.executeJSONRPC('%s "sort": {"method": "random"}}}' %json_string) + else: + json_query = xbmc.executeJSONRPC('%s "sort": {"method": "random"}}}' %json_string) + json_query = simplejson.loads(json_query) + if 'result' in json_query and 'songs' in json_query['result']: + self._clear_properties(request) + count = 0 + for item in json_query['result']['songs']: + count += 1 + play = 'XBMC.RunScript(' + __addonid__ + ',songid=' + str(item.get('songid')) + ')' + path = media_path(item['file']) + self.WINDOW.setProperty("%s.%d.Title" % (request, count), item['title']) + self.WINDOW.setProperty("%s.%d.Artist" % (request, count), " / ".join(item['artist'])) + self.WINDOW.setProperty("%s.%d.Year" % (request, count), str(item['year'])) + self.WINDOW.setProperty("%s.%d.Rating" % (request, count), str(int(item['rating'])-48)) + self.WINDOW.setProperty("%s.%d.Userrating" % (request, count), str(item['userrating'])) + self.WINDOW.setProperty("%s.%d.Album" % (request, count), item['album']) + self.WINDOW.setProperty("%s.%d.Thumb" % (request, count), item['thumbnail']) #remove + self.WINDOW.setProperty("%s.%d.Fanart" % (request, count), item['fanart']) #remove + self.WINDOW.setProperty("%s.%d.Art(thumb)" % (request, count), item['thumbnail']) + self.WINDOW.setProperty("%s.%d.Art(fanart)" % (request, count), item['fanart']) + self.WINDOW.setProperty("%s.%d.File" % (request, count), item['file']) + self.WINDOW.setProperty("%s.%d.Path" % (request, count), path) + self.WINDOW.setProperty("%s.%d.Play" % (request, count), play) + del json_query - def _fetch_addons(self, request): - if not xbmc.abortRequested: - data = REQ.addons(request) - GUI.addons(request, data) + def _fetch_addon(self, request): + if not self.Monitor.abortRequested(): + json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "Addons.GetAddons", "params": {"properties": ["name", "author", "summary", "version", "fanart", "thumbnail"]}, "id": 1}') + json_query = simplejson.loads(json_query) + if 'result' in json_query and 'addons' in json_query['result']: + # find plugins and scripts + addonlist = [] + for item in json_query['result']['addons']: + if item['type'] == 'xbmc.python.script' or item['type'] == 'xbmc.python.pluginsource': + addonlist.append(item) + # randomize the list + random.shuffle(addonlist) + self._clear_properties(request) + count = 0 + for item in addonlist: + count += 1 + self.WINDOW.setProperty("%s.%d.Title" % (request, count), item['name']) + self.WINDOW.setProperty("%s.%d.Author" % (request, count), item['author']) + self.WINDOW.setProperty("%s.%d.Summary" % (request, count), item['summary']) + self.WINDOW.setProperty("%s.%d.Version" % (request, count), item['version']) + self.WINDOW.setProperty("%s.%d.Path" % (request, count), item['addonid']) + self.WINDOW.setProperty("%s.%d.Thumb" % (request, count), item['thumbnail']) #remove + self.WINDOW.setProperty("%s.%d.Fanart" % (request, count), item['fanart']) #remove + self.WINDOW.setProperty("%s.%d.Art(thumb)" % (request, count), item['thumbnail']) + self.WINDOW.setProperty("%s.%d.Art(fanart)" % (request, count), item['fanart']) + self.WINDOW.setProperty("%s.%d.Type" % (request, count), item['type']) + # stop if we've reached the number of items we need + if count == self.LIMIT: + break + self.WINDOW.setProperty("%s.Count" % (request), str(json_query['result']['limits']['total'])) + del json_query def _daemon(self): # deamon is meant to keep script running at all time count = 0 home_update = False - while (not xbmc.abortRequested) and WINDOW.getProperty('SkinWidgets_Running') == 'true': - xbmc.sleep(500) + while (not self.Monitor.abortRequested()) and self.WINDOW.getProperty('SkinWidgets_Running') == 'true': + if self.Monitor.waitForAbort(1): + break if not xbmc.Player().isPlayingVideo(): if self.RANDOMITEMS_UPDATE_METHOD == 0: count += 1 if count == self.RANDOMITEMS_TIME: self._fetch_info_randomitems() count = 0 # reset counter - if WINDOW.getProperty('SkinWidgets_RandomItems_Update') == 'true': + if self.WINDOW.getProperty('SkinWidgets_RandomItems_Update') == 'true': count = 0 - WINDOW.setProperty('SkinWidgets_RandomItems_Update','false') + self.WINDOW.setProperty('SkinWidgets_RandomItems_Update','false') self._fetch_info_randomitems() if self.RECENTITEMS_HOME_UPDATE == 'true' and home_update and xbmcgui.getCurrentWindowId() == 10000: self._fetch_info_recentitems() home_update = False elif self.RECENTITEMS_HOME_UPDATE == 'true' and not home_update and xbmcgui.getCurrentWindowId() != 10000: home_update = True + else: + self.Monitor.update_listitems = None + self.Monitor.update_settings = None + self.Player.action = None + + def _clear_properties(self, request): + count = 0 + for count in range(int(self.LIMIT)): + count += 1 + self.WINDOW.clearProperty("%s.%d.Title" % (request, count)) def _update(self, type): xbmc.sleep(1000) @@ -210,15 +638,15 @@ def _update(self, type): self._fetch_movies('RecommendedMovie') self._fetch_movies('RecentMovie') elif type == 'episode': - self._fetch_episodes_recommended('RecommendedEpisode') + self._fetch_tvshows_recommended('RecommendedEpisode') self._fetch_tvshows('RecentEpisode') elif type == 'video': #only on db update self._fetch_movies('RecommendedMovie') - self._fetch_episodes_recommended('RecommendedEpisode') + self._fetch_tvshows_recommended('RecommendedEpisode') self._fetch_movies('RecentMovie') self._fetch_tvshows('RecentEpisode') - self._fetch_musicvideos('RecentMusicVideo') + self._fetch_musicvideo('RecentMusicVideo') elif type == 'music': self._fetch_albums('RecommendedAlbum') self._fetch_albums('RecentAlbum') @@ -227,13 +655,84 @@ def _update(self, type): if type == 'video': self._fetch_movies('RandomMovie') self._fetch_tvshows('RandomEpisode') - self._fetch_musicvideos('RandomMusicVideo') + self._fetch_musicvideo('RandomMusicVideo') elif type == 'music': self._fetch_albums('RandomAlbum') - self._fetch_artists('RandomArtist') - self._fetch_songs('RandomSong') - self._fetch_addons('RandomAddon') + self._fetch_artist('RandomArtist') + self._fetch_song('RandomSong') + self._fetch_addon('RandomAddon') + +def media_path(path): + # Check for stacked movies + try: + path = os.path.split(path)[0].rsplit(' , ', 1)[1].replace(",,",",") + except: + path = os.path.split(path)[0] + # Fixes problems with rared movies and multipath + if path.startswith("rar://"): + path = [os.path.split(urllib.request.url2pathname(path.replace("rar://","")))[0]] + elif path.startswith("multipath://"): + temp_path = path.replace("multipath://","").split('%2f/') + path = [] + for item in temp_path: + path.append(urllib.request.url2pathname(item)) + else: + path = [path] + return path[0] + +def media_streamdetails(filename, streamdetails): + info = {} + video = streamdetails['video'] + audio = streamdetails['audio'] + if '3d' in filename: + info['videoresolution'] = '3d' + elif video: + videowidth = video[0]['width'] + videoheight = video[0]['height'] + if (video[0]['width'] <= 720 and video[0]['height'] <= 480): + info['videoresolution'] = "480" + elif (video[0]['width'] <= 768 and video[0]['height'] <= 576): + info['videoresolution'] = "576" + elif (video[0]['width'] <= 960 and video[0]['height'] <= 544): + info['videoresolution'] = "540" + elif (video[0]['width'] <= 1280 and video[0]['height'] <= 720): + info['videoresolution'] = "720" + elif (video[0]['width'] >= 1281 or video[0]['height'] >= 721): + info['videoresolution'] = "1080" + else: + info['videoresolution'] = "" + elif (('dvd') in filename and not ('hddvd' or 'hd-dvd') in filename) or (filename.endswith('.vob' or '.ifo')): + info['videoresolution'] = '576' + elif (('bluray' or 'blu-ray' or 'brrip' or 'bdrip' or 'hddvd' or 'hd-dvd') in filename): + info['videoresolution'] = '1080' + else: + info['videoresolution'] = '1080' + if video: + info['videocodec'] = video[0]['codec'] + if (video[0]['aspect'] < 1.4859): + info['videoaspect'] = "1.33" + elif (video[0]['aspect'] < 1.7190): + info['videoaspect'] = "1.66" + elif (video[0]['aspect'] < 1.8147): + info['videoaspect'] = "1.78" + elif (video[0]['aspect'] < 2.0174): + info['videoaspect'] = "1.85" + elif (video[0]['aspect'] < 2.2738): + info['videoaspect'] = "2.20" + else: + info['videoaspect'] = "2.35" + else: + info['videocodec'] = '' + info['videoaspect'] = '' + if audio: + info['audiocodec'] = audio[0]['codec'] + info['audiochannels'] = audio[0]['channels'] + else: + info['audiocodec'] = '' + info['audiochannels'] = '' + return info + class Widgets_Monitor(xbmc.Monitor): def __init__(self, *args, **kwargs): xbmc.Monitor.__init__(self) @@ -291,9 +790,9 @@ def onPlayBackStopped(self): self.type = "" if (__name__ == "__main__"): - log('script version %s started' % __version__) + log('script version %s started' % __addonversion__) Main() del Widgets_Monitor del Widgets_Player del Main - log('script version %s stopped' % __version__) + log('script version %s stopped' % __addonversion__) diff --git a/lib/__init__.py b/lib/__init__.py deleted file mode 100644 index 153912c..0000000 --- a/lib/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# Copyright (C) 2012-2013 Team-XBMC -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -from common import * \ No newline at end of file diff --git a/lib/common.py b/lib/common.py deleted file mode 100644 index e500e92..0000000 --- a/lib/common.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# Copyright (C) 2012-2013 Team-XBMC -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -import xbmc -import xbmcaddon - -### get addon info -__addon__ = xbmcaddon.Addon(id='service.skin.widgets') -__addonid__ = __addon__.getAddonInfo('id') -__addonname__ = __addon__.getAddonInfo('name') -__author__ = __addon__.getAddonInfo('author') -__version__ = __addon__.getAddonInfo('version') -__addonpath__ = __addon__.getAddonInfo('path') -__addonprofile__= xbmc.translatePath(__addon__.getAddonInfo('profile')).decode('utf-8') -__icon__ = __addon__.getAddonInfo('icon') -__localize__ = __addon__.getLocalizedString - -def log(txt): - message = '%s: %s' % (__addonname__, txt.encode('ascii', 'ignore')) - xbmc.log(msg=message, level=xbmc.LOGDEBUG) \ No newline at end of file diff --git a/lib/properties.py b/lib/properties.py deleted file mode 100644 index d832b80..0000000 --- a/lib/properties.py +++ /dev/null @@ -1,404 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# Copyright (C) 2012-2013 Team-XBMC -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -import lib.common -from lib.utils import media_path, media_streamdetails -from lib.requests import req -import os -import random -import sys -import xbmc -import xbmcgui -import xbmcvfs -if sys.version_info < (2, 7): - import simplejson -else: - import json as simplejson - -__addon__ = lib.common.__addon__ -__addonid__ = lib.common.__addonid__ -__localize__ = lib.common.__localize__ - -WINDOW = xbmcgui.Window(10000) -LIMIT = 20 -PLOT_ENABLE = __addon__.getSetting("plot_enable") == 'true' - -class gui: - def movies(self, request, data): - if data: - clear_properties(request) - count = 0 - for item in data['result']['movies']: - count += 1 - if (item['resume']['position'] and item['resume']['total'])> 0: - resume = "true" - played = '%s%%'%int((float(item['resume']['position']) / float(item['resume']['total'])) * 100) - else: - resume = "false" - played = '0%' - if item['playcount'] >= 1: - watched = "true" - else: - watched = "false" - if not PLOT_ENABLE and watched == "false": - plot = __localize__(32014) - else: - plot = item['plot'] - art = item['art'] - path = media_path(item['file']) - play = 'XBMC.RunScript(' + __addonid__ + ',movieid=' + str(item.get('movieid')) + ')' - streaminfo = media_streamdetails(item['file'].encode('utf-8').lower(), - item['streamdetails']) - WINDOW.setProperty("%s.%d.DBID" % (request, count), str(item.get('movieid'))) - WINDOW.setProperty("%s.%d.Title" % (request, count), item['title']) - WINDOW.setProperty("%s.%d.OriginalTitle" % (request, count), item['originaltitle']) - WINDOW.setProperty("%s.%d.Year" % (request, count), str(item['year'])) - WINDOW.setProperty("%s.%d.Genre" % (request, count), " / ".join(item['genre'])) - WINDOW.setProperty("%s.%d.Studio" % (request, count), item['studio'][0]) - WINDOW.setProperty("%s.%d.Country" % (request, count), item['country'][0]) - WINDOW.setProperty("%s.%d.Plot" % (request, count), plot) - WINDOW.setProperty("%s.%d.PlotOutline" % (request, count), item['plotoutline']) - WINDOW.setProperty("%s.%d.Tagline" % (request, count), item['tagline']) - WINDOW.setProperty("%s.%d.Runtime" % (request, count), str(int((item['runtime'] / 60) + 0.5))) - WINDOW.setProperty("%s.%d.Rating" % (request, count), str(round(float(item['rating']),1))) - WINDOW.setProperty("%s.%d.mpaa" % (request, count), item['mpaa']) - WINDOW.setProperty("%s.%d.Director" % (request, count), " / ".join(item['director'])) - WINDOW.setProperty("%s.%d.Trailer" % (request, count), item['trailer']) - WINDOW.setProperty("%s.%d.Art(poster)" % (request, count), art.get('poster','')) - WINDOW.setProperty("%s.%d.Art(fanart)" % (request, count), art.get('fanart','')) - WINDOW.setProperty("%s.%d.Art(clearlogo)" % (request, count), art.get('clearlogo','')) - WINDOW.setProperty("%s.%d.Art(clearart)" % (request, count), art.get('clearart','')) - WINDOW.setProperty("%s.%d.Art(landscape)" % (request, count), art.get('landscape','')) - WINDOW.setProperty("%s.%d.Art(banner)" % (request, count), art.get('banner','')) - WINDOW.setProperty("%s.%d.Art(discart)" % (request, count), art.get('discart','')) - WINDOW.setProperty("%s.%d.Resume" % (request, count), resume) - WINDOW.setProperty("%s.%d.PercentPlayed" % (request, count), played) - WINDOW.setProperty("%s.%d.Watched" % (request, count), watched) - WINDOW.setProperty("%s.%d.File" % (request, count), item['file']) - WINDOW.setProperty("%s.%d.Path" % (request, count), path) - WINDOW.setProperty("%s.%d.Play" % (request, count), play) - WINDOW.setProperty("%s.%d.VideoCodec" % (request, count), streaminfo['videocodec']) - WINDOW.setProperty("%s.%d.VideoResolution" % (request, count), streaminfo['videoresolution']) - WINDOW.setProperty("%s.%d.VideoAspect" % (request, count), streaminfo['videoaspect']) - WINDOW.setProperty("%s.%d.AudioCodec" % (request, count), streaminfo['audiocodec']) - WINDOW.setProperty("%s.%d.AudioChannels" % (request, count), str(streaminfo['audiochannels'])) - del data - - def episodes_recommended(self, request, data): - if data: - clear_properties(request) - count = 0 - for item in data['result']['tvshows']: - if xbmc.abortRequested: - break - count += 1 - data2 = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": {"tvshowid": %d, "properties": ["title", "playcount", "plot", "season", "episode", "showtitle", "file", "lastplayed", "rating", "resume", "art", "streamdetails", "firstaired", "runtime"], "sort": {"method": "episode"}, "filter": {"field": "playcount", "operator": "is", "value": "0"}, "limits": {"end": 1}}, "id": 1}' %item['tvshowid']) - data2 = unicode(data2, 'utf-8', errors='ignore') - data2 = simplejson.loads(data2) - if data2.has_key('result') and data2['result'] != None and data2['result'].has_key('episodes'): - for item2 in data2['result']['episodes']: - episode = ("%.2d" % float(item2['episode'])) - season = "%.2d" % float(item2['season']) - rating = str(round(float(item2['rating']),1)) - episodeno = "s%se%s" %(season,episode) - art2 = item2['art'] - - #seasonthumb = '' - if (item2['resume']['position'] and item2['resume']['total']) > 0: - resume = "true" - played = '%s%%'%int((float(item2['resume']['position']) / float(item2['resume']['total'])) * 100) - else: - resume = "false" - played = '0%' - if item2['playcount'] >= 1: - watched = "true" - else: - watched = "false" - if not PLOT_ENABLE and watched == "false": - plot = __localize__(32014) - else: - plot = item2['plot'] - art = item['art'] - path = media_path(item['file']) - play = 'XBMC.RunScript(' + __addonid__ + ',episodeid=' + str(item2.get('episodeid')) + ')' - streaminfo = media_streamdetails(item['file'].encode('utf-8').lower(), - item2['streamdetails']) - WINDOW.setProperty("%s.%d.DBID" % (request, count), str(item2.get('episodeid'))) - WINDOW.setProperty("%s.%d.Title" % (request, count), item2['title']) - WINDOW.setProperty("%s.%d.Episode" % (request, count), episode) - WINDOW.setProperty("%s.%d.EpisodeNo" % (request, count), episodeno) - WINDOW.setProperty("%s.%d.Season" % (request, count), season) - WINDOW.setProperty("%s.%d.Plot" % (request, count), plot) - WINDOW.setProperty("%s.%d.TVshowTitle" % (request, count), item2['showtitle']) - WINDOW.setProperty("%s.%d.Rating" % (request, count), rating) - WINDOW.setProperty("%s.%d.Runtime" % (request, count), str(int((item2['runtime'] / 60) + 0.5))) - WINDOW.setProperty("%s.%d.Premiered" % (request, count), item2['firstaired']) - WINDOW.setProperty("%s.%d.Art(thumb)" % (request, count), art2.get('thumb','')) - WINDOW.setProperty("%s.%d.Art(tvshow.fanart)" % (request, count), art2.get('tvshow.fanart','')) - WINDOW.setProperty("%s.%d.Art(tvshow.poster)" % (request, count), art2.get('tvshow.poster','')) - WINDOW.setProperty("%s.%d.Art(tvshow.banner)" % (request, count), art2.get('tvshow.banner','')) - WINDOW.setProperty("%s.%d.Art(tvshow.clearlogo)"% (request, count), art2.get('tvshow.clearlogo','')) - WINDOW.setProperty("%s.%d.Art(tvshow.clearart)" % (request, count), art2.get('tvshow.clearart','')) - WINDOW.setProperty("%s.%d.Art(tvshow.landscape)"% (request, count), art2.get('tvshow.landscape','')) - WINDOW.setProperty("%s.%d.Art(tvshow.characterart)"% (request, count), art2.get('tvshow.characterart','')) - #WINDOW.setProperty("%s.%d.Art(season.poster)" % (request, count), seasonthumb) - WINDOW.setProperty("%s.%d.Studio" % (request, count), item['studio'][0]) - WINDOW.setProperty("%s.%d.mpaa" % (request, count), item['mpaa']) - WINDOW.setProperty("%s.%d.Resume" % (request, count), resume) - WINDOW.setProperty("%s.%d.PercentPlayed" % (request, count), played) - WINDOW.setProperty("%s.%d.Watched" % (request, count), watched) - WINDOW.setProperty("%s.%d.File" % (request, count), item2['file']) - WINDOW.setProperty("%s.%d.Path" % (request, count), path) - WINDOW.setProperty("%s.%d.Play" % (request, count), play) - WINDOW.setProperty("%s.%d.VideoCodec" % (request, count), streaminfo['videocodec']) - WINDOW.setProperty("%s.%d.VideoResolution" % (request, count), streaminfo['videoresolution']) - WINDOW.setProperty("%s.%d.VideoAspect" % (request, count), streaminfo['videoaspect']) - WINDOW.setProperty("%s.%d.AudioCodec" % (request, count), streaminfo['audiocodec']) - WINDOW.setProperty("%s.%d.AudioChannels" % (request, count), str(streaminfo['audiochannels'])) - del data2 - del data - - def episodes(self, request, data): - if data: - season_folders = __addon__.getSetting("randomitems_seasonfolders") - clear_properties(request) - count = 0 - for item in data['result']['episodes']: - count += 1 - ''' - # This part is commented out because it takes 1.5second extra on my system to request these which doubles the total time. - # Hence the ugly path hack that will require users to have season folders. - data2 = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShowDetails", "params": {"properties": ["file", "studio"], "tvshowid":%s}, "id": 1}' %item['tvshowid']) - data2 = unicode(data2, 'utf-8', errors='ignore') - data2 = simplejson.loads(data2) - path = data2['result']['tvshowdetails']['file'] - studio = data2['result']['tvshowdetails']['studio'][0] - ''' - if season_folders == 'true': - path = os.path.split(media_path(item['file']))[0] - else: - path = media_path(item['file']) - episode = ("%.2d" % float(item['episode'])) - season = "%.2d" % float(item['season']) - episodeno = "s%se%s" %(season,episode) - #seasonthumb = '' - rating = str(round(float(item['rating']),1)) - if (item['resume']['position'] and item['resume']['total']) > 0: - resume = "true" - played = '%s%%'%int((float(item['resume']['position']) / float(item['resume']['total'])) * 100) - else: - resume = "false" - played = '0%' - if item['playcount'] >= 1: - watched = "true" - else: - watched = "false" - if not PLOT_ENABLE and watched == "false": - plot = __localize__(32014) - else: - plot = item['plot'] - art = item['art'] - path = media_path(item['file']) - play = 'XBMC.RunScript(' + __addonid__ + ',episodeid=' + str(item.get('episodeid')) + ')' - streaminfo = media_streamdetails(item['file'].encode('utf-8').lower(), - item['streamdetails']) - WINDOW.setProperty("%s.%d.DBID" % (request, count), str(item.get('episodeid'))) - WINDOW.setProperty("%s.%d.Title" % (request, count), item['title']) - WINDOW.setProperty("%s.%d.Episode" % (request, count), episode) - WINDOW.setProperty("%s.%d.EpisodeNo" % (request, count), episodeno) - WINDOW.setProperty("%s.%d.Season" % (request, count), season) - WINDOW.setProperty("%s.%d.Plot" % (request, count), plot) - WINDOW.setProperty("%s.%d.TVshowTitle" % (request, count), item['showtitle']) - WINDOW.setProperty("%s.%d.Rating" % (request, count), rating) - WINDOW.setProperty("%s.%d.Runtime" % (request, count), str(int((item['runtime'] / 60) + 0.5))) - WINDOW.setProperty("%s.%d.Premiered" % (request, count), item['firstaired']) - WINDOW.setProperty("%s.%d.Art(thumb)" % (request, count), art.get('thumb','')) - WINDOW.setProperty("%s.%d.Art(tvshow.fanart)" % (request, count), art.get('tvshow.fanart','')) - WINDOW.setProperty("%s.%d.Art(tvshow.poster)" % (request, count), art.get('tvshow.poster','')) - WINDOW.setProperty("%s.%d.Art(tvshow.banner)" % (request, count), art.get('tvshow.banner','')) - WINDOW.setProperty("%s.%d.Art(tvshow.clearlogo)"% (request, count), art.get('tvshow.clearlogo','')) - WINDOW.setProperty("%s.%d.Art(tvshow.clearart)" % (request, count), art.get('tvshow.clearart','')) - WINDOW.setProperty("%s.%d.Art(tvshow.landscape)"% (request, count), art.get('tvshow.landscape','')) - WINDOW.setProperty("%s.%d.Art(tvshow.characterart)"% (request, count), art.get('tvshow.characterart','')) - WINDOW.setProperty("%s.%d.Resume" % (request, count), resume) - WINDOW.setProperty("%s.%d.PercentPlayed" % (request, count), played) - WINDOW.setProperty("%s.%d.Watched" % (request, count), watched) - WINDOW.setProperty("%s.%d.File" % (request, count), item['file']) - WINDOW.setProperty("%s.%d.Path" % (request, count), path) - WINDOW.setProperty("%s.%d.Play" % (request, count), play) - WINDOW.setProperty("%s.%d.VideoCodec" % (request, count), streaminfo['videocodec']) - WINDOW.setProperty("%s.%d.VideoResolution" % (request, count), streaminfo['videoresolution']) - WINDOW.setProperty("%s.%d.VideoAspect" % (request, count), streaminfo['videoaspect']) - WINDOW.setProperty("%s.%d.AudioCodec" % (request, count), streaminfo['audiocodec']) - WINDOW.setProperty("%s.%d.AudioChannels" % (request, count), str(streaminfo['audiochannels'])) - del data - - def musicvideos(self, request, data): - if data: - clear_properties(request) - count = 0 - for item in data['result']['musicvideos']: - count += 1 - if (item['resume']['position'] and item['resume']['total'])> 0: - resume = "true" - played = '%s%%'%int((float(item['resume']['position']) / float(item['resume']['total'])) * 100) - else: - resume = "false" - played = '0%' - if item['playcount'] >= 1: - watched = "true" - else: - watched = "false" - play = 'XBMC.RunScript(' + __addonid__ + ',musicvideoid=' + str(item.get('musicvideoid')) + ')' - path = media_path(item['file']) - streaminfo = media_streamdetails(item['file'].encode('utf-8').lower(), - item['streamdetails']) - WINDOW.setProperty("%s.%d.DBID" % (request, count), str(item.get('musicvideoid'))) - WINDOW.setProperty("%s.%d.Title" % (request, count), item['title']) - WINDOW.setProperty("%s.%d.Artist" % (request, count), " / ".join(item['artist'])) - WINDOW.setProperty("%s.%d.Year" % (request, count), str(item['year'])) - WINDOW.setProperty("%s.%d.Plot" % (request, count), item['plot']) - WINDOW.setProperty("%s.%d.Genre" % (request, count), " / ".join(item['genre'])) - WINDOW.setProperty("%s.%d.Runtime" % (request, count), str(int((item['runtime'] / 60) + 0.5))) - WINDOW.setProperty("%s.%d.Thumb" % (request, count), item['thumbnail']) #remove - WINDOW.setProperty("%s.%d.Fanart" % (request, count), item['fanart']) #remove - WINDOW.setProperty("%s.%d.Art(thumb)" % (request, count), item['thumbnail']) - WINDOW.setProperty("%s.%d.Art(fanart)" % (request, count), item['fanart']) - WINDOW.setProperty("%s.%d.File" % (request, count), item['file']) - WINDOW.setProperty("%s.%d.Path" % (request, count), path) - WINDOW.setProperty("%s.%d.Resume" % (request, count), resume) - WINDOW.setProperty("%s.%d.PercentPlayed" % (request, count), played) - WINDOW.setProperty("%s.%d.Watched" % (request, count), watched) - WINDOW.setProperty("%s.%d.Play" % (request, count), play) - WINDOW.setProperty("%s.%d.VideoCodec" % (request, count), streaminfo['videocodec']) - WINDOW.setProperty("%s.%d.VideoResolution" % (request, count), streaminfo['videoresolution']) - WINDOW.setProperty("%s.%d.VideoAspect" % (request, count), streaminfo['videoaspect']) - WINDOW.setProperty("%s.%d.AudioCodec" % (request, count), streaminfo['audiocodec']) - WINDOW.setProperty("%s.%d.AudioChannels" % (request, count), str(streaminfo['audiochannels'])) - del data - - def albums(self, request, data): - if data: - clear_properties(request) - count = 0 - for item in data['result']['albums']: - count += 1 - rating = str(item['rating']) - if rating == '48': - rating = '' - play = 'XBMC.RunScript(' + __addonid__ + ',albumid=' + str(item.get('albumid')) + ')' - WINDOW.setProperty("%s.%d.Title" % (request, count), item['title']) - WINDOW.setProperty("%s.%d.Label" % (request, count), item['title']) #needs to be removed - WINDOW.setProperty("%s.%d.Artist" % (request, count), " / ".join(item['artist'])) - WINDOW.setProperty("%s.%d.Genre" % (request, count), " / ".join(item['genre'])) - WINDOW.setProperty("%s.%d.Theme" % (request, count), " / ".join(item['theme'])) - WINDOW.setProperty("%s.%d.Mood" % (request, count), " / ".join(item['mood'])) - WINDOW.setProperty("%s.%d.Style" % (request, count), " / ".join(item['style'])) - WINDOW.setProperty("%s.%d.Type" % (request, count), " / ".join(item['type'])) - WINDOW.setProperty("%s.%d.Year" % (request, count), str(item['year'])) - WINDOW.setProperty("%s.%d.RecordLabel" % (request, count), item['albumlabel']) - WINDOW.setProperty("%s.%d.Description" % (request, count), item['description']) - WINDOW.setProperty("%s.%d.Rating" % (request, count), rating) - WINDOW.setProperty("%s.%d.Thumb" % (request, count), item['thumbnail']) #remove - WINDOW.setProperty("%s.%d.Fanart" % (request, count), item['fanart']) #remove - WINDOW.setProperty("%s.%d.Art(thumb)" % (request, count), item['thumbnail']) - WINDOW.setProperty("%s.%d.Art(fanart)" % (request, count), item['fanart']) - WINDOW.setProperty("%s.%d.Play" % (request, count), play) - del data - - def artists(self, request, data): - if data: - clear_properties(request) - count = 0 - for item in data['result']['artists']: - count += 1 - path = 'musicdb://2/' + str(item['artistid']) + '/' - WINDOW.setProperty("%s.%d.Title" % (request, count), item['label']) - WINDOW.setProperty("%s.%d.Genre" % (request, count), " / ".join(item['genre'])) - WINDOW.setProperty("%s.%d.Thumb" % (request, count), item['thumbnail']) #remove - WINDOW.setProperty("%s.%d.Fanart" % (request, count), item['fanart']) #remove - WINDOW.setProperty("%s.%d.Art(thumb)" % (request, count), item['thumbnail']) - WINDOW.setProperty("%s.%d.Art(fanart)" % (request, count), item['fanart']) - WINDOW.setProperty("%s.%d.Description" % (request, count), item['description']) - WINDOW.setProperty("%s.%d.Born" % (request, count), item['born']) - WINDOW.setProperty("%s.%d.Died" % (request, count), item['died']) - WINDOW.setProperty("%s.%d.Formed" % (request, count), item['formed']) - WINDOW.setProperty("%s.%d.Disbanded" % (request, count), item['disbanded']) - WINDOW.setProperty("%s.%d.YearsActive" % (request, count), " / ".join(item['yearsactive'])) - WINDOW.setProperty("%s.%d.Style" % (request, count), " / ".join(item['style'])) - WINDOW.setProperty("%s.%d.Mood" % (request, count), " / ".join(item['mood'])) - WINDOW.setProperty("%s.%d.Instrument" % (request, count), " / ".join(item['instrument'])) - WINDOW.setProperty("%s.%d.LibraryPath" % (request, count), path) - - def songs(self, request, data): - if data: - clear_properties(request) - count = 0 - for item in data['result']['songs']: - count += 1 - play = 'XBMC.RunScript(' + __addonid__ + ',songid=' + str(item.get('songid')) + ')' - path = media_path(item['file']) - WINDOW.setProperty("%s.%d.Title" % (request, count), item['title']) - WINDOW.setProperty("%s.%d.Artist" % (request, count), " / ".join(item['artist'])) - WINDOW.setProperty("%s.%d.Year" % (request, count), str(item['year'])) - WINDOW.setProperty("%s.%d.Rating" % (request, count), str(int(item['rating'])-48)) - WINDOW.setProperty("%s.%d.Album" % (request, count), item['album']) - WINDOW.setProperty("%s.%d.Thumb" % (request, count), item['thumbnail']) #remove - WINDOW.setProperty("%s.%d.Fanart" % (request, count), item['fanart']) #remove - WINDOW.setProperty("%s.%d.Art(thumb)" % (request, count), item['thumbnail']) - WINDOW.setProperty("%s.%d.Art(fanart)" % (request, count), item['fanart']) - WINDOW.setProperty("%s.%d.File" % (request, count), item['file']) - WINDOW.setProperty("%s.%d.Path" % (request, count), path) - WINDOW.setProperty("%s.%d.Play" % (request, count), play) - del data - - def addons(self, request, data): - if data: - # find plugins and scripts - addonlist = [] - for item in data['result']['addons']: - if item['type'] == 'xbmc.python.script' or item['type'] == 'xbmc.python.pluginsource': - addonlist.append(item) - # randomize the list - random.shuffle(addonlist) - clear_properties(request) - count = 0 - for item in addonlist: - count += 1 - WINDOW.setProperty("%s.%d.Title" % (request, count), item['name']) - WINDOW.setProperty("%s.%d.Author" % (request, count), item['author']) - WINDOW.setProperty("%s.%d.Summary" % (request, count), item['summary']) - WINDOW.setProperty("%s.%d.Version" % (request, count), item['version']) - WINDOW.setProperty("%s.%d.Path" % (request, count), item['addonid']) - WINDOW.setProperty("%s.%d.Thumb" % (request, count), item['thumbnail']) #remove - WINDOW.setProperty("%s.%d.Fanart" % (request, count), item['fanart']) #remove - WINDOW.setProperty("%s.%d.Art(thumb)" % (request, count), item['thumbnail']) - WINDOW.setProperty("%s.%d.Art(fanart)" % (request, count), item['fanart']) - WINDOW.setProperty("%s.%d.Type" % (request, count), item['type']) - # stop if we've reached the number of items we need - if count == LIMIT: - break - WINDOW.setProperty("%s.Count" % (request), str(data['result']['limits']['total'])) - del data - -def clear_properties(request): - count = 0 - for count in range(int(LIMIT)): - count += 1 - WINDOW.clearProperty("%s.%d.Title" % (request, count)) diff --git a/lib/requests.py b/lib/requests.py deleted file mode 100644 index 7d95347..0000000 --- a/lib/requests.py +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# Copyright (C) 2012-2013 Team-XBMC -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -import lib.common -import sys -import xbmc -if sys.version_info < (2, 7): - import simplejson -else: - import json as simplejson - -__addon__ = lib.common.__addon__ -LIMIT = 20 -RANDOMITEMS_UNPLAYED = __addon__.getSetting("randomitems_unplayed") == 'true' -RECENTITEMS_UNPLAYED = __addon__.getSetting("recentitems_unplayed") == 'true' - -class req: - def movies(self, request): - json_string = '{"jsonrpc": "2.0", "id": 1, "method": "VideoLibrary.GetMovies", "params": {"properties": ["title", "originaltitle", "playcount", "year", "genre", "studio", "country", "tagline", "plot", "runtime", "file", "plotoutline", "lastplayed", "trailer", "rating", "resume", "art", "streamdetails", "mpaa", "director", "votes"], "limits": {"end": %d},' %LIMIT - if request == 'RecommendedMovie': - json_query = xbmc.executeJSONRPC('%s "sort": {"order": "descending", "method": "lastplayed"}, "filter": {"field": "inprogress", "operator": "true", "value": ""}}}' %json_string) - elif request == 'RecentMovie' and RECENTITEMS_UNPLAYED: - json_query = xbmc.executeJSONRPC('%s "sort": {"order": "descending", "method": "dateadded"}, "filter": {"field": "playcount", "operator": "is", "value": "0"}}}' %json_string) - elif request == 'RecentMovie': - json_query = xbmc.executeJSONRPC('%s "sort": {"order": "descending", "method": "dateadded"}}}' %json_string) - elif request == "RandomMovie" and RANDOMITEMS_UNPLAYED: - json_query = xbmc.executeJSONRPC('%s "sort": {"method": "random" }, "filter": {"field": "playcount", "operator": "lessthan", "value": "1"}}}' %json_string) - else: - json_query = xbmc.executeJSONRPC('%s "sort": {"method": "random" } }}' %json_string) - json_query = unicode(json_query, 'utf-8', errors='ignore') - json_query = simplejson.loads(json_query) - if json_query.has_key('result') and json_query['result'].has_key('movies'): - return json_query - else: - return False - - def episodes(self, request): - json_string = '{"jsonrpc": "2.0", "id": 1, "method": "VideoLibrary.GetEpisodes", "params": { "properties": ["title", "playcount", "season", "episode", "showtitle", "plot", "file", "rating", "resume", "tvshowid", "art", "streamdetails", "firstaired", "runtime"], "limits": {"end": %d},' %LIMIT - if request == 'RecentEpisode' and RECENTITEMS_UNPLAYED: - json_query = xbmc.executeJSONRPC('%s "sort": {"order": "descending", "method": "dateadded"}, "filter": {"field": "playcount", "operator": "lessthan", "value": "1"}}}' %json_string) - elif request == 'RecentEpisode': - json_query = xbmc.executeJSONRPC('%s "sort": {"order": "descending", "method": "dateadded"}}}' %json_string) - elif request == 'RandomEpisode' and RANDOMITEMS_UNPLAYED: - json_query = xbmc.executeJSONRPC('%s "sort": {"method": "random" }, "filter": {"field": "playcount", "operator": "lessthan", "value": "1"}}}' %json_string) - else: - json_query = xbmc.executeJSONRPC('%s "sort": {"method": "random" }}}' %json_string) - json_query = unicode(json_query, 'utf-8', errors='ignore') - json_query = simplejson.loads(json_query) - if json_query.has_key('result') and json_query['result'].has_key('episodes'): - return json_query - else: - return False - - def episodes_recommended(self, request): - if not xbmc.abortRequested: - # First unplayed episode of recent played tvshows - json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": {"properties": ["title", "studio", "mpaa", "file", "art"], "sort": {"order": "descending", "method": "lastplayed"}, "filter": {"field": "inprogress", "operator": "true", "value": ""}, "limits": {"end": %d}}, "id": 1}' %LIMIT) - json_query = unicode(json_query, 'utf-8', errors='ignore') - json_query = simplejson.loads(json_query) - if json_query.has_key('result') and json_query['result'].has_key('tvshows'): - return json_query - else: - return False - - def seasonthumb(self, tvshowid, seasonnumber): - json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetSeasons", "params": {"properties": ["season", "thumbnail"], "tvshowid":%s }, "id": 1}' % tvshowid) - json_query = unicode(json_query, 'utf-8', errors='ignore') - json_query = simplejson.loads(json_query) - if json_query.has_key('result') and json_query['result'].has_key('seasons'): - for item in json_query['result']['seasons']: - season = "%.2d" % float(item['season']) - if season == seasonnumber: - thumbnail = item['thumbnail'] - return thumbnail - - def musicvideos(self, request): - json_string = '{"jsonrpc": "2.0", "id": 1, "method": "VideoLibrary.GetMusicVideos", "params": {"properties": ["title", "artist", "playcount", "year", "plot", "genre", "runtime", "fanart", "thumbnail", "file", "streamdetails", "resume"], "limits": {"end": %d},' %LIMIT - if request == 'RecommendedMusicVideo': - json_query = xbmc.executeJSONRPC('%s "sort": {"order": "descending", "method": "playcount" }}}' %json_string) - elif request == 'RecentMusicVideo': - json_query = xbmc.executeJSONRPC('%s "sort": {"order": "descending", "method": "dateadded"}}}' %json_string) - else: - json_query = xbmc.executeJSONRPC('%s "sort": {"method": "random"}}}' %json_string) - json_query = unicode(json_query, 'utf-8', errors='ignore') - json_query = simplejson.loads(json_query) - if json_query.has_key('result') and json_query['result'].has_key('musicvideos'): - return json_query - else: - return False - - def albums(self, request): - json_string = '{"jsonrpc": "2.0", "id": 1, "method": "AudioLibrary.GetAlbums", "params": {"properties": ["title", "description", "albumlabel", "theme", "mood", "style", "type", "artist", "genre", "year", "thumbnail", "fanart", "rating", "playcount"], "limits": {"end": %d},' %LIMIT - if request == 'RecommendedAlbum': - json_query = xbmc.executeJSONRPC('%s "sort": {"order": "descending", "method": "playcount" }}}' %json_string) - elif request == 'RecentAlbum': - json_query = xbmc.executeJSONRPC('%s "sort": {"order": "descending", "method": "dateadded" }}}' %json_string) - else: - json_query = xbmc.executeJSONRPC('%s "sort": {"method": "random"}}}' %json_string) - json_query = unicode(json_query, 'utf-8', errors='ignore') - json_query = simplejson.loads(json_query) - if json_query.has_key('result') and json_query['result'].has_key('albums'): - return json_query - else: - return False - - def artist(self, request): - # Random artist - json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "AudioLibrary.GetArtists", "params": {"properties": ["genre", "description", "mood", "style", "born", "died", "formed", "disbanded", "yearsactive", "instrument", "fanart", "thumbnail"], "sort": {"method": "random"}, "limits": {"end": %d}}, "id": 1}' %LIMIT) - json_query = unicode(json_query, 'utf-8', errors='ignore') - json_query = simplejson.loads(json_query) - if json_query.has_key('result') and json_query['result'].has_key('artists'): - return json_query - else: - return False - - def songs(self, request): - json_string = '{"jsonrpc": "2.0", "id": 1, "method": "AudioLibrary.GetSongs", "params": {"properties": ["title", "playcount", "genre", "artist", "album", "year", "file", "thumbnail", "fanart", "rating"], "filter": {"field": "playcount", "operator": "lessthan", "value": "1"}, "limits": {"end": %d},' %LIMIT - if request == 'RandomSong' and RANDOMITEMS_UNPLAYED == "True": - json_query = xbmc.executeJSONRPC('%s "sort": {"method": "random"}}}' %json_string) - else: - json_query = xbmc.executeJSONRPC('%s "sort": {"method": "random"}}}' %json_string) - json_query = unicode(json_query, 'utf-8', errors='ignore') - json_query = simplejson.loads(json_query) - if json_query.has_key('result') and json_query['result'].has_key('songs'): - return json_query - else: - return False - - def addons(self, request): - json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "Addons.GetAddons", "params": {"properties": ["name", "author", "summary", "version", "fanart", "thumbnail"]}, "id": 1}') - json_query = unicode(json_query, 'utf-8', errors='ignore') - json_query = simplejson.loads(json_query) - if json_query.has_key('result') and json_query['result'].has_key('addons'): - return json_query - else: - return False \ No newline at end of file diff --git a/lib/utils.py b/lib/utils.py deleted file mode 100644 index 338f6a3..0000000 --- a/lib/utils.py +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# Copyright (C) 2012-2013 Team-XBMC -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -import os -import urllib - -def media_path(path): - # Check for stacked movies - try: - path = os.path.split(path)[0].rsplit(' , ', 1)[1].replace(",,",",") - except: - path = os.path.split(path)[0] - # Fixes problems with rared movies and multipath - if path.startswith("rar://"): - path = [os.path.split(urllib.url2pathname(path.replace("rar://","")))[0]] - elif path.startswith("multipath://"): - temp_path = path.replace("multipath://","").split('%2f/') - path = [] - for item in temp_path: - path.append(urllib.url2pathname(item)) - else: - path = [path] - return path[0] - -def media_streamdetails(filename, streamdetails): - info = {} - video = streamdetails['video'] - audio = streamdetails['audio'] - if '3d' in filename: - info['videoresolution'] = '3d' - elif video: - videowidth = video[0]['width'] - videoheight = video[0]['height'] - if (video[0]['width'] <= 720 and video[0]['height'] <= 480): - info['videoresolution'] = "480" - elif (video[0]['width'] <= 768 and video[0]['height'] <= 576): - info['videoresolution'] = "576" - elif (video[0]['width'] <= 960 and video[0]['height'] <= 544): - info['videoresolution'] = "540" - elif (video[0]['width'] <= 1280 and video[0]['height'] <= 720): - info['videoresolution'] = "720" - elif (video[0]['width'] >= 1281 or video[0]['height'] >= 721): - info['videoresolution'] = "1080" - else: - info['videoresolution'] = "" - elif (('dvd') in filename and not ('hddvd' or 'hd-dvd') in filename) or (filename.endswith('.vob' or '.ifo')): - info['videoresolution'] = '576' - elif (('bluray' or 'blu-ray' or 'brrip' or 'bdrip' or 'hddvd' or 'hd-dvd') in filename): - info['videoresolution'] = '1080' - else: - info['videoresolution'] = '1080' - if video: - info['videocodec'] = video[0]['codec'] - if (video[0]['aspect'] < 1.4859): - info['videoaspect'] = "1.33" - elif (video[0]['aspect'] < 1.7190): - info['videoaspect'] = "1.66" - elif (video[0]['aspect'] < 1.8147): - info['videoaspect'] = "1.78" - elif (video[0]['aspect'] < 2.0174): - info['videoaspect'] = "1.85" - elif (video[0]['aspect'] < 2.2738): - info['videoaspect'] = "2.20" - else: - info['videoaspect'] = "2.35" - else: - info['videocodec'] = '' - info['videoaspect'] = '' - if audio: - info['audiocodec'] = audio[0]['codec'] - info['audiochannels'] = audio[0]['channels'] - else: - info['audiocodec'] = '' - info['audiochannels'] = '' - return info \ No newline at end of file diff --git a/icon.png b/resources/icon.png similarity index 100% rename from icon.png rename to resources/icon.png diff --git a/resources/language/Afrikaans/strings.po b/resources/language/resource.language.af_za/strings.po similarity index 100% rename from resources/language/Afrikaans/strings.po rename to resources/language/resource.language.af_za/strings.po diff --git a/resources/language/Amharic/strings.po b/resources/language/resource.language.am_et/strings.po similarity index 100% rename from resources/language/Amharic/strings.po rename to resources/language/resource.language.am_et/strings.po diff --git a/resources/language/Arabic/strings.po b/resources/language/resource.language.ar_sa/strings.po similarity index 100% rename from resources/language/Arabic/strings.po rename to resources/language/resource.language.ar_sa/strings.po diff --git a/resources/language/Belarusian/strings.po b/resources/language/resource.language.be_by/strings.po similarity index 100% rename from resources/language/Belarusian/strings.po rename to resources/language/resource.language.be_by/strings.po diff --git a/resources/language/Bulgarian/strings.po b/resources/language/resource.language.bg_bg/strings.po similarity index 100% rename from resources/language/Bulgarian/strings.po rename to resources/language/resource.language.bg_bg/strings.po diff --git a/resources/language/Bosnian/strings.po b/resources/language/resource.language.bs_ba/strings.po similarity index 100% rename from resources/language/Bosnian/strings.po rename to resources/language/resource.language.bs_ba/strings.po diff --git a/resources/language/Catalan/strings.po b/resources/language/resource.language.ca_es/strings.po similarity index 100% rename from resources/language/Catalan/strings.po rename to resources/language/resource.language.ca_es/strings.po diff --git a/resources/language/Czech/strings.po b/resources/language/resource.language.cs_cz/strings.po similarity index 100% rename from resources/language/Czech/strings.po rename to resources/language/resource.language.cs_cz/strings.po diff --git a/resources/language/Danish/strings.po b/resources/language/resource.language.da_dk/strings.po similarity index 100% rename from resources/language/Danish/strings.po rename to resources/language/resource.language.da_dk/strings.po diff --git a/resources/language/German/strings.po b/resources/language/resource.language.de_de/strings.po similarity index 100% rename from resources/language/German/strings.po rename to resources/language/resource.language.de_de/strings.po diff --git a/resources/language/Greek/strings.po b/resources/language/resource.language.el_gr/strings.po similarity index 100% rename from resources/language/Greek/strings.po rename to resources/language/resource.language.el_gr/strings.po diff --git a/resources/language/English/strings.po b/resources/language/resource.language.en_gb/strings.po similarity index 97% rename from resources/language/English/strings.po rename to resources/language/resource.language.en_gb/strings.po index 04e1dfe..5456e8f 100644 --- a/resources/language/English/strings.po +++ b/resources/language/resource.language.en_gb/strings.po @@ -24,8 +24,6 @@ msgctxt "#32002" msgid "Random Items" msgstr "" -#empty string with id 32003 - msgctxt "#32004" msgid "Randomize time (minutes)" msgstr "" diff --git a/resources/language/Esperanto/strings.po b/resources/language/resource.language.eo/strings.po similarity index 100% rename from resources/language/Esperanto/strings.po rename to resources/language/resource.language.eo/strings.po diff --git a/resources/language/Spanish (Argentina)/strings.po b/resources/language/resource.language.es_ar/strings.po similarity index 100% rename from resources/language/Spanish (Argentina)/strings.po rename to resources/language/resource.language.es_ar/strings.po diff --git a/resources/language/Spanish/strings.po b/resources/language/resource.language.es_es/strings.po similarity index 100% rename from resources/language/Spanish/strings.po rename to resources/language/resource.language.es_es/strings.po diff --git a/resources/language/Spanish (Mexico)/strings.po b/resources/language/resource.language.es_mx/strings.po similarity index 100% rename from resources/language/Spanish (Mexico)/strings.po rename to resources/language/resource.language.es_mx/strings.po diff --git a/resources/language/Estonian/strings.po b/resources/language/resource.language.et_ee/strings.po similarity index 100% rename from resources/language/Estonian/strings.po rename to resources/language/resource.language.et_ee/strings.po diff --git a/resources/language/Basque/strings.po b/resources/language/resource.language.eu_es/strings.po similarity index 100% rename from resources/language/Basque/strings.po rename to resources/language/resource.language.eu_es/strings.po diff --git a/resources/language/Persian/strings.po b/resources/language/resource.language.fa_af/strings.po similarity index 100% rename from resources/language/Persian/strings.po rename to resources/language/resource.language.fa_af/strings.po diff --git a/resources/language/Persian (Iran)/strings.po b/resources/language/resource.language.fa_ir/strings.po similarity index 100% rename from resources/language/Persian (Iran)/strings.po rename to resources/language/resource.language.fa_ir/strings.po diff --git a/resources/language/Finnish/strings.po b/resources/language/resource.language.fi_fi/strings.po similarity index 100% rename from resources/language/Finnish/strings.po rename to resources/language/resource.language.fi_fi/strings.po diff --git a/resources/language/French/strings.po b/resources/language/resource.language.fr_fr/strings.po similarity index 100% rename from resources/language/French/strings.po rename to resources/language/resource.language.fr_fr/strings.po diff --git a/resources/language/Galician/strings.po b/resources/language/resource.language.gl_es/strings.po similarity index 100% rename from resources/language/Galician/strings.po rename to resources/language/resource.language.gl_es/strings.po diff --git a/resources/language/Hebrew/strings.po b/resources/language/resource.language.he_il/strings.po similarity index 100% rename from resources/language/Hebrew/strings.po rename to resources/language/resource.language.he_il/strings.po diff --git a/resources/language/Hindi (Devanagiri)/strings.po b/resources/language/resource.language.hi_in/strings.po similarity index 100% rename from resources/language/Hindi (Devanagiri)/strings.po rename to resources/language/resource.language.hi_in/strings.po diff --git a/resources/language/Croatian/strings.po b/resources/language/resource.language.hr_hr/strings.po similarity index 100% rename from resources/language/Croatian/strings.po rename to resources/language/resource.language.hr_hr/strings.po diff --git a/resources/language/Hungarian/strings.po b/resources/language/resource.language.hu_hu/strings.po similarity index 100% rename from resources/language/Hungarian/strings.po rename to resources/language/resource.language.hu_hu/strings.po diff --git a/resources/language/Indonesian/strings.po b/resources/language/resource.language.id_id/strings.po similarity index 100% rename from resources/language/Indonesian/strings.po rename to resources/language/resource.language.id_id/strings.po diff --git a/resources/language/Icelandic/strings.po b/resources/language/resource.language.is_is/strings.po similarity index 100% rename from resources/language/Icelandic/strings.po rename to resources/language/resource.language.is_is/strings.po diff --git a/resources/language/Italian/strings.po b/resources/language/resource.language.it_it/strings.po similarity index 100% rename from resources/language/Italian/strings.po rename to resources/language/resource.language.it_it/strings.po diff --git a/resources/language/Japanese/strings.po b/resources/language/resource.language.ja_jp/strings.po similarity index 100% rename from resources/language/Japanese/strings.po rename to resources/language/resource.language.ja_jp/strings.po diff --git a/resources/language/Korean/strings.po b/resources/language/resource.language.ko_kr/strings.po similarity index 100% rename from resources/language/Korean/strings.po rename to resources/language/resource.language.ko_kr/strings.po diff --git a/resources/language/Lithuanian/strings.po b/resources/language/resource.language.lt_lt/strings.po similarity index 100% rename from resources/language/Lithuanian/strings.po rename to resources/language/resource.language.lt_lt/strings.po diff --git a/resources/language/Latvian/strings.po b/resources/language/resource.language.lv_lv/strings.po similarity index 100% rename from resources/language/Latvian/strings.po rename to resources/language/resource.language.lv_lv/strings.po diff --git a/resources/language/Macedonian/strings.po b/resources/language/resource.language.mk_mk/strings.po similarity index 100% rename from resources/language/Macedonian/strings.po rename to resources/language/resource.language.mk_mk/strings.po diff --git a/resources/language/Malayalam/strings.po b/resources/language/resource.language.ml_in/strings.po similarity index 100% rename from resources/language/Malayalam/strings.po rename to resources/language/resource.language.ml_in/strings.po diff --git a/resources/language/Malay/strings.po b/resources/language/resource.language.ms_my/strings.po similarity index 100% rename from resources/language/Malay/strings.po rename to resources/language/resource.language.ms_my/strings.po diff --git a/resources/language/Maltese/strings.po b/resources/language/resource.language.mt_mt/strings.po similarity index 100% rename from resources/language/Maltese/strings.po rename to resources/language/resource.language.mt_mt/strings.po diff --git a/resources/language/Norwegian/strings.po b/resources/language/resource.language.nb_no/strings.po similarity index 100% rename from resources/language/Norwegian/strings.po rename to resources/language/resource.language.nb_no/strings.po diff --git a/resources/language/Dutch/strings.po b/resources/language/resource.language.nl_nl/strings.po similarity index 100% rename from resources/language/Dutch/strings.po rename to resources/language/resource.language.nl_nl/strings.po diff --git a/resources/language/Polish/strings.po b/resources/language/resource.language.pl_pl/strings.po similarity index 100% rename from resources/language/Polish/strings.po rename to resources/language/resource.language.pl_pl/strings.po diff --git a/resources/language/Portuguese (Brazil)/strings.po b/resources/language/resource.language.pt_br/strings.po similarity index 100% rename from resources/language/Portuguese (Brazil)/strings.po rename to resources/language/resource.language.pt_br/strings.po diff --git a/resources/language/Portuguese/strings.po b/resources/language/resource.language.pt_pt/strings.po similarity index 100% rename from resources/language/Portuguese/strings.po rename to resources/language/resource.language.pt_pt/strings.po diff --git a/resources/language/Romanian/strings.po b/resources/language/resource.language.ro_ro/strings.po similarity index 100% rename from resources/language/Romanian/strings.po rename to resources/language/resource.language.ro_ro/strings.po diff --git a/resources/language/Russian/strings.po b/resources/language/resource.language.ru_ru/strings.po similarity index 100% rename from resources/language/Russian/strings.po rename to resources/language/resource.language.ru_ru/strings.po diff --git a/resources/language/Slovak/strings.po b/resources/language/resource.language.sk_sk/strings.po similarity index 100% rename from resources/language/Slovak/strings.po rename to resources/language/resource.language.sk_sk/strings.po diff --git a/resources/language/Slovenian/strings.po b/resources/language/resource.language.sl_si/strings.po similarity index 100% rename from resources/language/Slovenian/strings.po rename to resources/language/resource.language.sl_si/strings.po diff --git a/resources/language/Albanian/strings.po b/resources/language/resource.language.sq_al/strings.po similarity index 100% rename from resources/language/Albanian/strings.po rename to resources/language/resource.language.sq_al/strings.po diff --git a/resources/language/Serbian (Cyrillic)/strings.po b/resources/language/resource.language.sr_rs/strings.po similarity index 100% rename from resources/language/Serbian (Cyrillic)/strings.po rename to resources/language/resource.language.sr_rs/strings.po diff --git a/resources/language/Serbian/strings.po b/resources/language/resource.language.sr_rs@latin/strings.po similarity index 100% rename from resources/language/Serbian/strings.po rename to resources/language/resource.language.sr_rs@latin/strings.po diff --git a/resources/language/Swedish/strings.po b/resources/language/resource.language.sv_se/strings.po similarity index 100% rename from resources/language/Swedish/strings.po rename to resources/language/resource.language.sv_se/strings.po diff --git a/resources/language/Tamil (India)/strings.po b/resources/language/resource.language.ta_in/strings.po similarity index 100% rename from resources/language/Tamil (India)/strings.po rename to resources/language/resource.language.ta_in/strings.po diff --git a/resources/language/Thai/strings.po b/resources/language/resource.language.th_th/strings.po similarity index 100% rename from resources/language/Thai/strings.po rename to resources/language/resource.language.th_th/strings.po diff --git a/resources/language/Turkish/strings.po b/resources/language/resource.language.tr_tr/strings.po similarity index 100% rename from resources/language/Turkish/strings.po rename to resources/language/resource.language.tr_tr/strings.po diff --git a/resources/language/Ukrainian/strings.po b/resources/language/resource.language.uk_ua/strings.po similarity index 100% rename from resources/language/Ukrainian/strings.po rename to resources/language/resource.language.uk_ua/strings.po diff --git a/resources/language/Vietnamese/strings.po b/resources/language/resource.language.vi_vn/strings.po similarity index 100% rename from resources/language/Vietnamese/strings.po rename to resources/language/resource.language.vi_vn/strings.po diff --git a/resources/language/Chinese (Simple)/strings.po b/resources/language/resource.language.zh_cn/strings.po similarity index 100% rename from resources/language/Chinese (Simple)/strings.po rename to resources/language/resource.language.zh_cn/strings.po diff --git a/resources/language/Chinese (Traditional)/strings.po b/resources/language/resource.language.zh_tw/strings.po similarity index 100% rename from resources/language/Chinese (Traditional)/strings.po rename to resources/language/resource.language.zh_tw/strings.po diff --git a/resources/settings.xml b/resources/settings.xml index cc72177..efbf883 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -1,21 +1,99 @@ - - - - - - - - - - - - - - - - - - - + +
+ + + + 1 + true + + + + + + + + 1 + true + + + + + + + + 1 + true + + + + 1 + true + + + true + + + + 1 + true + + true + + + + 1 + 0 + + + + + + + + + true + + + + 1 + 10 + + 5 + 5 + 60 + + + + 0 + + + + + + + + 1 + true + + + + 1 + true + + + true + + + + 1 + false + + + true + + + + +