def showWidgets(): url = ("{server}/emby/Movies/Recommendations" + "?userId={userid}" + "&categoryLimit=1" + "&ItemLimit={ItemLimit}" + "&format=json" + "&ImageTypeLimit=1" + "&IsMissing=False") addMenuDirectoryItem( i18n('movies_recommendations'), "plugin://plugin.video.embycon/?mode=GET_CONTENT&media_type=Movies&url=" + urllib.quote(url)) url = ("{server}/emby/Users/{userid}/Items" + "?Limit={ItemLimit}" + "&format=json" + "&ImageTypeLimit=1" + "&IsMissing=False" + "&Filters={IsUnplayed,}IsNotFolder" + "&Recursive=true" + "&SortBy=Random" + "&SortOrder=Descending" + "&IsVirtualUnaired=false" + "&IsMissing=False" + "&IncludeItemTypes=Movie") addMenuDirectoryItem( i18n('movies_random'), "plugin://plugin.video.embycon/?mode=GET_CONTENT&media_type=Movies&url=" + urllib.quote(url)) #addMenuDirectoryItem(i18n('movies_recently_added'), 'plugin://plugin.video.embycon/?mode=WIDGET_CONTENT&type=recent_movies') #addMenuDirectoryItem(i18n('movies_in_progress'), 'plugin://plugin.video.embycon/?mode=WIDGET_CONTENT&type=inprogress_movies') #addMenuDirectoryItem(i18n('episodes_recently_added'), 'plugin://plugin.video.embycon/?mode=WIDGET_CONTENT&type=recent_episodes') #addMenuDirectoryItem(i18n('episodes_in_progress'), 'plugin://plugin.video.embycon/?mode=WIDGET_CONTENT&type=inprogress_episodes') #addMenuDirectoryItem(i18n('episodes_up_next'), 'plugin://plugin.video.embycon/?mode=WIDGET_CONTENT&type=nextup_episodes') xbmcplugin.endOfDirectory(int(sys.argv[1]))
def showWidgets(): url = ("{server}/emby/Movies/Recommendations" + "?userId={userid}" + "&categoryLimit=1" + "&ItemLimit={ItemLimit}" + "&format=json" + "&ImageTypeLimit=1" + "&IsMissing=False") addMenuDirectoryItem(i18n('movies_recommendations'), "plugin://plugin.video.embycon/?mode=GET_CONTENT&media_type=Movies&url=" + urllib.quote(url)) url = ("{server}/emby/Users/{userid}/Items" + "?Limit={ItemLimit}" + "&format=json" + "&ImageTypeLimit=1" + "&IsMissing=False" + "&Filters={IsUnplayed,}IsNotFolder" + "&Recursive=true" + "&SortBy=Random" + "&SortOrder=Descending" + "&IsVirtualUnaired=false" + "&IsMissing=False" + "&IncludeItemTypes=Movie") addMenuDirectoryItem(i18n('movies_random'), "plugin://plugin.video.embycon/?mode=GET_CONTENT&media_type=Movies&url=" + urllib.quote(url)) #addMenuDirectoryItem(i18n('movies_recently_added'), 'plugin://plugin.video.embycon/?mode=WIDGET_CONTENT&type=recent_movies') #addMenuDirectoryItem(i18n('movies_in_progress'), 'plugin://plugin.video.embycon/?mode=WIDGET_CONTENT&type=inprogress_movies') #addMenuDirectoryItem(i18n('episodes_recently_added'), 'plugin://plugin.video.embycon/?mode=WIDGET_CONTENT&type=recent_episodes') #addMenuDirectoryItem(i18n('episodes_in_progress'), 'plugin://plugin.video.embycon/?mode=WIDGET_CONTENT&type=inprogress_episodes') #addMenuDirectoryItem(i18n('episodes_up_next'), 'plugin://plugin.video.embycon/?mode=WIDGET_CONTENT&type=nextup_episodes') xbmcplugin.endOfDirectory(int(sys.argv[1]))
def showSearch(): addMenuDirectoryItem(i18n('movies'), 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=Movie') addMenuDirectoryItem(i18n('tvshows'), 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=Series') addMenuDirectoryItem(i18n('episodes'), 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=Episode') addMenuDirectoryItem("Song", 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=Audio') addMenuDirectoryItem("Album", 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=MusicAlbum') #addMenuDirectoryItem("Artist", 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=MusicArtists') xbmcplugin.endOfDirectory(int(sys.argv[1]))
def showSearch(): addMenuDirectoryItem( i18n('movies'), 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=Movie') addMenuDirectoryItem( i18n('tvshows'), 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=Series') addMenuDirectoryItem( i18n('episodes'), 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=Episode') xbmcplugin.endOfDirectory(int(sys.argv[1]))
def wrapper(*args, **kwargs): try: return func(*args, **kwargs) except errors as error: if not (hasattr(error, 'quiet') and error.quiet): return_value = xbmcgui.Dialog().yesno( i18n('error'), i18n('embycon_error'), i18n('embycon_error_submit')) if return_value: log.debug("Sending Error Data") try: submit_error_data() except Exception as error: log.debug("Sending Error Data Failed: {0}", error) raise return default_value
def cache_artwork_interactive(self): log.debug("cache_artwork_interactive") xbmcplugin.endOfDirectory(int(sys.argv[1]), cacheToDisc=False) # is the web server enabled web_query = {"setting": "services.webserver"} result = json_rpc('Settings.GetSettingValue').execute(web_query) xbmc_webserver_enabled = result['result']['value'] if not xbmc_webserver_enabled: xbmcgui.Dialog().ok(i18n('notice'), i18n('http_control')) return # ask to delete all textures question_result = xbmcgui.Dialog().yesno(i18n('delete'), i18n('delete_existing')) if question_result: pdialog = xbmcgui.DialogProgress() pdialog.create(i18n('deleting_textures'), "") index = 0 json_result = json_rpc('Textures.GetTextures').execute() textures = json_result.get("result", {}).get("textures", []) log.debug("texture ids: {0}", textures) total = len(textures) for texture in textures: texture_id = texture["textureid"] params = {"textureid": int(texture_id)} json_rpc('Textures.RemoveTexture').execute(params) percentage = int((float(index) / float(total)) * 100) message = "%s of %s" % (index, total) pdialog.update(percentage, "%s" % (message)) index += 1 if pdialog.iscanceled(): break del textures del pdialog question_result = xbmcgui.Dialog().yesno( i18n('cache_all_textures_title'), i18n('cache_all_textures')) if not question_result: return pdialog = xbmcgui.DialogProgress() pdialog.create(i18n('caching_textures'), "") result_report = self.cache_artwork(pdialog) pdialog.close() del pdialog if result_report: xbmcgui.Dialog().ok(i18n('done'), "\n".join(result_report))
def cache_artwork_interactive(self): log.debug("cache_artwork_interactive") xbmcplugin.endOfDirectory(int(sys.argv[1]), cacheToDisc=False) # is the web server enabled web_query = {"setting": "services.webserver"} result = json_rpc('Settings.GetSettingValue').execute(web_query) xbmc_webserver_enabled = result['result']['value'] if not xbmc_webserver_enabled: xbmcgui.Dialog().ok(i18n('notice'), i18n('http_control')) return # ask to delete all textures question_result = xbmcgui.Dialog().yesno(i18n('delete'), i18n('delete_existing')) if question_result: pdialog = xbmcgui.DialogProgress() pdialog.create(i18n('deleting_textures'), "") index = 0 json_result = json_rpc('Textures.GetTextures').execute() textures = json_result.get("result", {}).get("textures", []) log.debug("texture ids: {0}", textures) total = len(textures) for texture in textures: texture_id = texture["textureid"] params = {"textureid": int(texture_id)} json_rpc('Textures.RemoveTexture').execute(params) percentage = int((float(index) / float(total)) * 100) message = "%s of %s" % (index, total) pdialog.update(percentage, "%s" % (message)) index += 1 if pdialog.iscanceled(): break del textures del pdialog question_result = xbmcgui.Dialog().yesno(i18n('cache_all_textures_title'), i18n('cache_all_textures')) if not question_result: return pdialog = xbmcgui.DialogProgress() pdialog.create(i18n('caching_textures'), "") result_report = self.cache_artwork(pdialog) pdialog.close() del pdialog if result_report: xbmcgui.Dialog().ok(i18n('done'), "\n".join(result_report))
def cache_artwork_background(self): log.debug("cache_artwork_background") dp = xbmcgui.DialogProgressBG() dp.create(i18n('caching_textures'), "") result_text = self.cache_artwork(dp) dp.close() del dp if result_text: log.debug("Cache Images reuslt : {0}", " - ".join(result_text))
def showSearch(): addMenuDirectoryItem( i18n('movies'), 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=Movie') addMenuDirectoryItem( i18n('tvshows'), 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=Series') addMenuDirectoryItem( i18n('episodes'), 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=Episode') addMenuDirectoryItem( "Song", 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=Audio') addMenuDirectoryItem( "Album", 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=MusicAlbum') #addMenuDirectoryItem("Artist", 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=MusicArtists') xbmcplugin.endOfDirectory(int(sys.argv[1]))
def add_context_menu(item_details, folder): commands = [] if item_details.id is None: return commands scriptToRun = PLUGINPATH + "/default.py" if item_details.item_type == "Season" or item_details.item_type == "MusicAlbum": argsToPass = "******" + item_details.id commands.append( (i18n('play_all'), "RunPlugin(plugin://plugin.video.embycon" + argsToPass + ")")) if not folder: argsToPass = "******" + item_details.id + "&force_transcode=true" commands.append( (i18n('emby_force_transcode'), "RunPlugin(plugin://plugin.video.embycon" + argsToPass + ")")) if not folder and item_details.item_type == "Movie": argsToPass = "******" + item_details.id commands.append( (i18n('play_trailer'), "RunPlugin(plugin://plugin.video.embycon" + argsToPass + ")")) # watched/unwatched if item_details.play_count == 0: argsToPass = '******' + item_details.id commands.append((i18n('emby_mark_watched'), "RunScript(" + scriptToRun + ", " + argsToPass + ")")) else: argsToPass = '******' + item_details.id commands.append((i18n('emby_mark_unwatched'), "RunScript(" + scriptToRun + ", " + argsToPass + ")")) # favourite add/remove if item_details.favorite == 'false': argsToPass = '******' + item_details.id commands.append((i18n('emby_set_favorite'), "RunScript(" + scriptToRun + ", " + argsToPass + ")")) else: argsToPass = '******' + item_details.id commands.append((i18n('emby_unset_favorite'), "RunScript(" + scriptToRun + ", " + argsToPass + ")")) # delete argsToPass = '******' + item_details.id commands.append((i18n('emby_delete'), "RunScript(" + scriptToRun + ", " + argsToPass + ")")) return commands
def onInit(self): self.action_exitkeys_id = [10, 13] # load skin views addonPath = __addon__.getAddonInfo('path') skin_view_file = os.path.join(addonPath, "resources", "data", "skin_views.json") log.info("Loading skin views form: " + skin_view_file) dataFile = open(skin_view_file, 'r') jsonData = dataFile.read() dataFile.close() defaultViewData = json.loads(jsonData) log.info("Loaded skin views: " + str(defaultViewData)) skin_used = xbmc.getSkinDir() log.info("Current skin: " + skin_used) skin_views = defaultViewData.get(skin_used, None) log.info("Current skin views: " + str(skin_views)) if skin_views is None: xbmcgui.Dialog().notification( __addon__.getAddonInfo('name'), i18n('skin_not_supported') % skin_used, icon='special://home/addons/script.viewmaster/icon.png') self.close() return self.viewData = skin_views # load current default views savedData = loadSkinDefaults() self.defaultView = savedData.get("view", {}) #self.defaultSort = savedData.get("sort", {}) self.getControl(3110).setLabel(i18n('save')) #self.getControl(3019).setLabel(i18n('default_sort')) self.getControl(3020).setLabel(i18n('default_view')) self.getControl(3021).setLabel(i18n('movies')) self.getControl(3022).setLabel(i18n('boxsets')) self.getControl(3023).setLabel(i18n('series')) self.getControl(3024).setLabel(i18n('seasons')) self.getControl(3025).setLabel(i18n('episodes')) # set default values name = self.getViewNameById(self.defaultView.get("Movies")) self.getControl(3010).setLabel(name) name = self.getViewNameById(self.defaultView.get("BoxSets")) self.getControl(3011).setLabel(name) name = self.getViewNameById(self.defaultView.get("Series")) self.getControl(3012).setLabel(name) name = self.getViewNameById(self.defaultView.get("Seasons")) self.getControl(3013).setLabel(name) name = self.getViewNameById(self.defaultView.get("Episodes")) self.getControl(3014).setLabel(name)
def delete(item): item_id = item.get("Id") item_name = item.get("Name") series_name = item.get("SeriesName") if series_name: final_name = series_name + " - " + item_name else: final_name = item_name return_value = xbmcgui.Dialog().yesno(i18n('confirm_file_delete'), final_name, i18n('file_delete_confirm')) if return_value: log.debug('Deleting Item: {0}', item_id) url = '{server}/emby/Items/' + item_id progress = xbmcgui.DialogProgress() progress.create(i18n('deleting'), i18n('waiting_server_delete')) downloadUtils.downloadUrl(url, method="DELETE") progress.close() home_window = HomeWindow() home_window.setProperty("force_data_reload", "true") home_window.setProperty("embycon_widget_reload", str(time.time())) xbmc.executebuiltin("Container.Refresh")
def populate_listitem(item_id): log.debug("populate_listitem: {0}", item_id) url = "{server}/emby/Users/{userid}/Items/" + item_id + "?format=json" jsonData = downloadUtils.downloadUrl(url) result = json.loads(jsonData) log.debug("populate_listitem item info: {0}", result) ''' server = downloadUtils.getServer() gui_options = {} gui_options["server"] = server gui_options["name_format"] = None gui_options["name_format_type"] = None details, extraData = extract_item_info(result,gui_options ) u, list_item, folder = add_gui_item(result["Id"], details, extraData, {}, folder=False) log.debug("list_item path: {0}", u) #list_item.setProperty('IsPlayable', 'false') #list_item.setPath(u) ''' item_title = result.get("Name", i18n('missing_title')) list_item = xbmcgui.ListItem(label=item_title) server = downloadUtils.getServer() art = getArt(result, server=server) list_item.setIconImage(art['thumb']) # back compat list_item.setProperty('fanart_image', art['fanart']) # back compat list_item.setProperty('discart', art['discart']) # not avail to setArt list_item.setArt(art) list_item.setProperty('IsPlayable', 'false') list_item.setProperty('IsFolder', 'false') list_item.setProperty('id', result.get("Id")) # play info details = { 'title': item_title, 'plot': result.get("Overview") } list_item.setInfo("Video", infoLabels=details) return list_item
def showYearsList(): server = downloadUtils.getServer() if server is None: return jsonData = downloadUtils.downloadUrl("{server}/emby/Years" + "?SortBy=Name" + "&SortOrder=Descending" + "&IncludeItemTypes=Movie" + "&Recursive=true" + "&UserId={userid}" + "&format=json") log.debug("YEAR_LIST_DATA: {0}", jsonData) result = json.loads(jsonData) if result is not None: result = result.get("Items") else: result = [] collections = [] for year in result: item_data = {} item_data['title'] = year.get("Name") item_data['media_type'] = "Movies" item_data['path'] = ('{server}/emby/Users/{userid}/Items' '?Fields={field_filters}' + '&Recursive=true' + '&Years=' + year.get("Name") + '&IncludeItemTypes=Movie' + '&ImageTypeLimit=1' + "&SortBy=Name" + "&SortOrder=Ascending" + '&format=json') collections.append(item_data) for collection in collections: url = sys.argv[0] + ("?url=" + urllib.quote(collection['path']) + "&mode=GET_CONTENT" + "&media_type=" + collection["media_type"]) log.debug("addMenuDirectoryItem: {0} ({1})", collection.get('title'), url) addMenuDirectoryItem(collection.get('title', i18n('unknown')), url) xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_LABEL) xbmcplugin.endOfDirectory(int(sys.argv[1]))
def showMovieAlphaList(): log.debug("== ENTER: showMovieAlphaList() ==") settings = xbmcaddon.Addon() server = downloadUtils.getServer() if server is None: return collections = [] item_data = {} item_data['title'] = "#" item_data['media_type'] = "Movies" item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Fields={field_filters}' + '&Recursive=true' + '&NameLessThan=A' + '&IncludeItemTypes=Movie' + '&ImageTypeLimit=1' + '&format=json') collections.append(item_data) alphaList = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "Y", "Z"] for alphaName in alphaList: item_data = {} item_data['title'] = alphaName item_data['media_type'] = "Movies" item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Fields={field_filters}' + '&Recursive=true' + '&NameStartsWith=' + alphaName + '&IncludeItemTypes=Movie' + "&SortBy=Name" + "&SortOrder=Ascending" + '&ImageTypeLimit=1&format=json') collections.append(item_data) for collection in collections: url = (sys.argv[0] + "?url=" + urllib.quote(collection['path']) + "&mode=GET_CONTENT&media_type=" + collection["media_type"]) log.debug("addMenuDirectoryItem: {0} ({1})", collection.get('title'), url) addMenuDirectoryItem(collection.get('title', i18n('unknown')), url) xbmcplugin.endOfDirectory(int(sys.argv[1]))
def showYearsList(): server = downloadUtils.getServer() if server is None: return jsonData = downloadUtils.downloadUrl("{server}/emby/Years" + "?SortBy=SortName" + "&SortOrder=Descending" + "&IncludeItemTypes=Movie" + "&Recursive=true" + "&UserId={userid}" + "&format=json") log.debug("YEAR_LIST_DATA: {0}", jsonData) result = json.loads(jsonData) if result is not None: result = result.get("Items") else: result = [] collections = [] for year in result: item_data = {} item_data['title'] = year.get("Name") item_data['media_type'] = "Movies" #item_data['thumbnail'] = server + "/Years/" + year.get("Name") + "/Images/Thumb" item_data['path'] = ('{server}/emby/Users/{userid}/Items' '?Fields={field_filters}' + '&Recursive=true' + '&Years=' + year.get("Name") + '&IncludeItemTypes=Movie' + '&ImageTypeLimit=1' + '&format=json') collections.append(item_data) for collection in collections: url = sys.argv[0] + ("?url=" + urllib.quote(collection['path']) + "&mode=GET_CONTENT" + "&media_type=" + collection["media_type"]) log.debug("addMenuDirectoryItem: {0} ({1})", collection.get('title'), url) addMenuDirectoryItem(collection.get('title', i18n('unknown')), url) #, thumbnail=collection.get("thumbnail")) xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_LABEL) xbmcplugin.endOfDirectory(int(sys.argv[1]))
def showMovieAlphaList(): log.debug("== ENTER: showMovieAlphaList() ==") settings = xbmcaddon.Addon() server = downloadUtils.getServer() if server is None: return collections = [] item_data = {} item_data['title'] = "#" item_data['media_type'] = "Movies" item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Fields={field_filters}' + '&Recursive=true' + '&NameLessThan=A' + '&IncludeItemTypes=Movie' + '&ImageTypeLimit=1' + '&format=json') collections.append(item_data) alphaList = [ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "Y", "Z" ] for alphaName in alphaList: item_data = {} item_data['title'] = alphaName item_data['media_type'] = "Movies" item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Fields={field_filters}' + '&Recursive=true' + '&NameStartsWith=' + alphaName + '&IncludeItemTypes=Movie' + "&SortBy=Name" + "&SortOrder=Ascending" + '&ImageTypeLimit=1&format=json') collections.append(item_data) for collection in collections: url = (sys.argv[0] + "?url=" + urllib.quote(collection['path']) + "&mode=GET_CONTENT&media_type=" + collection["media_type"]) log.debug("addMenuDirectoryItem: {0} ({1})", collection.get('title'), url) addMenuDirectoryItem(collection.get('title', i18n('unknown')), url) xbmcplugin.endOfDirectory(int(sys.argv[1]))
def add_context_menu(item_details, folder): commands = [] if item_details.id is None: return commands scriptToRun = PLUGINPATH + "/default.py" if item_details.item_type == "Season" or item_details.item_type == "MusicAlbum": argsToPass = "******" + item_details.id commands.append((i18n('play_all'), "RunPlugin(plugin://plugin.video.embycon" + argsToPass + ")")) if not folder: argsToPass = "******" + item_details.id + "&force_transcode=true" commands.append((i18n('emby_force_transcode'), "RunPlugin(plugin://plugin.video.embycon" + argsToPass + ")")) if not folder and item_details.item_type == "Movie": argsToPass = "******" + item_details.id commands.append((i18n('play_trailer'), "RunPlugin(plugin://plugin.video.embycon" + argsToPass + ")")) # watched/unwatched if item_details.play_count == 0: argsToPass = '******' + item_details.id commands.append((i18n('emby_mark_watched'), "RunScript(" + scriptToRun + ", " + argsToPass + ")")) else: argsToPass = '******' + item_details.id commands.append((i18n('emby_mark_unwatched'), "RunScript(" + scriptToRun + ", " + argsToPass + ")")) # favourite add/remove if item_details.favorite == 'false': argsToPass = '******' + item_details.id commands.append((i18n('emby_set_favorite'), "RunScript(" + scriptToRun + ", " + argsToPass + ")")) else: argsToPass = '******' + item_details.id commands.append((i18n('emby_unset_favorite'), "RunScript(" + scriptToRun + ", " + argsToPass + ")")) # delete argsToPass = '******' + item_details.id commands.append((i18n('emby_delete'), "RunScript(" + scriptToRun + ", " + argsToPass + ")")) return commands
def show_search(): addMenuDirectoryItem( i18n('movies'), 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=Movie') addMenuDirectoryItem( i18n('tvshows'), 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=Series') addMenuDirectoryItem( i18n('episodes'), 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=Episode') addMenuDirectoryItem( i18n('song'), 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=Audio') addMenuDirectoryItem( i18n('album'), 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=MusicAlbum') addMenuDirectoryItem( i18n('person'), 'plugin://plugin.video.embycon/?mode=NEW_SEARCH&item_type=Person') xbmcplugin.endOfDirectory(int(sys.argv[1]))
def promptForStopActions(item_id, current_possition): settings = xbmcaddon.Addon() prompt_next_percentage = int(settings.getSetting('promptPlayNextEpisodePercentage')) play_prompt = settings.getSetting('promptPlayNextEpisodePercentage_prompt') == "true" prompt_delete_episode_percentage = int(settings.getSetting('promptDeleteEpisodePercentage')) prompt_delete_movie_percentage = int(settings.getSetting('promptDeleteMoviePercentage')) # everything is off so return if (prompt_next_percentage == 100 and prompt_delete_episode_percentage == 100 and prompt_delete_movie_percentage == 100): return jsonData = download_utils.downloadUrl("{server}/emby/Users/{userid}/Items/" + item_id + "?format=json") result = json.loads(jsonData) if result is None: log.debug("promptForStopActions failed! no result from server.") return prompt_to_delete = False runtime = result.get("RunTimeTicks", 0) # if no runtime we cant calculate perceantge so just return if runtime == 0: log.debug("No runtime so returing") return # item percentage complete percenatge_complete = int(((current_possition * 10000000) / runtime) * 100) log.debug("Episode Percentage Complete: {0}", percenatge_complete) if (prompt_delete_episode_percentage < 100 and result.get("Type", "na") == "Episode" and percenatge_complete > prompt_delete_episode_percentage): prompt_to_delete = True if (prompt_delete_movie_percentage < 100 and result.get("Type", "na") == "Movie" and percenatge_complete > prompt_delete_movie_percentage): prompt_to_delete = True if prompt_to_delete: log.debug("Prompting for delete") delete(result) # prompt for next episode if (prompt_next_percentage < 100 and result.get("Type", "na") == "Episode" and percenatge_complete > prompt_next_percentage): next_episode = get_next_episode(result) if next_episode is not None: resp = True index = next_episode.get("IndexNumber", -1) if play_prompt: next_epp_name = "%02d - %s" % (index, next_episode.get("Name", "n/a")) resp = xbmcgui.Dialog().yesno(i18n("play_next_title"), i18n("play_next_question"), next_epp_name, autoclose=10000) if resp: next_item_id = next_episode.get("Id") log.debug("Playing Next Episode: {0}", next_item_id) play_info = {} play_info["item_id"] = next_item_id play_info["auto_resume"] = "-1" play_info["force_transcode"] = False send_event_notification("embycon_play_action", play_info)
def playTrailer(id): log.debug("== ENTER: playTrailer ==") url = ("{server}/emby/Users/{userid}/Items/%s/LocalTrailers?format=json" % id) jsonData = downloadUtils.downloadUrl(url) result = json.loads(jsonData) if result is None: return log.debug("LocalTrailers {0}", result) count = 1 trailer_names = [] trailer_list = [] for trailer in result: info = {} info["type"] = "local" name = trailer.get("Name") while not name or name in trailer_names: name = "Trailer " + str(count) count += 1 info["name"] = name info["id"] = trailer.get("Id") count += 1 trailer_names.append(name) trailer_list.append(info) url = ("{server}/emby/Users/{userid}/Items/%s?format=json&Fields=RemoteTrailers" % id) jsonData = downloadUtils.downloadUrl(url) result = json.loads(jsonData) log.debug("RemoteTrailers: {0}", result) count = 1 if result is None: return remote_trailers = result.get("RemoteTrailers", []) for trailer in remote_trailers: info = {} info["type"] = "remote" url = trailer.get("Url", "none") if url.lower().find("youtube"): info["url"] = url name = trailer.get("Name") while not name or name in trailer_names: name = "Trailer " + str(count) count += 1 info["name"] = name trailer_names.append(name) trailer_list.append(info) log.debug("TrailerList: {0}", trailer_list) trailer_text = [] for trailer in trailer_list: name = trailer.get("name") + " (" + trailer.get("type") + ")" trailer_text.append(name) dialog = xbmcgui.Dialog() resp = dialog.select(i18n('select_trailer'), trailer_text) if resp > -1: trailer = trailer_list[resp] log.debug("SelectedTrailer: {0}", trailer) if trailer.get("type") == "local": params = {} params["item_id"] = trailer.get("id") PLAY(params) elif trailer.get("type") == "remote": youtube_id = trailer.get("url").rsplit('=', 1)[1] log.debug("YoutubeID: {0}", youtube_id) youtube_plugin = "PlayMedia(plugin://plugin.video.youtube/?action=play_video&videoid=%s)" % youtube_id xbmc.executebuiltin(youtube_plugin)
def onInit(self): self.action_exitkeys_id = [10, 13] self.getControl(3010).setLabel(self.resumeTimeStamp) self.getControl(3011).setLabel(i18n('start_from_beginning'))
def processDirectory(results, progress, params): log.debug("== ENTER: processDirectory ==") settings = xbmcaddon.Addon() server = downloadUtils.getServer() name_format = params.get("name_format", None) name_format_type = None if name_format is not None: name_format = urllib.unquote(name_format) tokens = name_format.split("|") if len(tokens) == 2: name_format_type = tokens[0] name_format = settings.getSetting(tokens[1]) else: name_format_type = None name_format = None dirItems = [] if results is None: results = [] baseline_name = None if isinstance(results, dict) and results.get("Items") is not None: baseline_name = results.get("BaselineItemName") results = results.get("Items", []) elif isinstance(results, list) and len(results) > 0 and results[0].get("Items") is not None: baseline_name = results[0].get("BaselineItemName") results = results[0].get("Items") # flatten single season # if there is only one result and it is a season and you have flatten signle season turned on then # build a new url, set the content media type and call get content again flatten_single_season = settings.getSetting("flatten_single_season") == "true" if flatten_single_season and len(results) == 1 and results[0].get("Type", "") == "Season": season_id = results[0].get("Id") season_url = ('{server}/emby/Users/{userid}/items' + '?ParentId=' + season_id + '&IsVirtualUnAired=false' + '&IsMissing=false' + '&Fields={field_filters}' + '&format=json') if progress is not None: progress.close() params["media_type"] = "Episodes" getContent(season_url, params) return None, None hide_unwatched_details = settings.getSetting('hide_unwatched_details') == 'true' display_options = {} display_options["addCounts"] = settings.getSetting("addCounts") == 'true' display_options["addResumePercent"] = settings.getSetting("addResumePercent") == 'true' display_options["addSubtitleAvailable"] = settings.getSetting("addSubtitleAvailable") == 'true' show_empty_folders = settings.getSetting("show_empty_folders") == 'true' item_count = len(results) current_item = 1 first_season_item = None total_unwatched = 0 total_episodes = 0 total_watched = 0 gui_options = {} gui_options["server"] = server gui_options["name_format"] = name_format gui_options["name_format_type"] = name_format_type detected_type = None for item in results: if progress is not None: percent_done = (float(current_item) / float(item_count)) * 100 progress.update(int(percent_done), i18n('processing_item:') + str(current_item)) current_item = current_item + 1 # get the infofrom the item item_details = extract_item_info(item, gui_options) item_details.baseline_itemname = baseline_name if detected_type is not None: if item_details.item_type != detected_type: detected_type = "mixed" else: detected_type = item_details.item_type if item_details.item_type == "Season" and first_season_item is None: first_season_item = item total_unwatched += item_details.unwatched_episodes total_episodes += item_details.total_episodes total_watched += item_details.watched_episodes # if set, for unwatched episodes dont show some of the info if hide_unwatched_details and item_details.item_type == "Episode" and item_details.play_count == 0: item_details.plot = "[Spoiler Alert]" item_details.art["poster"] = item_details.art["tvshow.poster"] item_details.art["thumb"] = item_details.art["tvshow.poster"] if item["IsFolder"] is True: if item_details.item_type == "Series": u = ('{server}/emby/Shows/' + item_details.id + '/Seasons' '?userId={userid}' + '&Fields={field_filters}' + '&format=json') else: u = ('{server}/emby/Users/{userid}/items' + '?ParentId=' + item_details.id + '&IsVirtualUnAired=false' + '&IsMissing=false' + '&Fields={field_filters}' + '&format=json') if show_empty_folders or item["RecursiveItemCount"] != 0: dirItems.append(add_gui_item(u, item_details, display_options)) elif item_details.item_type == "MusicArtist": u = ('{server}/emby/Users/{userid}/items' + '?ArtistIds=' + item_details.id + '&IncludeItemTypes=MusicAlbum' + '&CollapseBoxSetItems=false' + '&Recursive=true' + '&format=json') dirItems.append(add_gui_item(u, item_details, display_options)) else: u = item_details.id dirItems.append(add_gui_item(u, item_details, display_options, folder=False)) # add the all episodes item show_all_episodes = settings.getSetting('show_all_episodes') == 'true' if (show_all_episodes and first_season_item is not None and len(dirItems) > 1 and first_season_item.get("SeriesId") is not None): series_url = ('{server}/emby/Users/{userid}/items' + '?ParentId=' + first_season_item.get("SeriesId") + '&IsVirtualUnAired=false' + '&IsMissing=false' + '&Fields={field_filters}' + '&Recursive=true' + '&IncludeItemTypes=Episode' + '&format=json') played = 0 overlay = "7" if total_unwatched == 0: played = 1 overlay = "6" item_details = ItemDetails() item_details.id = first_season_item.get("Id") item_details.name = i18n('all') item_details.art = getArt(first_season_item, server) item_details.play_count = played item_details.overlay = overlay item_details.name_format = "Episode|episode_name_format" item_details.series_name = first_season_item.get("SeriesName") item_details.item_type = "Season" item_details.unwatched_episodes = total_unwatched item_details.total_episodes = total_episodes item_details.watched_episodes = total_watched item_details.mode = "GET_CONTENT" dirItems.append(add_gui_item(series_url, item_details, display_options, folder=True)) return dirItems, detected_type
def downloadUrl(self, url, suppress=False, postBody=None, method="GET", authenticate=True, headers=None): log.debug("downloadUrl") return_data = "null" settings = xbmcaddon.Addon() if settings.getSetting("suppressErrors") == "true": suppress = True log.debug("Before: {0}", url) if url.find("{server}") != -1: server = self.getServer() if server is None: return return_data url = url.replace("{server}", server) if url.find("{userid}") != -1: userid = self.getUserId() url = url.replace("{userid}", userid) if url.find("{ItemLimit}") != -1: show_x_filtered_items = settings.getSetting("show_x_filtered_items") url = url.replace("{ItemLimit}", show_x_filtered_items) if url.find("{IsUnplayed}") != -1 or url.find("{,IsUnplayed}") != -1 or url.find("{IsUnplayed,}") != -1 \ or url.find("{,IsUnplayed,}") != -1: show_latest_unplayed = settings.getSetting("show_latest_unplayed") == "true" if show_latest_unplayed: url = url.replace("{IsUnplayed}", "") url = url.replace("{,IsUnplayed}", "") url = url.replace("{IsUnplayed,}", "") url = url.replace("{,IsUnplayed,}", "") elif url.find("{IsUnplayed}") != -1: url = url.replace("{IsUnplayed}", "IsUnplayed") elif url.find("{,IsUnplayed}") != -1: url = url.replace("{,IsUnplayed}", ",IsUnplayed") elif url.find("{IsUnplayed,}") != -1: url = url.replace("{IsUnplayed,}", "IsUnplayed,") elif url.find("{,IsUnplayed,}") != -1: url = url.replace("{,IsUnplayed,}", ",IsUnplayed,") if url.find("{field_filters}") != -1: filter_string = getDetailsString() url = url.replace("{field_filters}", filter_string) log.debug("After: {0}", url) try: if url.startswith('http'): serversplit = 2 urlsplit = 3 else: serversplit = 0 urlsplit = 1 server = url.split('/')[serversplit] urlPath = "/" + "/".join(url.split('/')[urlsplit:]) log.debug("DOWNLOAD_URL: {0}", url) log.debug("server: {0}", server) log.debug("urlPath: {0}", urlPath) # check the server details tokens = server.split(':') host = tokens[0] port = tokens[1] if (host == "<none>" or host == "" or port == ""): return "" use_https = settings.getSetting('use_https') == 'true' verify_cert = settings.getSetting('verify_cert') == 'true' if use_https and verify_cert: log.debug("Connection: HTTPS, Cert checked") conn = httplib.HTTPSConnection(server, timeout=40) elif use_https and not verify_cert: log.debug("Connection: HTTPS, Cert NOT checked") conn = httplib.HTTPSConnection(server, timeout=40, context=ssl._create_unverified_context()) else: log.debug("Connection: HTTP") conn = httplib.HTTPConnection(server, timeout=40) head = self.getAuthHeader(authenticate) log.debug("HEADERS: {0}", head) if (postBody != None): if isinstance(postBody, dict): content_type = "application/json" postBody = json.dumps(postBody) else: content_type = "application/x-www-form-urlencoded" head["Content-Type"] = content_type log.debug("Content-Type: {0}", content_type) log.debug("POST DATA: {0}", postBody) conn.request(method=method, url=urlPath, body=postBody, headers=head) else: conn.request(method=method, url=urlPath, headers=head) data = conn.getresponse() log.debug("GET URL HEADERS: {0}", data.getheaders()) if int(data.status) == 200: retData = data.read() contentType = data.getheader('content-encoding') log.debug("Data Len Before: {0}", len(retData)) if (contentType == "gzip"): retData = StringIO.StringIO(retData) gzipper = gzip.GzipFile(fileobj=retData) return_data = gzipper.read() else: return_data = retData if headers is not None and isinstance(headers, dict): headers.update(data.getheaders()) log.debug("Data Len After: {0}", len(return_data)) log.debug("====== 200 returned =======") log.debug("Content-Type: {0}", contentType) log.debug("{0}", return_data) log.debug("====== 200 finished ======") elif int(data.status) >= 400: if int(data.status) == 401: # remove any saved password username = settings.getSetting("username") m = hashlib.md5() m.update(username) hashed_username = m.hexdigest() log.error("HTTP response error 401 auth error, removing any saved passwords for user: {0}", hashed_username) settings.setSetting("saved_user_password_" + hashed_username, "") log.error("HTTP response error: {0} {1}", data.status, data.reason) if suppress is False: xbmcgui.Dialog().notification(i18n("connection_error"), i18n('url_error_') % str(data.reason), icon="special://home/addons/plugin.video.embycon/icon.png") except Exception, msg: log.error("Unable to connect to {0} : {1}", server, msg) if suppress is False: xbmcgui.Dialog().notification(i18n("connection_error"), str(msg), icon="special://home/addons/plugin.video.embycon/icon.png")
def searchResults(params): item_type = params.get('item_type') if item_type.lower() == 'movie': heading_type = i18n('movies') elif item_type.lower() == 'series': heading_type = i18n('tvshows') elif item_type.lower() == 'episode': heading_type = i18n('episodes') else: heading_type = item_type home_window = HomeWindow() last_search = home_window.getProperty("last_search") kb = xbmc.Keyboard() kb.setHeading(heading_type.capitalize() + ' ' + i18n('search').lower()) kb.setDefault(last_search) kb.doModal() if kb.isConfirmed(): user_input = kb.getText().strip() else: return home_window.setProperty("last_search", user_input) log.debug('searchResults Called: {0}', params) handle = int(sys.argv[1]) query = urllib.quote_plus(user_input) item_type = params.get('item_type') if (not item_type) or (not query): return limit = int(params.get('limit', 50)) index = 0 settings = xbmcaddon.Addon() server = downloadUtils.getServer() content_url = ('{server}/emby/Search/Hints?searchTerm=' + query + '&IncludeItemTypes=' + item_type + '&ExcludeItemTypes=LiveTvProgram' + '&UserId={userid}' '&StartIndex=' + str(index) + '&Limit=' + str(limit) + '&IncludePeople=false' + '&IncludeMedia=true' + '&IncludeGenres=false' + '&IncludeStudios=false' + '&IncludeArtists=false') if item_type.lower() == 'movie': xbmcplugin.setContent(handle, 'movies') view_type = 'Movies' media_type = 'movie' elif item_type.lower() == 'series': xbmcplugin.setContent(handle, 'tvshows') view_type = 'Series' media_type = 'tvshow' elif item_type.lower() == 'episode': xbmcplugin.setContent(handle, 'episodes') view_type = 'Episodes' media_type = 'episode' else: xbmcplugin.setContent(handle, 'videos') view_type = '' media_type = 'video' setSort(handle, view_type) # show a progress indicator if needed progress = None if (settings.getSetting('showLoadProgress') == "true"): progress = xbmcgui.DialogProgress() progress.create(i18n('loading_content')) progress.update(0, i18n('retrieving_data')) result = dataManager.GetContent(content_url) log.debug('SearchHints jsonData: {0}', result) if result is None: result = {} results = result.get('SearchHints') if results is None: results = [] item_count = 1 total_results = int(result.get('TotalRecordCount', 0)) log.debug('SEARCH_TOTAL_RESULTS: {0}', total_results) list_items = [] for item in results: item_id = item.get('ItemId') name = title = item.get('Name') log.debug('SEARCH_RESULT_NAME: {0}', name) if progress is not None: percent_complete = (float(item_count) / float(total_results)) * 100 progress.update(int(percent_complete), i18n('processing_item:') + str(item_count)) tvshowtitle = '' season = episode = None if (item.get('Type') == 'Episode') and (item.get('Series') is not None): episode = '0' if item.get('IndexNumber') is not None: ep_number = item.get('IndexNumber') if ep_number < 10: episode = '0' + str(ep_number) else: episode = str(ep_number) season = '0' season_number = item.get('ParentIndexNumber') if season_number < 10: season = '0' + str(season_number) else: season = str(season_number) tvshowtitle = item.get('Series') title = tvshowtitle + ' - ' + title primary_image = thumb_image = backdrop_image = '' primary_tag = item.get('PrimaryImageTag') if primary_tag: primary_image = downloadUtils.imageUrl(item_id, 'Primary', 0, 0, 0, imageTag=primary_tag, server=server) thumb_id = item.get('ThumbImageId') thumb_tag = item.get('ThumbImageTag') if thumb_tag and thumb_id: thumb_image = downloadUtils.imageUrl(thumb_id, 'Thumb', 0, 0, 0, imageTag=thumb_tag, server=server) backdrop_id = item.get('BackdropImageItemId') backdrop_tag = item.get('BackdropImageTag') if backdrop_tag and backdrop_id: backdrop_image = downloadUtils.imageUrl(backdrop_id, 'Backdrop', 0, 0, 0, imageTag=backdrop_tag, server=server) art = { 'thumb': thumb_image or primary_image, 'fanart': backdrop_image, 'poster': primary_image or thumb_image, 'banner': '', 'clearlogo': '', 'clearart': '', 'discart': '', 'landscape': '', 'tvshow.poster': primary_image } if kodi_version > 17: list_item = xbmcgui.ListItem(label=name, iconImage=art['thumb'], offscreen=True) else: list_item = xbmcgui.ListItem(label=name, iconImage=art['thumb']) info = { 'title': title, 'tvshowtitle': tvshowtitle, 'mediatype': media_type } log.debug('SEARCH_RESULT_ART: {0}', art) list_item.setProperty('fanart_image', art['fanart']) list_item.setProperty('discart', art['discart']) list_item.setArt(art) # add count list_item.setProperty('item_index', str(item_count)) item_count += 1 if item.get('MediaType') == 'Video': total_time = str( int(float(item.get('RunTimeTicks', '0')) / (10000000 * 60))) list_item.setProperty('TotalTime', str(total_time)) list_item.setProperty('IsPlayable', 'false') list_item_url = 'plugin://plugin.video.embycon/?item_id=' + item_id + '&mode=PLAY' is_folder = False else: item_url = ('{server}/emby/Users/{userid}' + '/items?ParentId=' + item_id + '&IsVirtualUnAired=false&IsMissing=false' + '&Fields={field_filters}' + '&format=json') list_item_url = 'plugin://plugin.video.embycon/?mode=GET_CONTENT&media_type={item_type}&url={item_url}'\ .format(item_type=item_type, item_url=urllib.quote(item_url)) list_item.setProperty('IsPlayable', 'false') is_folder = True item_details = ItemDetails() item_details.id = item_id #menu_items = add_context_menu(item_details, is_folder) #if len(menu_items) > 0: # list_item.addContextMenuItems(menu_items, True) if (season is not None) and (episode is not None): info['episode'] = episode info['season'] = season info['year'] = item.get('ProductionYear', '') log.debug('SEARCH_RESULT_INFO: {0}', info) list_item.setInfo('Video', infoLabels=info) item_tuple = (list_item_url, list_item, is_folder) list_items.append(item_tuple) xbmcplugin.addDirectoryItems(handle, list_items) xbmcplugin.endOfDirectory(handle, cacheToDisc=False) if progress is not None: progress.update(100, i18n('done')) progress.close()
def getCollections(): log.debug("== ENTER: getCollections ==") server = downloadUtils.getServer() if server is None: return [] userid = downloadUtils.getUserId() if userid == None or len(userid) == 0: log.debug("No userid so returning []") return [] data_manager = DataManager() result = data_manager.GetContent( "{server}/emby/Users/{userid}/Items/Root?format=json") if result is None: return [] parentid = result.get("Id") log.debug("parentid: {0}", parentid) htmlpath = "{server}/emby/Users/{userid}/items?ParentId=" + parentid + "&Sortby=SortName&format=json" result = data_manager.GetContent(htmlpath) if result is not None: result = result.get("Items") else: result = [] collections = [] for item in result: item_name = item.get("Name") collection_type = item.get('CollectionType', None) log.debug("CollectionType: {0}", collection_type) log.debug("Title: {0}", item_name) if collection_type == "music": item_data = {} item_data['title'] = item_name + i18n('_all_albums') item_data['thumbnail'] = downloadUtils.getArtwork(item, "Primary", server=server) item_data['media_type'] = 'MusicAlbums' item_data['path'] = ( '{server}/emby/Users/{userid}/Items' + '?Recursive=true' + '&ParentId=' + item.get("Id") + '&IncludeItemTypes=MusicAlbum' + '&ImageTypeLimit=1' + '&EnableImageTypes=Primary,Backdrop,Banner,Thumb' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = item_name + i18n('_all_artists') item_data['thumbnail'] = downloadUtils.getArtwork(item, "Primary", server=server) item_data['media_type'] = 'MusicArtists' item_data['path'] = ( '{server}/emby/Artists/AlbumArtists' + '?Recursive=true' + '&ParentId=' + item.get("Id") + '&ImageTypeLimit=1' + '&EnableImageTypes=Primary,Backdrop,Banner,Thumb' + '&format=json') collections.append(item_data) if collection_type in ["movies", "boxsets"]: collections.append({ 'title': item_name, 'thumbnail': downloadUtils.getArtwork(item, "Primary", server=server), 'path': ('{server}/emby/Users/{userid}/Items' + '?ParentId=' + item.get("Id") + '&IsVirtualUnaired=false' + '&CollapseBoxSetItems=true' + '&Recursive=true' + '&IsMissing=False' + '&Fields={field_filters}' + '&ImageTypeLimit=1' + '&format=json'), 'media_type': collection_type }) if collection_type == "tvshows": collections.append({ 'title': item_name, 'thumbnail': downloadUtils.getArtwork(item, "Primary", server=server), 'path': ('{server}/emby/Users/{userid}/Items' + '?ParentId=' + item.get("Id") + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&Fields={field_filters}' + '&ImageTypeLimit=1' + '&format=json'), 'media_type': collection_type }) collections.append({ 'title': item_name + i18n('_unwatched'), 'thumbnail': downloadUtils.getArtwork(item, "Primary", server=server), 'path': ('{server}/emby/Users/{userid}/Items' + '?ParentId=' + item.get("Id") + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&Fields={field_filters}' + '&Filters=IsUnplayed' + '&Recursive=true' + '&IncludeItemTypes=Series' + '&ImageTypeLimit=1' + '&format=json'), 'media_type': 'tvshows' }) collections.append({ 'title': item_name + i18n('_in_progress'), 'thumbnail': downloadUtils.getArtwork(item, "Primary", server=server), 'path': ('{server}/emby/Users/{userid}/Items' + '?ParentId=' + item.get("Id") + '&Limit={ItemLimit}' + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&Fields={field_filters}' + '&Filters=IsResumable' + '&Recursive=true' + '&IncludeItemTypes=Episode' + '&ImageTypeLimit=1' + '&format=json'), 'media_type': 'Episodes', 'name_format': 'Episode|episode_name_format' }) collections.append({ 'title': item_name + i18n('_latest'), 'thumbnail': downloadUtils.getArtwork(item, "Primary", server=server), 'path': ('{server}/emby/Users/{userid}/Items/Latest' + '?ParentId=' + item.get("Id") + '&Limit={ItemLimit}' + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&Fields={field_filters}' + '&SortBy=DateCreated' + '&SortOrder=Descending' + '&Filters=IsUnplayed' + '&Recursive=true' + '&IncludeItemTypes=Episode' + '&ImageTypeLimit=1' + '&format=json'), 'media_type': 'Episodes', 'name_format': 'Episode|episode_name_format' }) collections.append({ 'title': item_name + i18n('_recently_added'), 'thumbnail': downloadUtils.getArtwork(item, "Primary", server=server), 'path': ('{server}/emby/Users/{userid}/Items' + '?ParentId=' + item.get("Id") + '&Limit={ItemLimit}' + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&Fields={field_filters}' + '&SortBy=DateCreated' + '&SortOrder=Descending' + '&Filters={IsUnplayed,}IsNotFolder' + '&Recursive=true' + '&IncludeItemTypes=Episode' + '&ImageTypeLimit=1' + '&format=json'), 'media_type': 'Episodes', 'name_format': 'Episode|episode_name_format' }) collections.append({ 'title': item_name + i18n('_next_up'), 'thumbnail': downloadUtils.getArtwork(item, "Primary", server=server), 'path': ('{server}/emby/Shows/NextUp/?Userid={userid}' + '&ParentId=' + item.get("Id") + '&Limit={ItemLimit}' + '&Recursive=true' + '&Fields={field_filters}' + '&Filters=IsUnplayed,IsNotFolder' + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&IncludeItemTypes=Episode' + '&ImageTypeLimit=1' + '&format=json'), 'media_type': 'Episodes', 'name_format': 'Episode|episode_name_format' }) collections.append({ 'title': item_name + i18n('_genres'), 'item_type': 'plugin_link', 'thumbnail': downloadUtils.getArtwork(item, "Primary", server=server), 'path': 'plugin://plugin.video.embycon/?mode=GENRES&item_type=tvshow&parent_id=' + item.get("Id"), 'media_type': 'tvshows' }) if collection_type == "movies": collections.append({ 'title': item_name + i18n('_unwatched'), 'thumbnail': downloadUtils.getArtwork(item, "Primary", server=server), 'path': ('{server}/emby/Users/{userid}/Items' + '?ParentId=' + item.get("Id") + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&Fields={field_filters}' + '&Filters=IsUnplayed' + '&ImageTypeLimit=1' + '&format=json'), 'media_type': collection_type }) collections.append({ 'title': item_name + i18n('_in_progress'), 'thumbnail': downloadUtils.getArtwork(item, "Primary", server=server), 'path': ('{server}/emby/Users/{userid}/Items' + '?ParentId=' + item.get("Id") + '&Limit={ItemLimit}' + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&Fields={field_filters}' + '&Filters=IsResumable' + '&ImageTypeLimit=1' + '&format=json'), 'media_type': collection_type }) collections.append({ 'title': item_name + i18n('_recently_added'), 'thumbnail': downloadUtils.getArtwork(item, "Primary", server=server), 'path': ('{server}/emby/Users/{userid}/Items' + '?ParentId=' + item.get("Id") + '&Limit={ItemLimit}' + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&Fields={field_filters}' + '&SortBy=DateCreated' + '&SortOrder=Descending' + '&Filters={IsUnplayed,}IsNotFolder' + '&ImageTypeLimit=1' + '&format=json'), 'media_type': collection_type }) collections.append({ 'title': item_name + i18n('_genres'), 'item_type': 'plugin_link', 'thumbnail': downloadUtils.getArtwork(item, "Primary", server=server), 'path': 'plugin://plugin.video.embycon/?mode=GENRES&item_type=movie&parent_id=' + item.get("Id"), 'media_type': collection_type }) # Add standard nodes item_data = {} item_data['title'] = i18n('movies_all') item_data['media_type'] = 'Movies' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Fields={field_filters}' + '&Recursive=true' + '&IncludeItemTypes=Movie' + '&ImageTypeLimit=1' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('movies_unwatched') item_data['media_type'] = 'Movies' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Recursive=true' + '&Fields={field_filters}' + '&Filters=IsUnplayed' + '&IncludeItemTypes=Movie' + '&ImageTypeLimit=1' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('movies_in_progress') item_data['media_type'] = 'Movies' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Limit={ItemLimit}' + '&Recursive=true' + '&Fields={field_filters}' + '&Filters=IsResumable' + '&IncludeItemTypes=Movie' + '&ImageTypeLimit=1' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('movies_recently_added') item_data['media_type'] = 'Movies' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Limit={ItemLimit}' + '&Recursive=true' + '&SortBy=DateCreated' + '&Fields={field_filters}' + '&SortOrder=Descending' + '&Filters={IsUnplayed,}IsNotFolder' + '&IncludeItemTypes=Movie' + '&ImageTypeLimit=1' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('movies_favorites') item_data['media_type'] = 'Movies' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Fields={field_filters}' + '&Recursive=true' + '&Filters=IsFavorite' + '&IncludeItemTypes=Movie' + '&ImageTypeLimit=1' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('movies_boxsets') item_data['media_type'] = 'BoxSets' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Recursive=true' + '&Fields={field_filters}' + '&IncludeItemTypes=BoxSet' + '&ImageTypeLimit=1' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('tvshows_all') item_data['media_type'] = 'tvshows' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Fields={field_filters}' + '&Recursive=true' + '&IncludeItemTypes=Series' + '&ImageTypeLimit=1' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('tvshows_unwatched') item_data['media_type'] = 'tvshows' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Fields={field_filters}' + '&Recursive=true' + '&Filters=IsUnplayed' + '&IncludeItemTypes=Series' + '&ImageTypeLimit=1' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('tvshows_favorites') item_data['media_type'] = 'tvshows' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Fields={field_filters}' + '&Recursive=true' + '&Filters=IsFavorite' + '&IncludeItemTypes=Series' + '&ImageTypeLimit=1' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('tvshows_latest') item_data['media_type'] = 'Episodes' item_data['path'] = ('{server}/emby/Users/{userid}/Items/Latest' + '?Limit={ItemLimit}' + '&Recursive=true' + '&GroupItems=true' + '&SortBy=DateCreated' + '&Fields={field_filters}' + '&SortOrder=Descending' + '&Filters={IsUnplayed}' + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&IncludeItemTypes=Episode' + '&ImageTypeLimit=1' + '&format=json') item_data['name_format'] = 'Episode|episode_name_format' collections.append(item_data) item_data = {} item_data['title'] = i18n('episodes_in_progress') item_data['media_type'] = 'Episodes' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Limit={ItemLimit}' + '&Recursive=true' + '&Fields={field_filters}' + '&Filters=IsResumable' + '&IncludeItemTypes=Episode' + '&ImageTypeLimit=1' + '&format=json') item_data['name_format'] = 'Episode|episode_name_format' collections.append(item_data) item_data = {} item_data['title'] = i18n('episodes_recently_added') item_data['media_type'] = 'Episodes' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Limit={ItemLimit}' + '&Recursive=true' + '&SortBy=DateCreated' + '&Fields={field_filters}' + '&SortOrder=Descending' + '&Filters={IsUnplayed,}IsNotFolder' + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&IncludeItemTypes=Episode' + '&ImageTypeLimit=1' + '&format=json') item_data['name_format'] = 'Episode|episode_name_format' collections.append(item_data) item_data = {} item_data['title'] = i18n('episodes_up_next') item_data['media_type'] = 'Episodes' item_data['path'] = ('{server}/emby/Shows/NextUp/?Userid={userid}' + '&Limit={ItemLimit}' + '&Recursive=true' + '&Fields={field_filters}' + '&Filters=IsUnplayed,IsNotFolder' + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&IncludeItemTypes=Episode' + '&ImageTypeLimit=1' + '&format=json') item_data['name_format'] = 'Episode|episode_name_format' collections.append(item_data) item_data = {} item_data['title'] = i18n('upcoming_tv') item_data['media_type'] = 'Episodes' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Recursive=true' + '&SortBy=PremiereDate' + '&Fields={field_filters}' + '&SortOrder=Ascending' + '&IsVirtualUnaired=true' + '&IsNotFolder' + '&IncludeItemTypes=Episode' + '&ImageTypeLimit=1' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('music_all_albums') item_data['media_type'] = 'MusicAlbums' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Recursive=true' + '&IncludeItemTypes=MusicAlbum' + '&ImageTypeLimit=1' + '&EnableImageTypes=Primary,Backdrop,Banner,Thumb' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('music_all_artists') item_data['media_type'] = 'MusicArtists' item_data['path'] = ('{server}/emby/Artists/AlbumArtists' + '?Recursive=true' + '&ImageTypeLimit=1' + '&EnableImageTypes=Primary,Backdrop,Banner,Thumb' + '&format=json') collections.append(item_data) return collections
def showGenreList(params): log.debug("showGenreList: {0}", params) server = downloadUtils.getServer() if server is None: return parent_id = params.get("parent_id") item_type = params.get("item_type") kodi_type = "Movies" emby_type = "Movie" if item_type is not None and item_type == "tvshow": emby_type = "Series" kodi_type = "tvshows" url = ("{server}/emby/Genres?" + "SortBy=SortName" + "&SortOrder=Ascending" + "&IncludeItemTypes=" + emby_type + "&Recursive=true" + "&UserId={userid}") if parent_id is not None: url += "&parentid=" + parent_id data_manager = DataManager() result = data_manager.GetContent(url) if result is not None: result = result.get("Items") else: result = [] collections = [] xbmcplugin.setContent(int(sys.argv[1]), 'genres') for genre in result: item_data = {} item_data['title'] = genre.get("Name") item_data['media_type'] = kodi_type item_data['thumbnail'] = downloadUtils.getArtwork(genre, "Primary", server=server) url = ("{server}/emby/Users/{userid}/Items" + "?Fields={field_filters}" + "&Recursive=true" + "&GenreIds=" + genre.get("Id") + "&IncludeItemTypes=" + emby_type + "&ImageTypeLimit=1") if parent_id is not None: url += "&parentid=" + parent_id item_data['path'] = url collections.append(item_data) for collection in collections: url = sys.argv[0] + ("?url=" + urllib.quote(collection['path']) + "&mode=GET_CONTENT" + "&media_type=" + collection["media_type"]) log.debug("addMenuDirectoryItem: {0} - {1} - {2}", collection.get('title'), url, collection.get("thumbnail")) addMenuDirectoryItem(collection.get('title', i18n('unknown')), url, thumbnail=collection.get("thumbnail")) xbmcplugin.endOfDirectory(int(sys.argv[1]))
def displaySections(): log.debug("== ENTER: displaySections() ==") xbmcplugin.setContent(int(sys.argv[1]), 'files') server = downloadUtils.getServer() if server is None: return # Add collections collections = getCollections() if collections: for collection in collections: if collection.get("item_type") == "plugin_link": plugin_path = collection['path'] addMenuDirectoryItem(collection.get('title', i18n('unknown')), plugin_path, thumbnail=collection.get("thumbnail")) else: url = (sys.argv[0] + "?url=" + urllib.quote(collection['path']) + "&mode=GET_CONTENT&media_type=" + collection["media_type"]) if collection.get("name_format") is not None: url += "&name_format=" + urllib.quote( collection.get("name_format")) log.debug("addMenuDirectoryItem: {0} ({1})", collection.get('title'), url) addMenuDirectoryItem(collection.get('title', i18n('unknown')), url, thumbnail=collection.get("thumbnail")) addMenuDirectoryItem( i18n('movies_year'), "plugin://plugin.video.embycon/?mode=MOVIE_YEARS") addMenuDirectoryItem( i18n('movies_genre'), "plugin://plugin.video.embycon/?mode=GENRES&item_type=movie") addMenuDirectoryItem( i18n('movies_az'), "plugin://plugin.video.embycon/?mode=MOVIE_ALPHA") addMenuDirectoryItem( i18n('tvshow_genre'), "plugin://plugin.video.embycon/?mode=GENRES&item_type=tvshow") addMenuDirectoryItem(i18n('search'), "plugin://plugin.video.embycon/?mode=SEARCH") addMenuDirectoryItem( i18n('show_clients'), "plugin://plugin.video.embycon/?mode=SHOW_SERVER_SESSIONS") addMenuDirectoryItem( i18n('change_user'), "plugin://plugin.video.embycon/?mode=CHANGE_USER") addMenuDirectoryItem( i18n('detect_server'), "plugin://plugin.video.embycon/?mode=DETECT_SERVER_USER") addMenuDirectoryItem(i18n('show_settings'), "plugin://plugin.video.embycon/?mode=SHOW_SETTINGS") # only add these if we have other collection which means we have a valid server conn if collections: addMenuDirectoryItem( i18n('cache_textures'), "plugin://plugin.video.embycon/?mode=CACHE_ARTWORK") addMenuDirectoryItem(i18n('widgets'), "plugin://plugin.video.embycon/?mode=WIDGETS") xbmcplugin.endOfDirectory(int(sys.argv[1]))
def showMoviePages(params): log.debug("showMoviePages: {0}", params) parent_id = params.get("parent_id") url = ('{server}/emby/Users/{userid}/Items' + '?IsVirtualUnaired=false' + '&CollapseBoxSetItems=true' + '&Recursive=true' + "&IncludeItemTypes=Movie" '&IsMissing=False' + '&ImageTypeLimit=0' + '&format=json') if parent_id: url += "&ParentId=" + parent_id data_manager = DataManager() result = data_manager.GetContent(url) if result is None: return total_results = result.get("TotalRecordCount", 0) log.debug("showMoviePages TotalRecordCount {0}", total_results) if result == 0: return settings = xbmcaddon.Addon() page_limit = int(settings.getSetting('moviePageSize')) if page_limit == 0: page_limit = 20 start_index = 0 collections = [] while start_index < total_results: item_url = ("{server}/emby/Users/{userid}/Items" + "?IsVirtualUnaired=false" + "&CollapseBoxSetItems=true" + "&Recursive=true" + "&IsMissing=False" + "&IncludeItemTypes=Movie" "&Fields={field_filters}" + "&ImageTypeLimit=1" + "&SortBy=Name" + "&SortOrder=Ascending" + "&format=json") if parent_id: item_url += "&ParentId=" + parent_id item_url += "&StartIndex=" + str(start_index) + "&Limit=" + str(page_limit) page_upper = start_index + page_limit if page_upper > total_results: page_upper = total_results item_data = {} item_data['title'] = "Page (" + str(start_index + 1) + " - " + str(page_upper) + ")" item_data['path'] = item_url item_data['media_type'] = 'movies' collections.append(item_data) start_index = start_index + page_limit for collection in collections: content_url = urllib.quote(collection['path']) url = sys.argv[0] + ("?url=" + content_url + "&mode=GET_CONTENT" + "&media_type=" + collection["media_type"]) log.debug("addMenuDirectoryItem: {0} - {1} - {2}", collection.get('title'), url, collection.get("art")) addMenuDirectoryItem(collection.get('title', i18n('unknown')), url, art=collection.get("art")) xbmcplugin.endOfDirectory(int(sys.argv[1]))
def displaySections(): log.debug("== ENTER: displaySections() ==") xbmcplugin.setContent(int(sys.argv[1]), 'files') server = downloadUtils.getServer() if server is None: return # Add collections collections = getCollections() if collections: for collection in collections: if collection.get("item_type") == "plugin_link": plugin_path = collection['path'] addMenuDirectoryItem(collection.get('title', i18n('unknown')), plugin_path, art=collection.get("art")) else: url = (sys.argv[0] + "?url=" + urllib.quote(collection['path']) + "&mode=GET_CONTENT&media_type=" + collection["media_type"]) if collection.get("name_format") is not None: url += "&name_format=" + urllib.quote(collection.get("name_format")) log.debug("addMenuDirectoryItem: {0} ({1})", collection.get('title'), url) addMenuDirectoryItem(collection.get('title', i18n('unknown')), url, art=collection.get("art")) addMenuDirectoryItem(i18n('movies_year'), "plugin://plugin.video.embycon/?mode=MOVIE_YEARS") addMenuDirectoryItem(i18n('movies_genre'), "plugin://plugin.video.embycon/?mode=GENRES&item_type=movie") addMenuDirectoryItem(i18n('movies_az'), "plugin://plugin.video.embycon/?mode=MOVIE_ALPHA") addMenuDirectoryItem("Movie (Pages)", "plugin://plugin.video.embycon/?mode=MOVIE_PAGES") addMenuDirectoryItem(i18n('tvshow_genre'), "plugin://plugin.video.embycon/?mode=GENRES&item_type=tvshow") addMenuDirectoryItem(i18n('search'), "plugin://plugin.video.embycon/?mode=SEARCH") addMenuDirectoryItem(i18n('show_clients'), "plugin://plugin.video.embycon/?mode=SHOW_SERVER_SESSIONS") addMenuDirectoryItem(i18n('change_user'), "plugin://plugin.video.embycon/?mode=CHANGE_USER") addMenuDirectoryItem(i18n('detect_server'), "plugin://plugin.video.embycon/?mode=DETECT_SERVER_USER") addMenuDirectoryItem(i18n('show_settings'), "plugin://plugin.video.embycon/?mode=SHOW_SETTINGS") # only add these if we have other collection which means we have a valid server conn if collections: addMenuDirectoryItem(i18n('cache_textures'), "plugin://plugin.video.embycon/?mode=CACHE_ARTWORK") addMenuDirectoryItem(i18n('widgets'), "plugin://plugin.video.embycon/?mode=WIDGETS") xbmcplugin.endOfDirectory(int(sys.argv[1]))
def getContent(url, params): log.debug("== ENTER: getContent ==") media_type = params.get("media_type", None) if not media_type: xbmcgui.Dialog().ok(i18n('error'), i18n('no_media_type')) log.debug("URL: {0}", url) log.debug("MediaType: {0}", media_type) pluginhandle = int(sys.argv[1]) settings = xbmcaddon.Addon() # determine view type, map it from media type to view type view_type = "" content_type = "" media_type = str(media_type).lower().strip() if media_type.startswith("movie"): view_type = "Movies" content_type = 'movies' elif media_type == "musicalbums": view_type = "Albums" content_type = 'albums' elif media_type == "musicartists": view_type = "Artists" content_type = 'artists' elif media_type == "musicartist": view_type = "Albums" content_type = 'albums' elif media_type == "music" or media_type == "audio" or media_type == "musicalbum": view_type = "Music" content_type = 'songs' elif media_type.startswith("boxsets"): view_type = "Movies" content_type = 'sets' elif media_type.startswith("boxset"): view_type = "BoxSets" content_type = 'movies' elif media_type == "tvshows": view_type = "Series" content_type = 'tvshows' elif media_type == "series": view_type = "Seasons" content_type = 'seasons' elif media_type == "season" or media_type == "episodes": view_type = "Episodes" content_type = 'episodes' log.debug("media_type:{0} content_type:{1} view_type:{2} ", media_type, content_type, view_type) # show a progress indicator if needed progress = None if (settings.getSetting('showLoadProgress') == "true"): progress = xbmcgui.DialogProgress() progress.create(i18n('loading_content')) progress.update(0, i18n('retrieving_data')) # update url for paging start_index = 0 page_limit = int(settings.getSetting('moviePageSize')) if page_limit > 0 and media_type.startswith("movie"): url_prev = None m = re.search('StartIndex=([0-9]{1,4})', url) if m and m.group(1): log.debug("UPDATING NEXT URL: {0}", url) start_index = int(m.group(1)) log.debug("current_start : {0}", start_index) if start_index > 0: prev_index = start_index - page_limit if prev_index < 0: prev_index = 0 url_prev = re.sub('StartIndex=([0-9]{1,4})', 'StartIndex=' + str(prev_index), url) url_next = re.sub('StartIndex=([0-9]{1,4})', 'StartIndex=' + str(start_index + page_limit), url) log.debug("UPDATING NEXT URL: {0}", url_next) else: log.debug("ADDING NEXT URL: {0}", url) url_next = url + "&StartIndex=" + str(start_index + page_limit) + "&Limit=" + str(page_limit) url = url + "&StartIndex=" + str(start_index) + "&Limit=" + str(page_limit) log.debug("ADDING NEXT URL: {0}", url_next) # use the data manager to get the data result = dataManager.GetContent(url) total_records = 0 if result is not None and isinstance(result, dict): total_records = result.get("TotalRecordCount", 0) dir_items, detected_type = processDirectory(result, progress, params) if dir_items is None: return # add paging items if page_limit > 0 and media_type.startswith("movie"): if url_prev: list_item = xbmcgui.ListItem("Prev Page (" + str(start_index - page_limit + 1) + "-" + str(start_index) + " of " + str(total_records) + ")") u = sys.argv[0] + "?url=" + urllib.quote(url_prev) + "&mode=GET_CONTENT&media_type=movies" dir_items.insert(0, (u, list_item, True)) if start_index + page_limit < total_records: upper_count = start_index + (page_limit * 2) if upper_count > total_records: upper_count = total_records list_item = xbmcgui.ListItem("Next Page (" + str(start_index + page_limit + 1) + "-" + str(upper_count) + " of " + str(total_records) + ")") u = sys.argv[0] + "?url=" + urllib.quote(url_next) + "&mode=GET_CONTENT&media_type=movies" dir_items.append((u, list_item, True)) # set the Kodi content type if content_type: xbmcplugin.setContent(pluginhandle, content_type) elif detected_type is not None: # if the media type is not set then try to use the detected type log.debug("Detected content type: {0}", detected_type) if detected_type == "Movie": view_type = "Movies" content_type = 'movies' if detected_type == "Episode": view_type = "Episodes" content_type = 'episodes' xbmcplugin.setContent(pluginhandle, content_type) # set the sort items if page_limit > 0 and media_type.startswith("movie"): xbmcplugin.addSortMethod(pluginhandle, xbmcplugin.SORT_METHOD_UNSORTED) else: setSort(pluginhandle, view_type) xbmcplugin.addDirectoryItems(pluginhandle, dir_items) xbmcplugin.endOfDirectory(pluginhandle, cacheToDisc=False) # send display items event display_items_notification = {"view_type": view_type} send_event_notification("display_items", display_items_notification) if (progress != None): progress.update(100, i18n('done')) progress.close() return
def getContent(url, params): log.debug("== ENTER: getContent ==") media_type = params.get("media_type", None) if not media_type: xbmcgui.Dialog().ok(i18n('error'), i18n('no_media_type')) log.debug("URL: {0}", url) log.debug("MediaType: {0}", media_type) pluginhandle = int(sys.argv[1]) settings = xbmcaddon.Addon() # determine view type, map it from media type to view type viewType = "" media_type = str(media_type).lower().strip() if media_type.startswith("movie"): viewType = "Movies" xbmcplugin.setContent(pluginhandle, 'movies') elif media_type == "musicalbums": viewType = "Albums" xbmcplugin.setContent(pluginhandle, 'albums') elif media_type == "musicartists": viewType = "Artists" xbmcplugin.setContent(pluginhandle, 'artists') elif media_type == "musicartist": viewType = "Albums" xbmcplugin.setContent(pluginhandle, 'albums') elif media_type == "music" or media_type == "audio" or media_type == "musicalbum": viewType = "Music" xbmcplugin.setContent(pluginhandle, 'songs') elif media_type.startswith("boxsets"): viewType = "Movies" xbmcplugin.setContent(pluginhandle, 'sets') elif media_type.startswith("boxset"): viewType = "BoxSets" xbmcplugin.setContent(pluginhandle, 'movies') elif media_type == "tvshows": viewType = "Series" xbmcplugin.setContent(pluginhandle, 'tvshows') elif media_type == "series": viewType = "Seasons" xbmcplugin.setContent(pluginhandle, 'seasons') elif media_type == "season" or media_type == "episodes": viewType = "Episodes" xbmcplugin.setContent(pluginhandle, 'episodes') log.debug("ViewType: {0} media_type: {1}", viewType, media_type) # show a progress indicator if needed progress = None if (settings.getSetting('showLoadProgress') == "true"): progress = xbmcgui.DialogProgress() progress.create(i18n('loading_content')) progress.update(0, i18n('retrieving_data')) # use the data manager to get the data result = dataManager.GetContent(url) dirItems = processDirectory(result, progress, params) if dirItems is None: return # set the sort items setSort(pluginhandle, viewType) xbmcplugin.addDirectoryItems(pluginhandle, dirItems) xbmcplugin.endOfDirectory(pluginhandle, cacheToDisc=False) # send display items event display_items_notification = {"view_type": viewType} send_event_notification("display_items", display_items_notification) if (progress != None): progress.update(100, i18n('done')) progress.close() return
def showMenu(params): log.debug("showMenu(): {0}", params) item_id = params["item_id"] url = "{server}/emby/Users/{userid}/Items/" + item_id + "?format=json" data_manager = DataManager() result = data_manager.GetContent(url) log.debug("Playfile item info: {0}", result) if result is None: return action_items = [] if result["Type"] in ["Episode", "Movie", "Music"]: li = xbmcgui.ListItem(i18n('play')) li.setProperty('menu_id', 'play') action_items.append(li) if result["Type"] in ["Season", "MusicAlbum"]: li = xbmcgui.ListItem(i18n('play_all')) li.setProperty('menu_id', 'play_all') action_items.append(li) if result["Type"] in ["Episode", "Movie"]: li = xbmcgui.ListItem(i18n('emby_force_transcode')) li.setProperty('menu_id', 'transcode') action_items.append(li) if result["Type"] == "Movie": li = xbmcgui.ListItem(i18n('play_trailer')) li.setProperty('menu_id', 'play_trailer') action_items.append(li) if result["Type"] == "Episode" and result["ParentId"] is not None: li = xbmcgui.ListItem(i18n('view_season')) li.setProperty('menu_id', 'view_season') action_items.append(li) user_data = result["UserData"] if user_data.get("Played", False) is False: li = xbmcgui.ListItem(i18n('emby_mark_watched')) li.setProperty('menu_id', 'mark_watched') action_items.append(li) else: li = xbmcgui.ListItem(i18n('emby_mark_unwatched')) li.setProperty('menu_id', 'mark_unwatched') action_items.append(li) if user_data["IsFavorite"] == False: li = xbmcgui.ListItem(i18n('emby_set_favorite')) li.setProperty('menu_id', 'emby_set_favorite') action_items.append(li) else: li = xbmcgui.ListItem(i18n('emby_unset_favorite')) li.setProperty('menu_id', 'emby_unset_favorite') action_items.append(li) li = xbmcgui.ListItem(i18n('emby_delete')) li.setProperty('menu_id', 'delete') action_items.append(li) #xbmcplugin.endOfDirectory(int(sys.argv[1]), cacheToDisc=False) action_menu = ActionMenu("ActionMenu.xml", PLUGINPATH, "default", "720p") action_menu.setActionItems(action_items) action_menu.doModal() selected_action_item = action_menu.getActionItem() selected_action = "" if selected_action_item is not None: selected_action = selected_action_item.getProperty('menu_id') log.debug("Menu Action Selected: {0}", selected_action_item) del action_menu if selected_action == "play": log.debug("Play Item") #list_item = populate_listitem(params["item_id"]) #result = xbmcgui.Dialog().info(list_item) #log.debug("xbmcgui.Dialog().info: {0}", result) PLAY(params) elif selected_action == "play_all": PLAY(params) elif selected_action == "play_trailer": playTrailer(item_id) elif selected_action == "transcode": params['force_transcode'] = 'true' PLAY(params) elif selected_action == "emby_set_favorite": markFavorite(item_id) elif selected_action == "emby_unset_favorite": unmarkFavorite(item_id) elif selected_action == "mark_watched": markWatched(item_id) elif selected_action == "mark_unwatched": markUnwatched(item_id) elif selected_action == "delete": delete(result) elif selected_action == "view_season": parent_id = result["ParentId"] xbmc.executebuiltin( 'ActivateWindow(Videos, plugin://plugin.video.embycon/?mode=PARENT_CONTENT&ParentId={0}&media_type=episodes, return)'.format(parent_id))
def searchResults(params): item_type = params.get('item_type') query_string = params.get('query') if query_string: log.debug("query_string : {0}", query_string) query_string = urllib.unquote(query_string) log.debug("query_string : {0}", query_string) query_string = urllib.quote(query_string) log.debug("query_string : {0}", query_string) item_type = item_type.lower() if item_type == 'movie': heading_type = i18n('movies') content_type = 'movies' elif item_type == 'series': heading_type = i18n('tvshows') content_type = 'tvshows' elif item_type == 'episode': heading_type = i18n('episodes') content_type = 'episodes' params["name_format"] = "Episode|episode_name_format" elif item_type == "music" or item_type == "audio" or item_type == "musicalbum": heading_type = 'Music' content_type = 'songs' elif item_type == "musicartists": heading_type = 'Artists' content_type = 'artists' else: heading_type = item_type content_type = 'video' handle = int(sys.argv[1]) if not query_string: home_window = HomeWindow() last_search = home_window.getProperty("last_search") kb = xbmc.Keyboard() kb.setHeading(heading_type.capitalize() + ' ' + i18n('search').lower()) kb.setDefault(last_search) kb.doModal() if kb.isConfirmed(): user_input = kb.getText().strip() else: return home_window.setProperty("last_search", user_input) log.debug('searchResults Called: {0}', params) query = user_input else: query = query_string if (not item_type) or (not query): return limit = int(params.get('limit', 20)) content_url = ('{server}/emby/Search/Hints?searchTerm=' + query + '&UserId={userid}' + '&Limit=' + str(limit) + '&IncludeItemTypes=' + item_type + '&ExcludeItemTypes=LiveTvProgram' + '&IncludePeople=false' + '&IncludeMedia=true' + '&IncludeGenres=false' + '&IncludeStudios=false' + '&IncludeArtists=false') if item_type == "musicartists": content_url = ('{server}/emby/Search/Hints?searchTerm=' + query + '&UserId={userid}' + '&Limit=' + str(limit) + '&IncludePeople=false' + '&IncludeMedia=false' + '&IncludeGenres=false' + '&IncludeStudios=false' + '&IncludeArtists=true') # set content type xbmcplugin.setContent(handle, content_type) # show a progress indicator if needed settings = xbmcaddon.Addon() progress = None if settings.getSetting('showLoadProgress') == "true": progress = xbmcgui.DialogProgress() progress.create(i18n('loading_content')) progress.update(0, i18n('retrieving_data')) search_hints_result = dataManager.GetContent(content_url) log.debug('SearchHints jsonData: {0}', search_hints_result) if search_hints_result is None: search_hints_result = {} search_hints = search_hints_result.get('SearchHints') if search_hints is None: search_hints = [] total_results = int(search_hints_result.get('TotalRecordCount', 0)) log.debug('SEARCH_TOTAL_RESULTS: {0}', total_results) # extract IDs for details query id_list = [] for item in search_hints: item_id = item.get('ItemId') id_list.append(item_id) if len(id_list) > 0: Ids = ",".join(id_list) details_url = ('{server}/emby/Users/{userid}/items' + '?Ids=' + Ids + '&Fields={field_filters}' + '&format=json') details_result = dataManager.GetContent(details_url) log.debug("Search Results Details: {0}", details_result) dir_items, detected_type = processDirectory(details_result, progress, params) if dir_items is not None: xbmcplugin.addDirectoryItems(handle, dir_items) xbmcplugin.endOfDirectory(handle, cacheToDisc=False) elif not query_string: xbmcgui.Dialog().ok("No Matches", "No items match your search.") if progress is not None: progress.update(100, i18n('done')) progress.close()
secure = False for user in result: if (user.get("Name") == unicode(userName, "utf-8")): userid = user.get("Id") userImage = self.get_user_artwork(user, 'Primary') log.debug("Username Found: {0}", user.get("Name")) if (user.get("HasPassword") == True): secure = True log.debug("Username Is Secure (HasPassword=True)") break if secure or not userid: authOk = self.authenticate() if authOk == "": xbmcgui.Dialog().notification(i18n("connection_error"), i18n('incorrect_user_pass'), icon="special://home/addons/plugin.video.embycon/icon.png") return "" if not userid: userid = WINDOW.getProperty("userid") if userid and not userImage: userImage = 'DefaultUser.png' if userid == "": xbmcgui.Dialog().notification(i18n("connection_error"), i18n('username_not_found'), icon="special://home/addons/plugin.video.embycon/icon.png") log.debug("userid: {0}", userid)
def checkServer(force=False, change_user=False, notify=False): log.debug("checkServer Called") settings = xbmcaddon.Addon() serverUrl = "" something_changed = False if force is False: # if not forcing use server details from settings svr = downloadUtils.getServer() if svr is not None: serverUrl = svr # if the server is not set then try to detect it if serverUrl == "": serverInfo = getServerDetails() serverNames = [] for server in serverInfo: serverNames.append(server.get("Name", i18n('n/a'))) if serverNames: return_index = xbmcgui.Dialog().select(i18n('select_server'), serverNames) else: xbmcgui.Dialog().ok(__addon_name__, i18n('no_server_detected')) return_index = -1 if (return_index == -1): xbmc.executebuiltin("ActivateWindow(Home)") return serverUrl = serverInfo[return_index]["Address"] log.debug("Selected server: {0}", serverUrl) # parse the url url_bits = urlparse(serverUrl) server_address = url_bits.hostname server_port = str(url_bits.port) server_protocol = url_bits.scheme log.debug("Detected server info {0} - {1} - {2}", server_protocol, server_address, server_port) # save the server info settings.setSetting("port", server_port) settings.setSetting("ipaddress", server_address) if server_protocol == "https": settings.setSetting("use_https", "true") else: settings.setSetting("use_https", "false") something_changed = True if notify: xbmcgui.Dialog().ok(i18n('server_detect_succeeded'), i18n('found_server'), i18n('address:') + server_address, i18n('server_port:') + server_port) # we need to change the user current_username = settings.getSetting("username") current_username = unicode(current_username, "utf-8") # if asked or we have no current user then show user selection screen if change_user or len(current_username) == 0: # get a list of users log.debug("Getting user list") jsonData = downloadUtils.downloadUrl(serverUrl + "/emby/Users/Public?format=json", authenticate=False) # TODO: add a setting to enable this show_manual = False log.debug("jsonData: {0}", jsonData) try: result = json.loads(jsonData) except: result = None if result is None: xbmcgui.Dialog().ok(i18n('error'), i18n('unable_connect_server'), i18n('address:') + serverUrl) else: selected_id = 0 names = [] user_list = [] secured = [] for user in result: config = user.get("Configuration") if (config != None): if (config.get("IsHidden") is None) or (config.get("IsHidden") is False): name = user.get("Name") user_list.append(name) if (user.get("HasPassword") is True): secured.append(True) name = i18n('username_secured') % name else: secured.append(False) names.append(name) if current_username == name: selected_id = len(names) - 1 if (len(current_username) > 0) and (not any(n == current_username for n in user_list)): names.insert(0, i18n('username_userdefined') % current_username) user_list.insert(0, current_username) secured.insert(0, True) if show_manual: names.append(i18n('username_userinput')) user_list.append('') secured.append(True) log.debug("User List: {0}", names) log.debug("User List: {0}", user_list) if current_username: selection_title = i18n('select_user') + " (" + current_username + ")" else: selection_title = i18n('select_user') return_value = xbmcgui.Dialog().select(selection_title, names, preselect=selected_id) if return_value > -1 and return_value != selected_id: log.debug("Selected User Index: {0}", return_value) if show_manual and return_value == (len(user_list) -1): kb = xbmc.Keyboard() kb.setHeading(i18n('username:'******'password', saved_password) else: kb = xbmc.Keyboard() kb.setHeading(i18n('password:'******'password', kb.getText()) # should we save the password save_password = xbmcgui.Dialog().yesno( "Save Password?", "Do you want to save the password?") if save_password: log.debug("Saving password for fast user switching: {0}", hashed_username) settings.setSetting("saved_user_password_" + hashed_username, kb.getText()) else: log.debug("Saving username is no password: {0}", selected_user) settings.setSetting("username", selected_user) settings.setSetting('password', '') if something_changed: home_window = HomeWindow() home_window.clearProperty("userid") home_window.clearProperty("AccessToken") home_window.setProperty("embycon_widget_reload", str(time.time())) download_utils = DownloadUtils() download_utils.authenticate() download_utils.getUserId() xbmc.executebuiltin("ActivateWindow(Home)") xbmc.executebuiltin("ReloadSkin()")
def cache_artwork(self, progress): log.debug("cache_artwork") # is the web server enabled web_query = {"setting": "services.webserver"} result = json_rpc('Settings.GetSettingValue').execute(web_query) xbmc_webserver_enabled = result['result']['value'] if not xbmc_webserver_enabled: log.debug("Kodi web server not enabled, can not cache images") return # get the port web_port = {"setting": "services.webserverport"} result = json_rpc('Settings.GetSettingValue').execute(web_port) xbmc_port = result['result']['value'] log.debug("xbmc_port: {0}", xbmc_port) # get the user web_user = {"setting": "services.webserverusername"} result = json_rpc('Settings.GetSettingValue').execute(web_user) xbmc_username = result['result']['value'] log.debug("xbmc_username: {0}", xbmc_username) # get the password web_pass = {"setting": "services.webserverpassword"} result = json_rpc('Settings.GetSettingValue').execute(web_pass) xbmc_password = result['result']['value'] params = {"properties": ["url"]} json_result = json_rpc('Textures.GetTextures').execute(params) textures = json_result.get("result", {}).get("textures", []) if self.stop_all_activity: return texture_urls = set() for texture in textures: url = texture.get("url") url = urllib.unquote(url) url = url.replace("image://", "") url = url[0:-1] texture_urls.add(url) del textures del json_result if self.stop_all_activity: return url = ('{server}/emby/Users/{userid}/Items?' + '&Recursive=true' + '&IncludeItemTypes=Movie,Series,Episode,BoxSet' + '&ImageTypeLimit=1' + '&format=json') data_manager = DataManager() results = data_manager.GetContent(url) if results is None: results = [] if isinstance(results, dict): results = results.get("Items") server = downloadUtils.getServer() missing_texture_urls = set() if self.stop_all_activity: return image_types = ["thumb", "poster", "banner", "clearlogo", "tvshow.poster", "tvshow.banner", "tvshow.landscape"] for item in results: art = getArt(item, server) for image_type in art: image_url = art[image_type] if image_url not in texture_urls and not image_url.endswith("&Tag=") and len(image_url) > 0: missing_texture_urls.add(image_url) if self.stop_all_activity: return log.debug("texture_urls: {0}", texture_urls) log.debug("missing_texture_urls: {0}", missing_texture_urls) log.debug("Number of existing textures: {0}", len(texture_urls)) log.debug("Number of missing textures: {0}", len(missing_texture_urls)) kodi_http_server = "localhost:" + str(xbmc_port) headers = {} if xbmc_password: auth = "%s:%s" % (xbmc_username, xbmc_password) headers = {'Authorization': 'Basic %s' % base64.b64encode(auth)} total = len(missing_texture_urls) index = 1 count_done = 0 for get_url in missing_texture_urls: log.debug("texture_url: {0}", get_url) url = double_urlencode(get_url) kodi_texture_url = ("/image/image://%s" % url) log.debug("kodi_texture_url: {0}", kodi_texture_url) percentage = int((float(index) / float(total)) * 100) message = "%s of %s" % (index, total) progress.update(percentage, "%s" % (message)) conn = httplib.HTTPConnection(kodi_http_server, timeout=20) conn.request(method="GET", url=kodi_texture_url, headers=headers) data = conn.getresponse() if data.status == 200: count_done += 1 log.debug("Get Image Result: {0}", data.status) index += 1 if "iscanceled" in dir(progress) and progress.iscanceled(): break if self.stop_all_activity: break result_report = [] result_report.append(i18n('existing_textures') + str(len(texture_urls))) result_report.append(i18n('missing_textures') + str(len(missing_texture_urls))) result_report.append(i18n('loaded_textures') + str(count_done)) return result_report
def showGenreList(params): log.debug("showGenreList: {0}", params) server = downloadUtils.getServer() if server is None: return parent_id = params.get("parent_id") item_type = params.get("item_type") kodi_type = "Movies" emby_type = "Movie" if item_type is not None and item_type == "tvshow": emby_type = "Series" kodi_type = "tvshows" url = ("{server}/emby/Genres?" + "SortBy=Name" + "&SortOrder=Ascending" + "&IncludeItemTypes=" + emby_type + "&Recursive=true" + "&UserId={userid}") if parent_id is not None: url += "&parentid=" + parent_id data_manager = DataManager() result = data_manager.GetContent(url) if result is not None: result = result.get("Items") else: result = [] collections = [] xbmcplugin.setContent(int(sys.argv[1]), 'genres') for genre in result: art = getArt(item=genre, server=server) item_data = {} item_data['title'] = genre.get("Name") item_data['media_type'] = kodi_type item_data['art'] = art url = ("{server}/emby/Users/{userid}/Items" + "?Fields={field_filters}" + "&Recursive=true" + "&GenreIds=" + genre.get("Id") + "&IncludeItemTypes=" + emby_type + "&ImageTypeLimit=1") if parent_id is not None: url += "&parentid=" + parent_id item_data['path'] = url collections.append(item_data) for collection in collections: url = sys.argv[0] + ("?url=" + urllib.quote(collection['path']) + "&mode=GET_CONTENT" + "&media_type=" + collection["media_type"]) log.debug("addMenuDirectoryItem: {0} - {1} - {2}", collection.get('title'), url, collection.get("art")) addMenuDirectoryItem(collection.get('title', i18n('unknown')), url, art=collection.get("art")) xbmcplugin.endOfDirectory(int(sys.argv[1]))
def playAllFiles(items, monitor): log.debug("playAllFiles called with items: {0}", items) server = download_utils.getServer() playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() for item in items: item_id = item.get("Id") sources = item.get("MediaSources") selected_media_source = sources[0] listitem_props = [] playback_type = "0" playurl = None play_session_id = id_generator() log.debug("play_session_id: {0}", play_session_id) # check if strm file, path will contain contain strm contents if selected_media_source.get('Container') == 'strm': playurl, listitem_props = PlayUtils().getStrmDetails(selected_media_source) if playurl is None: return if not playurl: playurl, playback_type = PlayUtils().getPlayUrl(item_id, selected_media_source, False, play_session_id) log.debug("Play URL: {0} ListItem Properties: {1}", playurl, listitem_props) playback_type_string = "DirectPlay" if playback_type == "2": playback_type_string = "Transcode" elif playback_type == "1": playback_type_string = "DirectStream" # add the playback type into the overview if item.get("Overview", None) is not None: item["Overview"] = playback_type_string + "\n" + item.get("Overview") else: item["Overview"] = playback_type_string # add title decoration is needed item_title = item.get("Name", i18n('missing_title')) list_item = xbmcgui.ListItem(label=item_title) # add playurl and data to the monitor data = {} data["item_id"] = item_id data["playback_type"] = playback_type_string data["play_session_id"] = play_session_id data["play_action_type"] = "play_all" monitor.played_information[playurl] = data log.debug("Add to played_information: {0}", monitor.played_information) list_item.setPath(playurl) list_item = setListItemProps(item_id, list_item, item, server, listitem_props, item_title) playlist.add(playurl, list_item) xbmc.Player().play(playlist)
def playFile(play_info, monitor): id = play_info.get("item_id") # if this is a list of items them add them all to the play list if isinstance(id, list): return playListOfItems(id, monitor) auto_resume = play_info.get("auto_resume", "-1") force_transcode = play_info.get("force_transcode", False) media_source_id = play_info.get("media_source_id", "") use_default = play_info.get("use_default", False) log.debug("playFile id({0}) resume({1}) force_transcode({2})", id, auto_resume, force_transcode) settings = xbmcaddon.Addon() addon_path = settings.getAddonInfo('path') force_auto_resume = settings.getSetting('forceAutoResume') == 'true' jump_back_amount = int(settings.getSetting("jump_back_amount")) server = download_utils.getServer() url = "{server}/emby/Users/{userid}/Items/" + id + "?format=json" data_manager = DataManager() result = data_manager.GetContent(url) log.debug("Playfile item: {0}", result) if result is None: log.debug("Playfile item was None, so can not play!") return # if this is a season, tv show or album then play all items in that parent if result.get("Type") == "Season" or result.get("Type") == "MusicAlbum": log.debug("PlayAllFiles for parent item id: {0}", id) url = ('{server}/emby/Users/{userid}/items' + '?ParentId=' + id + '&Fields=MediaSources' + '&format=json') result = data_manager.GetContent(url) log.debug("PlayAllFiles items: {0}", result) # process each item items = result["Items"] if items is None: items = [] return playAllFiles(items, monitor) # select the media source to use media_sources = result.get('MediaSources') selected_media_source = None if media_sources is None or len(media_sources) == 0: log.debug("Play Failed! There is no MediaSources data!") return elif len(media_sources) == 1: selected_media_source = media_sources[0] elif media_source_id != "": for source in media_sources: if source.get("Id", "na") == media_source_id: selected_media_source = source break elif len(media_sources) > 1: sourceNames = [] for source in media_sources: sourceNames.append(source.get("Name", "na")) dialog = xbmcgui.Dialog() resp = dialog.select(i18n('select_source'), sourceNames) if resp > -1: selected_media_source = media_sources[resp] else: log.debug("Play Aborted, user did not select a MediaSource") return if selected_media_source is None: log.debug("Play Aborted, MediaSource was None") return seekTime = 0 auto_resume = int(auto_resume) # process user data for resume points if auto_resume != -1: seekTime = (auto_resume / 1000) / 10000 elif force_auto_resume: userData = result.get("UserData") reasonableTicks = int(userData.get("PlaybackPositionTicks")) / 1000 seekTime = reasonableTicks / 10000 else: userData = result.get("UserData") if userData.get("PlaybackPositionTicks") != 0: reasonableTicks = int(userData.get("PlaybackPositionTicks")) / 1000 seekTime = reasonableTicks / 10000 displayTime = str(timedelta(seconds=seekTime)) resumeDialog = ResumeDialog("ResumeDialog.xml", addon_path, "default", "720p") resumeDialog.setResumeTime("Resume from " + displayTime) resumeDialog.doModal() resume_result = resumeDialog.getResumeAction() del resumeDialog log.debug("Resume Dialog Result: {0}", resume_result) # check system settings for play action # if prompt is set ask to set it to auto resume params = {"setting": "myvideos.selectaction"} setting_result = json_rpc('Settings.getSettingValue').execute(params) log.debug("Current Setting (myvideos.selectaction): {0}", setting_result) current_value = setting_result.get("result", None) if current_value is not None: current_value = current_value.get("value", -1) if current_value not in (2,3): return_value = xbmcgui.Dialog().yesno(i18n('extra_prompt'), i18n('turn_on_auto_resume?')) if return_value: params = {"setting": "myvideos.selectaction", "value": 2} json_rpc_result = json_rpc('Settings.setSettingValue').execute(params) log.debug("Save Setting (myvideos.selectaction): {0}", json_rpc_result) if resume_result == 1: seekTime = 0 elif resume_result == -1: return listitem_props = [] playback_type = "0" playurl = None play_session_id = id_generator() log.debug("play_session_id: {0}", play_session_id) # check if strm file, path will contain contain strm contents if selected_media_source.get('Container') == 'strm': playurl, listitem_props = PlayUtils().getStrmDetails(selected_media_source) if playurl is None: return if not playurl: playurl, playback_type = PlayUtils().getPlayUrl(id, selected_media_source, force_transcode, play_session_id) log.debug("Play URL: {0} ListItem Properties: {1}", playurl, listitem_props) playback_type_string = "DirectPlay" if playback_type == "2": playback_type_string = "Transcode" elif playback_type == "1": playback_type_string = "DirectStream" # add the playback type into the overview if result.get("Overview", None) is not None: result["Overview"] = playback_type_string + "\n" + result.get("Overview") else: result["Overview"] = playback_type_string # add title decoration is needed item_title = result.get("Name", i18n('missing_title')) list_item = xbmcgui.ListItem(label=item_title) if playback_type == "2": # if transcoding then prompt for audio and subtitle playurl = audioSubsPref(playurl, list_item, selected_media_source, id, use_default) log.debug("New playurl for transcoding: {0}", playurl) elif playback_type == "1": # for direct stream add any streamable subtitles externalSubs(selected_media_source, list_item, id) # add playurl and data to the monitor data = {} data["item_id"] = id data["playback_type"] = playback_type_string data["play_session_id"] = play_session_id data["play_action_type"] = "play" monitor.played_information[playurl] = data log.debug("Add to played_information: {0}", monitor.played_information) list_item.setPath(playurl) list_item = setListItemProps(id, list_item, result, server, listitem_props, item_title) playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() playlist.add(playurl, list_item) xbmc.Player().play(playlist) send_next_episode_details(result) if seekTime == 0: return count = 0 while not xbmc.Player().isPlaying(): log.debug("Not playing yet...sleep for 1 sec") count = count + 1 if count >= 10: return else: xbmc.Monitor().waitForAbort(1) seekTime = seekTime - jump_back_amount target_seek = (seekTime - 5) current_position = 0 while current_position < target_seek: # xbmc.Player().pause() xbmc.sleep(100) xbmc.Player().seekTime(seekTime) xbmc.sleep(100) # xbmc.Player().play() current_position = xbmc.Player().getTime() log.debug("Playback_Start_Seek target:{0} current:{1}", target_seek, current_position)
def audioSubsPref(url, list_item, media_source, item_id, use_default): dialog = xbmcgui.Dialog() audioStreamsList = {} audioStreams = [] audioStreamsChannelsList = {} subtitleStreamsList = {} subtitleStreams = ['No subtitles'] downloadableStreams = [] selectAudioIndex = "" selectSubsIndex = "" playurlprefs = "%s" % url default_audio = media_source.get('DefaultAudioStreamIndex', 1) default_sub = media_source.get('DefaultSubtitleStreamIndex', "") media_streams = media_source['MediaStreams'] for stream in media_streams: # Since Emby returns all possible tracks together, have to sort them. index = stream['Index'] if 'Audio' in stream['Type']: codec = stream['Codec'] channelLayout = stream.get('ChannelLayout', "") try: track = "%s - %s - %s %s" % (index, stream['Language'], codec, channelLayout) except: track = "%s - %s %s" % (index, codec, channelLayout) audioStreamsChannelsList[index] = stream['Channels'] audioStreamsList[track] = index audioStreams.append(track) elif 'Subtitle' in stream['Type']: try: track = "%s - %s" % (index, stream['Language']) except: track = "%s - %s" % (index, stream['Codec']) default = stream['IsDefault'] forced = stream['IsForced'] downloadable = stream['IsTextSubtitleStream'] and stream['IsExternal'] and stream['SupportsExternalStream'] if default: track = "%s - Default" % track if forced: track = "%s - Forced" % track if downloadable: downloadableStreams.append(index) subtitleStreamsList[track] = index subtitleStreams.append(track) if use_default: playurlprefs += "&AudioStreamIndex=%s" % default_audio elif len(audioStreams) > 1: resp = dialog.select(i18n('select_audio_stream'), audioStreams) if resp > -1: # User selected audio selected = audioStreams[resp] selectAudioIndex = audioStreamsList[selected] playurlprefs += "&AudioStreamIndex=%s" % selectAudioIndex else: # User backed out of selection playurlprefs += "&AudioStreamIndex=%s" % default_audio elif len(audioStreams) == 1: # There's only one audiotrack. selectAudioIndex = audioStreamsList[audioStreams[0]] playurlprefs += "&AudioStreamIndex=%s" % selectAudioIndex if len(subtitleStreams) > 1: if use_default: playurlprefs += "&SubtitleStreamIndex=%s" % default_sub else: resp = dialog.select(i18n('select_subtitle'), subtitleStreams) if resp == 0: # User selected no subtitles pass elif resp > -1: # User selected subtitles selected = subtitleStreams[resp] selectSubsIndex = subtitleStreamsList[selected] # Load subtitles in the listitem if downloadable if selectSubsIndex in downloadableStreams: url = [("%s/Videos/%s/%s/Subtitles/%s/Stream.srt" % (download_utils.getServer(), item_id, item_id, selectSubsIndex))] log.debug("Streaming subtitles url: {0} {1}", selectSubsIndex, url) list_item.setSubtitles(url) else: # Burn subtitles playurlprefs += "&SubtitleStreamIndex=%s" % selectSubsIndex else: # User backed out of selection playurlprefs += "&SubtitleStreamIndex=%s" % default_sub # Get number of channels for selected audio track audioChannels = audioStreamsChannelsList.get(selectAudioIndex, 0) if audioChannels > 2: playurlprefs += "&AudioBitrate=384000" else: playurlprefs += "&AudioBitrate=192000" return playurlprefs
def cache_artwork(self, progress): log.debug("cache_artwork") # is the web server enabled web_query = {"setting": "services.webserver"} result = json_rpc('Settings.GetSettingValue').execute(web_query) xbmc_webserver_enabled = result['result']['value'] if not xbmc_webserver_enabled: log.debug("Kodi web server not enabled, can not cache images") return # get the port web_port = {"setting": "services.webserverport"} result = json_rpc('Settings.GetSettingValue').execute(web_port) xbmc_port = result['result']['value'] log.debug("xbmc_port: {0}", xbmc_port) # get the user web_user = {"setting": "services.webserverusername"} result = json_rpc('Settings.GetSettingValue').execute(web_user) xbmc_username = result['result']['value'] log.debug("xbmc_username: {0}", xbmc_username) # get the password web_pass = {"setting": "services.webserverpassword"} result = json_rpc('Settings.GetSettingValue').execute(web_pass) xbmc_password = result['result']['value'] params = {"properties": ["url"]} json_result = json_rpc('Textures.GetTextures').execute(params) textures = json_result.get("result", {}).get("textures", []) if self.stop_all_activity: return texture_urls = set() for texture in textures: url = texture.get("url") url = urllib.unquote(url) url = url.replace("image://", "") url = url[0:-1] texture_urls.add(url) del textures del json_result if self.stop_all_activity: return url = ('{server}/emby/Users/{userid}/Items?' + '&Recursive=true' + '&IncludeItemTypes=Movie,Series,Episode,BoxSet' + '&ImageTypeLimit=1' + '&format=json') data_manager = DataManager() results = data_manager.GetContent(url) if results is None: results = [] if isinstance(results, dict): results = results.get("Items") server = downloadUtils.getServer() missing_texture_urls = set() if self.stop_all_activity: return image_types = [ "thumb", "poster", "banner", "clearlogo", "tvshow.poster", "tvshow.banner", "tvshow.landscape" ] for item in results: art = getArt(item, server) for image_type in art: image_url = art[image_type] if image_url not in texture_urls and not image_url.endswith( "&Tag=") and len(image_url) > 0: missing_texture_urls.add(image_url) if self.stop_all_activity: return log.debug("texture_urls: {0}", texture_urls) log.debug("missing_texture_urls: {0}", missing_texture_urls) log.debug("Number of existing textures: {0}", len(texture_urls)) log.debug("Number of missing textures: {0}", len(missing_texture_urls)) kodi_http_server = "localhost:" + str(xbmc_port) headers = {} if xbmc_password: auth = "%s:%s" % (xbmc_username, xbmc_password) headers = {'Authorization': 'Basic %s' % base64.b64encode(auth)} total = len(missing_texture_urls) index = 1 count_done = 0 for get_url in missing_texture_urls: log.debug("texture_url: {0}", get_url) url = double_urlencode(get_url) kodi_texture_url = ("/image/image://%s" % url) log.debug("kodi_texture_url: {0}", kodi_texture_url) percentage = int((float(index) / float(total)) * 100) message = "%s of %s" % (index, total) progress.update(percentage, "%s" % (message)) conn = httplib.HTTPConnection(kodi_http_server, timeout=20) conn.request(method="GET", url=kodi_texture_url, headers=headers) data = conn.getresponse() if data.status == 200: count_done += 1 log.debug("Get Image Result: {0}", data.status) index += 1 if "iscanceled" in dir(progress) and progress.iscanceled(): break if self.stop_all_activity: break result_report = [] result_report.append( i18n('existing_textures') + str(len(texture_urls))) result_report.append( i18n('missing_textures') + str(len(missing_texture_urls))) result_report.append(i18n('loaded_textures') + str(count_done)) return result_report
def checkServer(force=False, change_user=False, notify=False): log.debug("checkServer Called") settings = xbmcaddon.Addon() serverUrl = "" if force is False: # if not forcing use server details from settings svr = downloadUtils.getServer() if svr is not None: serverUrl = svr # if the server is not set then try to detect it if serverUrl == "": serverInfo = getServerDetails() serverNames = [] for server in serverInfo: serverNames.append(server.get("Name", i18n('n/a'))) if serverNames: return_index = xbmcgui.Dialog().select(i18n('select_server'), serverNames) else: xbmcgui.Dialog().ok(__addon_name__, i18n('no_server_detected')) return_index = -1 if (return_index == -1): xbmc.executebuiltin("ActivateWindow(Home)") return serverUrl = serverInfo[return_index]["Address"] log.debug("Selected server: {0}", serverUrl) # parse the url url_bits = urlparse(serverUrl) server_address = url_bits.hostname server_port = str(url_bits.port) server_protocol = url_bits.scheme log.debug("Detected server info {0} - {1} - {2}", server_protocol, server_address, server_port) # save the server info settings.setSetting("port", server_port) settings.setSetting("ipaddress", server_address) if server_protocol == "https": settings.setSetting("use_https", "true") else: settings.setSetting("use_https", "false") if notify: xbmcgui.Dialog().ok(i18n('server_detect_succeeded'), i18n('found_server'), i18n('address:') + server_address, i18n('server_port:') + server_port) # we need to change the user current_username = settings.getSetting("username") current_username = unicode(current_username, "utf-8") # if asked or we have no current user then show user selection screen if change_user or len(current_username) == 0: # get a list of users log.debug("Getting user list") jsonData = downloadUtils.downloadUrl(serverUrl + "/emby/Users/Public?format=json", authenticate=False) log.debug("jsonData: {0}", jsonData) try: result = json.loads(jsonData) except: result = None if result is None: xbmcgui.Dialog().ok(i18n('error'), i18n('unable_connect_server'), i18n('address:') + serverUrl) else: names = [] user_list = [] secured = [] for user in result: config = user.get("Configuration") if (config != None): if (config.get("IsHidden") is None) or (config.get("IsHidden") is False): name = user.get("Name") user_list.append(name) if (user.get("HasPassword") is True): secured.append(True) name = i18n('username_secured') % name else: secured.append(False) names.append(name) if (len(current_username) > 0) and (not any(n == current_username for n in user_list)): names.insert(0, i18n('username_userdefined') % current_username) user_list.insert(0, current_username) secured.insert(0, True) names.insert(0, i18n('username_userinput')) user_list.insert(0, '') secured.insert(0, True) log.debug("User List: {0}", names) log.debug("User List: {0}", user_list) return_value = xbmcgui.Dialog().select(i18n('select_user'), names) if (return_value > -1): log.debug("Selected User Index: {0}", return_value) if return_value == 0: kb = xbmc.Keyboard() kb.setHeading(i18n('username:'******'password:'******'password', kb.getText()) else: settings.setSetting('password', '') home_window = HomeWindow() home_window.clearProperty("userid") home_window.clearProperty("AccessToken") xbmc.executebuiltin("ActivateWindow(Home)")
def getCollections(): log.debug("== ENTER: getCollections ==") server = downloadUtils.getServer() if server is None: return [] userid = downloadUtils.getUserId() if userid == None or len(userid) == 0: log.debug("No userid so returning []") return [] data_manager = DataManager() result = data_manager.GetContent("{server}/emby/Users/{userid}/Items/Root?format=json") if result is None: return [] parentid = result.get("Id") log.debug("parentid: {0}", parentid) htmlpath = "{server}/emby/Users/{userid}/Views?format=json" #htmlpath = "{server}/emby/Users/{userid}/items?ParentId=" + parentid + "&Sortby=SortName&format=json" result = data_manager.GetContent(htmlpath) if result is not None: result = result.get("Items") else: result = [] collections = [] for item in result: item_name = item.get("Name") collection_type = item.get('CollectionType', None) type = item.get('Type', None) log.debug("CollectionType: {0}", collection_type) log.debug("Title: {0}", item_name) art = getArt(item=item, server=server) art['landscape'] = downloadUtils.getArtwork(item, "Primary", server=server) if collection_type == "music": item_data = {} item_data['title'] = item_name + i18n('_all_albums') item_data['art'] = art item_data['media_type'] = 'MusicAlbums' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Recursive=true' + '&ParentId=' + item.get("Id") + '&IncludeItemTypes=MusicAlbum' + '&ImageTypeLimit=1' + '&EnableImageTypes=Primary,Backdrop,Banner,Thumb' + '&SortBy=Name' + '&SortOrder=Ascending' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = item_name + i18n('_all_artists') item_data['art'] = art item_data['media_type'] = 'MusicArtists' item_data['path'] = ('{server}/emby/Artists/AlbumArtists' + '?Recursive=true' + '&ParentId=' + item.get("Id") + '&ImageTypeLimit=1' + '&EnableImageTypes=Primary,Backdrop,Banner,Thumb' + '&SortBy=Name' + '&SortOrder=Ascending' + '&format=json') collections.append(item_data) if collection_type in ["movies", "boxsets"]: collections.append({ 'title': item_name, 'art': art, 'path': ('{server}/emby/Users/{userid}/Items' + '?ParentId=' + item.get("Id") + '&IsVirtualUnaired=false' + '&CollapseBoxSetItems=true' + '&Recursive=true' + '&IsMissing=False' + '&Fields={field_filters}' + '&ImageTypeLimit=1' + '&SortBy=Name' + '&SortOrder=Ascending' + '&format=json'), 'media_type': collection_type}) if collection_type == "tvshows": collections.append({ 'title': item_name, 'art': art, 'path': ('{server}/emby/Users/{userid}/Items' + '?ParentId=' + item.get("Id") + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&Fields={field_filters}' + '&ImageTypeLimit=1' + '&SortBy=Name' + '&SortOrder=Ascending' + '&format=json'), 'media_type': collection_type}) collections.append({ 'title': item_name + i18n('_unwatched'), 'art': art, 'path': ('{server}/emby/Users/{userid}/Items' + '?ParentId=' + item.get("Id") + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&Fields={field_filters}' + '&Filters=IsUnplayed' + '&Recursive=true' + '&IncludeItemTypes=Series' + '&SortBy=Name' + '&SortOrder=Ascending' + '&ImageTypeLimit=1' + '&format=json'), 'media_type': 'tvshows'}) collections.append({ 'title': item_name + i18n('_in_progress'), 'art': art, 'path': ('{server}/emby/Users/{userid}/Items' + '?ParentId=' + item.get("Id") + '&Limit={ItemLimit}' + '&SortBy=DatePlayed' + '&SortOrder=Descending' + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&Fields={field_filters}' + '&Filters=IsResumable' + '&Recursive=true' + '&IncludeItemTypes=Episode' + '&ImageTypeLimit=1' + '&format=json'), 'media_type': 'Episodes', 'name_format': 'Episode|episode_name_format'}) collections.append({ 'title': item_name + i18n('_latest'), 'art': art, 'path': ('{server}/emby/Users/{userid}/Items/Latest' + '?ParentId=' + item.get("Id") + '&Limit={ItemLimit}' + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&Fields={field_filters}' + '&SortBy=DateCreated' + '&SortOrder=Descending' + '&Filters=IsUnplayed' + '&Recursive=true' + '&IncludeItemTypes=Episode' + '&ImageTypeLimit=1' + '&format=json'), 'media_type': 'Episodes', 'name_format': 'Episode|episode_name_format'}) collections.append({ 'title': item_name + i18n('_recently_added'), 'art': art, 'path': ('{server}/emby/Users/{userid}/Items' + '?ParentId=' + item.get("Id") + '&Limit={ItemLimit}' + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&Fields={field_filters}' + '&SortBy=DateCreated' + '&SortOrder=Descending' + '&Filters={IsUnplayed,}IsNotFolder' + '&Recursive=true' + '&IncludeItemTypes=Episode' + '&ImageTypeLimit=1' + '&format=json'), 'media_type': 'Episodes', 'name_format': 'Episode|episode_name_format'}) collections.append({ 'title': item_name + i18n('_next_up'), 'art': art, 'path': ('{server}/emby/Shows/NextUp/?Userid={userid}' + '&ParentId=' + item.get("Id") + '&Limit={ItemLimit}' + '&Recursive=true' + '&Fields={field_filters}' + '&Filters=IsUnplayed,IsNotFolder' + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&IncludeItemTypes=Episode' + '&ImageTypeLimit=1' + '&format=json'), 'media_type': 'Episodes', 'name_format': 'Episode|episode_name_format'}) collections.append({ 'title': item_name + i18n('_genres'), 'item_type': 'plugin_link', 'art': art, 'path': 'plugin://plugin.video.embycon/?mode=GENRES&item_type=tvshow&parent_id=' + item.get("Id"), 'media_type': 'tvshows'}) if type == "Channel": collections.append({ 'title': item_name, 'art': art, 'path': ('{server}/emby/Users/{userid}/Items' + '?ParentId=' + item.get("Id") + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&Fields={field_filters}' + '&ImageTypeLimit=1' + '&format=json'), 'media_type': 'files', 'name_format': 'Episode|episode_name_format'}) if collection_type == "movies": collections.append({ 'title': item_name + i18n('_unwatched'), 'art': art, 'path': ('{server}/emby/Users/{userid}/Items' + '?ParentId=' + item.get("Id") + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&Fields={field_filters}' + '&Filters=IsUnplayed' + '&ImageTypeLimit=1' + '&SortBy=Name' + '&SortOrder=Ascending' + '&format=json'), 'media_type': collection_type}) collections.append({ 'title': item_name + i18n('_in_progress'), 'art': art, 'path': ('{server}/emby/Users/{userid}/Items' + '?ParentId=' + item.get("Id") + '&Limit={ItemLimit}' + '&SortBy=DatePlayed' + '&SortOrder=Descending' + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&Fields={field_filters}' + '&Filters=IsResumable' + '&ImageTypeLimit=1' + '&format=json'), 'media_type': collection_type}) collections.append({ 'title': item_name + i18n('_recently_added'), 'art': art, 'path': ('{server}/emby/Users/{userid}/Items' + '?ParentId=' + item.get("Id") + '&Limit={ItemLimit}' + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&Fields={field_filters}' + '&SortBy=DateCreated' + '&SortOrder=Descending' + '&Filters={IsUnplayed,}IsNotFolder' + '&ImageTypeLimit=1' + '&format=json'), 'media_type': collection_type}) collections.append({ 'title': item_name + i18n('_genres'), 'item_type': 'plugin_link', 'art': art, 'path': 'plugin://plugin.video.embycon/?mode=GENRES&item_type=movie&parent_id=' + item.get("Id"), 'media_type': collection_type}) collections.append({ 'title': item_name + ' - Pages', 'item_type': 'plugin_link', 'art': art, 'path': 'plugin://plugin.video.embycon/?mode=MOVIE_PAGES&parent_id=' + item.get("Id"), 'media_type': collection_type}) # Add standard nodes item_data = {} item_data['title'] = i18n('movies_all') item_data['media_type'] = 'Movies' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Fields={field_filters}' + '&Recursive=true' + '&IncludeItemTypes=Movie' + '&ImageTypeLimit=1' + '&SortBy=Name' + '&SortOrder=Ascending' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('movies_unwatched') item_data['media_type'] = 'Movies' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Recursive=true' + '&Fields={field_filters}' + '&Filters=IsUnplayed' + '&IncludeItemTypes=Movie' + '&ImageTypeLimit=1' + '&SortBy=Name' + '&SortOrder=Ascending' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('movies_in_progress') item_data['media_type'] = 'Movies' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Limit={ItemLimit}' + '&Recursive=true' + '&Fields={field_filters}' + '&SortBy=DatePlayed' + '&SortOrder=Descending' + '&Filters=IsResumable' + '&IncludeItemTypes=Movie' + '&ImageTypeLimit=1' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('movies_recently_added') item_data['media_type'] = 'Movies' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Limit={ItemLimit}' + '&Recursive=true' + '&SortBy=DateCreated' + '&Fields={field_filters}' + '&SortOrder=Descending' + '&Filters={IsUnplayed,}IsNotFolder' + '&IncludeItemTypes=Movie' + '&ImageTypeLimit=1' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('movies_favorites') item_data['media_type'] = 'Movies' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Fields={field_filters}' + '&Recursive=true' + '&Filters=IsFavorite' + '&IncludeItemTypes=Movie' + '&ImageTypeLimit=1' + '&SortBy=Name' + '&SortOrder=Ascending' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('movies_boxsets') item_data['media_type'] = 'BoxSets' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Recursive=true' + '&Fields={field_filters}' + '&IncludeItemTypes=BoxSet' + '&ImageTypeLimit=1' + '&SortBy=Name' + '&SortOrder=Ascending' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('tvshows_all') item_data['media_type'] = 'tvshows' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Fields={field_filters}' + '&Recursive=true' + '&IncludeItemTypes=Series' + '&ImageTypeLimit=1' + '&SortBy=Name' + '&SortOrder=Ascending' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('tvshows_unwatched') item_data['media_type'] = 'tvshows' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Fields={field_filters}' + '&Recursive=true' + '&Filters=IsUnplayed' + '&IncludeItemTypes=Series' + '&ImageTypeLimit=1' + '&SortBy=Name' + '&SortOrder=Ascending' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('tvshows_favorites') item_data['media_type'] = 'tvshows' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Fields={field_filters}' + '&Recursive=true' + '&Filters=IsFavorite' + '&IncludeItemTypes=Series' + '&ImageTypeLimit=1' + '&SortBy=Name' + '&SortOrder=Ascending' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('tvshows_latest') item_data['media_type'] = 'Episodes' item_data['path'] = ('{server}/emby/Users/{userid}/Items/Latest' + '?Limit={ItemLimit}' + '&Recursive=true' + '&GroupItems=true' + '&SortBy=DateCreated' + '&Fields={field_filters}' + '&SortOrder=Descending' + '&Filters={IsUnplayed}' + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&IncludeItemTypes=Episode' + '&ImageTypeLimit=1' + '&format=json') item_data['name_format'] = 'Episode|episode_name_format' collections.append(item_data) item_data = {} item_data['title'] = i18n('episodes_in_progress') item_data['media_type'] = 'Episodes' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Limit={ItemLimit}' + '&SortBy=DatePlayed' + '&SortOrder=Descending' + '&Recursive=true' + '&Fields={field_filters}' + '&Filters=IsResumable' + '&IncludeItemTypes=Episode' + '&ImageTypeLimit=1' + '&format=json') item_data['name_format'] = 'Episode|episode_name_format' collections.append(item_data) item_data = {} item_data['title'] = i18n('episodes_recently_added') item_data['media_type'] = 'Episodes' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Limit={ItemLimit}' + '&Recursive=true' + '&SortBy=DateCreated' + '&Fields={field_filters}' + '&SortOrder=Descending' + '&Filters={IsUnplayed,}IsNotFolder' + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&IncludeItemTypes=Episode' + '&ImageTypeLimit=1' + '&format=json') item_data['name_format'] = 'Episode|episode_name_format' collections.append(item_data) item_data = {} item_data['title'] = i18n('episodes_up_next') item_data['media_type'] = 'Episodes' item_data['path'] = ('{server}/emby/Shows/NextUp/?Userid={userid}' + '&Limit={ItemLimit}' + '&Recursive=true' + '&Fields={field_filters}' + '&Filters=IsUnplayed,IsNotFolder' + '&IsVirtualUnaired=false' + '&IsMissing=False' + '&IncludeItemTypes=Episode' + '&ImageTypeLimit=1' + '&format=json') item_data['name_format'] = 'Episode|episode_name_format' collections.append(item_data) item_data = {} item_data['title'] = i18n('upcoming_tv') item_data['media_type'] = 'Episodes' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Recursive=true' + '&SortBy=PremiereDate' + '&Fields={field_filters}' + '&SortOrder=Ascending' + '&IsVirtualUnaired=true' + '&IsNotFolder' + '&IncludeItemTypes=Episode' + '&ImageTypeLimit=1' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('music_all_albums') item_data['media_type'] = 'MusicAlbums' item_data['path'] = ('{server}/emby/Users/{userid}/Items' + '?Recursive=true' + '&IncludeItemTypes=MusicAlbum' + '&ImageTypeLimit=1' + '&EnableImageTypes=Primary,Backdrop,Banner,Thumb' + '&SortBy=Name' + '&SortOrder=Ascending' + '&format=json') collections.append(item_data) item_data = {} item_data['title'] = i18n('music_all_artists') item_data['media_type'] = 'MusicArtists' item_data['path'] = ('{server}/emby/Artists/AlbumArtists' + '?Recursive=true' + '&ImageTypeLimit=1' + '&EnableImageTypes=Primary,Backdrop,Banner,Thumb' + '&SortBy=Name' + '&SortOrder=Ascending' + '&format=json') collections.append(item_data) return collections