def mainEntryPoint(): log.info("===== ViewMaster START =====") log.info("Running Python: " + str(sys.version_info)) log.info("Kodi BuildVersion: " + xbmc.getInfoLabel("System.BuildVersion")) log.info("Kodi Version: " + str(kodi_version)) log.info("Script argument data: " + str(sys.argv)) try: params = get_params(sys.argv[2]) except: params = {} if (len(params) == 0): home_window = HomeWindow() windowParams = home_window.getProperty("Params") log.info("windowParams : " + windowParams) # home_window.clearProperty("Params") if (windowParams): try: params = get_params(windowParams) except: params = {} log.info("Script params = " + str(params)) home_window = HomeWindow() try: setView(sys.argv[1]) except: showSetViews() log.info("===== ViewMaster FINISHED =====")
def getDeviceId(self): WINDOW = HomeWindow() client_id = WINDOW.getProperty("client_id") if client_id: return client_id emby_guid_path = xbmc.translatePath("special://temp/embycon_guid").decode('utf-8') log.debug("emby_guid_path: {0}", emby_guid_path) guid = xbmcvfs.File(emby_guid_path) client_id = guid.read() guid.close() if not client_id: client_id = str("%012X" % uuid4()) log.debug("Generating a new guid: {0}", client_id) guid = xbmcvfs.File(emby_guid_path, 'w') guid.write(client_id) guid.close() log.debug("emby_client_id (NEW): {0}", client_id) else: log.debug("emby_client_id: {0}", client_id) WINDOW.setProperty("client_id", client_id) return client_id
def getDeviceId(self): WINDOW = HomeWindow() client_id = WINDOW.getProperty("client_id") if client_id: return client_id emby_guid_path = xbmc.translatePath( "special://temp/embycon_guid").decode('utf-8') log.debug("emby_guid_path: {0}", emby_guid_path) guid = xbmcvfs.File(emby_guid_path) client_id = guid.read() guid.close() if not client_id: client_id = str("%012X" % uuid4()) log.debug("Generating a new guid: {0}", client_id) guid = xbmcvfs.File(emby_guid_path, 'w') guid.write(client_id) guid.close() log.debug("emby_client_id (NEW): {0}", client_id) else: log.debug("emby_client_id: {0}", client_id) WINDOW.setProperty("client_id", client_id) return client_id
def checkForNewContent(): log.debug("checkForNewContent Called") added_url = ('{server}/emby/Users/{userid}/Items' + '?Recursive=true' + '&limit=1' + '&Fields=DateCreated,Etag' + '&SortBy=DateCreated' + '&SortOrder=Descending' + '&IncludeItemTypes=Movie,Episode' + '&ImageTypeLimit=0' + '&format=json') added_result = downloadUtils.downloadUrl(added_url, suppress=True) result = json.loads(added_result) log.debug("LATEST_ADDED_ITEM: {0}", result) last_added_date = "" if result is not None: items = result.get("Items", []) if len(items) > 0: item = items[0] last_added_date = item.get("Etag", "") log.debug("last_added_date: {0}", last_added_date) played_url = ('{server}/emby/Users/{userid}/Items' + '?Recursive=true' + '&limit=1' + '&Fields=DateCreated,Etag' + '&SortBy=DatePlayed' + '&SortOrder=Descending' + '&IncludeItemTypes=Movie,Episode' + '&ImageTypeLimit=0' + '&format=json') played_result = downloadUtils.downloadUrl(played_url, suppress=True) result = json.loads(played_result) log.debug("LATEST_PLAYED_ITEM: {0}", result) last_played_date = "" if result is not None: items = result.get("Items", []) if len(items) > 0: item = items[0] last_played_date = item.get("Etag", "") log.debug("last_played_date: {0}", last_played_date) home_window = HomeWindow() current_widget_hash = home_window.getProperty("embycon_widget_reload") log.debug("Current Widget Hash: {0}", current_widget_hash) m = hashlib.md5() m.update(last_played_date + last_added_date) new_widget_hash = m.hexdigest() log.debug("New Widget Hash: {0}", new_widget_hash) if current_widget_hash != new_widget_hash: home_window.setProperty("embycon_widget_reload", new_widget_hash) log.debug("Setting New Widget Hash: {0}", new_widget_hash)
def set_library_window_values(force=False): log.debug("set_library_window_values Called forced={0}", force) home_window = HomeWindow() already_set = home_window.getProperty("view_item.0.name") if not force and already_set: return for index in range(0, 20): home_window.clearProperty("view_item.%i.name" % index) home_window.clearProperty("view_item.%i.id" % index) home_window.clearProperty("view_item.%i.type" % index) home_window.clearProperty("view_item.%i.thumb" % index) data_manager = DataManager() url = "{server}/emby/Users/{userid}/Views" result = data_manager.GetContent(url) if result is None: return result = result.get("Items") server = downloadUtils.getServer() index = 0 for item in result: type = item.get("CollectionType") if type in ["movies", "boxsets", "music", "tvshows"]: name = item.get("Name") id = item.get("Id") # plugin.video.jellyfincon- prop_name = "view_item.%i.name" % index home_window.setProperty(prop_name, name) log.debug( "set_library_window_values: plugin.video.jellyfincon-{0}={1}", prop_name, name) prop_name = "view_item.%i.id" % index home_window.setProperty(prop_name, id) log.debug( "set_library_window_values: plugin.video.jellyfincon-{0}={1}", prop_name, id) prop_name = "view_item.%i.type" % index home_window.setProperty(prop_name, type) log.debug( "set_library_window_values: plugin.video.jellyfincon-{0}={1}", prop_name, type) thumb = downloadUtils.getArtwork(item, "Primary", server=server) prop_name = "view_item.%i.thumb" % index home_window.setProperty(prop_name, thumb) log.debug( "set_library_window_values: plugin.video.jellyfincon-{0}={1}", prop_name, thumb) index += 1
def checkForNewContent(): log.debug("checkForNewContent Called") added_url = ('{server}/emby/Users/{userid}/Items' + '?Recursive=true' + '&limit=1' + '&Fields=DateCreated,Etag' + '&SortBy=DateCreated' + '&SortOrder=Descending' + '&IncludeItemTypes=Movie,Episode' + '&ImageTypeLimit=0' + '&format=json') added_result = downloadUtils.downloadUrl(added_url, suppress=True) result = json.loads(added_result) log.debug("LATEST_ADDED_ITEM: {0}", result) last_added_date = "" if result is not None: items = result.get("Items", []) if len(items) > 0: item = items[0] last_added_date = item.get("Etag", "") log.debug("last_added_date: {0}", last_added_date) played_url = ('{server}/emby/Users/{userid}/Items' + '?Recursive=true' + '&limit=1' + '&Fields=DateCreated,Etag' + '&SortBy=DatePlayed' + '&SortOrder=Descending' + '&IncludeItemTypes=Movie,Episode' + '&ImageTypeLimit=0' + '&format=json') played_result = downloadUtils.downloadUrl(played_url, suppress=True) result = json.loads(played_result) log.debug("LATEST_PLAYED_ITEM: {0}", result) last_played_date = "" if result is not None: items = result.get("Items", []) if len(items) > 0: item = items[0] last_played_date = item.get("Etag", "") log.debug("last_played_date: {0}", last_played_date) home_window = HomeWindow() current_widget_hash = home_window.getProperty("embycon_widget_reload") log.debug("Current Widget Hash: {0}", current_widget_hash) m = hashlib.md5() m.update(last_played_date + last_added_date) new_widget_hash = m.hexdigest() log.debug("New Widget Hash: {0}", new_widget_hash) if current_widget_hash != new_widget_hash: home_window.setProperty("embycon_widget_reload", new_widget_hash) log.debug("Setting New Widget Hash: {0}", new_widget_hash)
def authenticate(self): WINDOW = HomeWindow() token = WINDOW.getProperty("AccessToken") if token is not None and token != "": log.debug("EmbyCon DownloadUtils -> Returning saved AccessToken: {0}", token) return token settings = xbmcaddon.Addon() port = settings.getSetting("port") host = settings.getSetting("ipaddress") if host is None or host == "" or port is None or port == "": return "" url = "{server}/emby/Users/AuthenticateByName?format=json" pwd_sha = hashlib.sha1(settings.getSetting('password')).hexdigest() user_name = urllib.quote(settings.getSetting('username')) pwd_text = urllib.quote(settings.getSetting('password')) messageData = "username="******"&password="******"&pw=" + pwd_text resp = self.downloadUrl(url, postBody=messageData, method="POST", suppress=True, authenticate=False) log.debug("AuthenticateByName: {0}", resp) accessToken = None userid = None try: result = json.loads(resp) accessToken = result.get("AccessToken") #userid = result["SessionInfo"].get("UserId") userid = result["User"].get("Id") except: pass if accessToken is not None: log.debug("User Authenticated: {0}", accessToken) log.debug("User Id: {0}", userid) WINDOW.setProperty("AccessToken", accessToken) WINDOW.setProperty("userid", userid) #WINDOW.setProperty("userimage", "") self.post_capabilities() return accessToken else: log.debug("User NOT Authenticated") WINDOW.setProperty("AccessToken", "") WINDOW.setProperty("userid", "") WINDOW.setProperty("userimage", "") return ""
def getUserId(self): WINDOW = HomeWindow() userid = WINDOW.getProperty("userid") userImage = WINDOW.getProperty("userimage") if userid and userImage: log.debug("EmbyCon DownloadUtils -> Returning saved UserID: {0}", userid) return userid settings = xbmcaddon.Addon() userName = settings.getSetting('username') if not userName: return "" log.debug("Looking for user name: {0}", userName) jsonData = None try: jsonData = self.downloadUrl("{server}/emby/Users/Public?format=json", suppress=True, authenticate=False) except Exception, msg: log.error("Get User unable to connect: {0}", msg) return ""
def getUserId(self): WINDOW = HomeWindow() userid = WINDOW.getProperty("userid") userImage = WINDOW.getProperty("userimage") if userid and userImage: log.debug("EmbyCon DownloadUtils -> Returning saved UserID: {0}", userid) return userid settings = xbmcaddon.Addon() userName = settings.getSetting('username') if not userName: return "" log.debug("Looking for user name: {0}", userName) jsonData = None try: jsonData = self.downloadUrl("{server}/emby/Users/Public?format=json", suppress=True, authenticate=False) except Exception, msg: log.error("Get User unable to connect: {0}", msg) return ""
def authenticate(self): WINDOW = HomeWindow() token = WINDOW.getProperty("AccessToken") if token is not None and token != "": log.debug("EmbyCon DownloadUtils -> Returning saved AccessToken: {0}", token) return token settings = xbmcaddon.Addon() port = settings.getSetting("port") host = settings.getSetting("ipaddress") if host is None or host == "" or port is None or port == "": return "" url = "{server}/emby/Users/AuthenticateByName?format=json" pwd_sha = hashlib.sha1(settings.getSetting('password')).hexdigest() user_name = urllib.quote(settings.getSetting('username')) pwd_text = urllib.quote(settings.getSetting('password')) messageData = "username="******"&password="******"&pw=" + pwd_text resp = self.downloadUrl(url, postBody=messageData, method="POST", suppress=True, authenticate=False) accessToken = None userid = None try: result = json.loads(resp) accessToken = result.get("AccessToken") userid = result["SessionInfo"].get("UserId") except: pass if accessToken is not None: log.debug("User Authenticated: {0}", accessToken) WINDOW.setProperty("AccessToken", accessToken) WINDOW.setProperty("userid", userid) WINDOW.setProperty("userimage", "") return accessToken else: log.debug("User NOT Authenticated") WINDOW.setProperty("AccessToken", "") WINDOW.setProperty("userid", "") WINDOW.setProperty("userimage", "") return ""
def set_library_window_values(): log.debug("set_library_window_values called") home_window = HomeWindow() already_set = home_window.getProperty("view_item.0.name") if already_set: return data_manager = DataManager() url = "{server}/emby/Users/{userid}/Views" result = data_manager.GetContent(url) if result is None: return result = result.get("Items") server = downloadUtils.getServer() index = 0 for item in result: type = item.get("CollectionType") if type in ["movies", "boxsets", "music", "tvshows"]: name = item.get("Name") id = item.get("Id") # plugin.video.embycon- prop_name = "view_item.%i.name" % index home_window.setProperty(prop_name, name) log.debug("set_library_window_values: plugin.video.embycon-{0}={1}", prop_name, name) prop_name = "view_item.%i.id" % index home_window.setProperty(prop_name, id) log.debug("set_library_window_values: plugin.video.embycon-{0}={1}", prop_name, id) prop_name = "view_item.%i.type" % index home_window.setProperty(prop_name, type) log.debug("set_library_window_values: plugin.video.embycon-{0}={1}", prop_name, type) thumb = downloadUtils.getArtwork(item, "Primary", server=server) prop_name = "view_item.%i.thumb" % index home_window.setProperty(prop_name, thumb) log.debug("set_library_window_values: plugin.video.embycon-{0}={1}", prop_name, thumb) index += 1
def populateWidgetItems(itemsUrl, override_select_action=None): server = downloadUtils.getServer() if server is None: return [] settings = xbmcaddon.Addon() select_action = settings.getSetting("widget_select_action") if override_select_action is not None: select_action = str(override_select_action) log.debug("WIDGET_DATE_URL: {0}", itemsUrl) home_window = HomeWindow() # get the items data_manager = DataManager() result = data_manager.GetContent(itemsUrl) if result is not None and isinstance( result, dict) and result.get("Items") is not None: simmilarTo = result.get("BaselineItemName", None) result = result.get("Items") elif result is not None and isinstance(result, list) and len(result) > 0: simmilarTo = result[0].get("BaselineItemName", None) result = result[0].get("Items") else: result = [] itemCount = 1 listItems = [] for item in result: item_id = item["Id"] name = item["Name"] episodeDetails = "" log.debug("WIDGET_DATE_NAME: {0}", name) title = name tvshowtitle = "" item_type = item["Type"] series_name = item["SeriesName"] if item_type == "Episode" and series_name is not None: episode_number = item["IndexNumber"] if episode_number is None: episode_number = 0 season_number = item["ParentIndexNumber"] if season_number is None: season_number = 0 name = series_name + " " + episodeDetails name = "%s S%02dE%02d" % (series_name, season_number, episode_number) tvshowtitle = "S%02dE%02d" % (season_number, episode_number) title = series_name art = getArt(item, server, widget=True) 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']) # list_item.setLabel2(episodeDetails) production_year = item["ProductionYear"] prem_year = item["PremiereDate"] if production_year is None and prem_year is not None: production_year = int(prem_year[:4]) # add progress percent userData = item["UserData"] if userData["Played"] == True: playCount = "1" overlay = "5" else: playCount = "0" overlay = "6" runtime = item["RunTimeTicks"] playBackTicks = userData["PlaybackPositionTicks"] if playBackTicks is not None and runtime is not None and runtime > 0: runtime = float(runtime) playBackTicks = float(playBackTicks) playBackPos = int(((playBackTicks / 1000) / 10000) / 60) list_item.setProperty('ResumeTime', str(playBackPos)) percentage = int((playBackTicks / runtime) * 100.0) list_item.setProperty("complete_percentage", str(percentage)) video_info_label = { "title": title, "tvshowtitle": tvshowtitle, "year": production_year, "Overlay": overlay, "playcount": playCount } list_item.setInfo(type="Video", infoLabels=video_info_label) list_item.setProperty('fanart_image', art['fanart']) # back compat list_item.setProperty('discart', art['discart']) # not avail to setArt list_item.setArt(art) # add count #list_item.setProperty("item_index", str(itemCount)) #itemCount = itemCount + 1 list_item.setProperty('IsPlayable', 'false') if runtime is not None: totalTime = str(int(float(runtime) / (10000000 * 60))) list_item.setProperty('TotalTime', str(totalTime)) list_item.setContentLookup(False) list_item.setProperty('id', item_id) if simmilarTo is not None: list_item.setProperty('suggested_from_watching', simmilarTo) session_id = "&session_id=" + home_window.getProperty("session_id") if select_action == "1": playurl = "plugin://plugin.video.embycon/?item_id=" + item_id + '&mode=PLAY' + session_id elif select_action == "0": playurl = "plugin://plugin.video.embycon/?item_id=" + item_id + '&mode=SHOW_MENU' + session_id itemTupple = (playurl, list_item, False) listItems.append(itemTupple) return listItems
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()
def mainEntryPoint(): log.debug("===== EmbyCon START =====") settings = xbmcaddon.Addon() profile_code = settings.getSetting('profile') == "true" pr = None if (profile_code): return_value = xbmcgui.Dialog().yesno("Profiling Enabled", "Do you want to run profiling?") if return_value: pr = cProfile.Profile() pr.enable() ADDON_VERSION = ClientInformation().getVersion() log.debug("Running Python: {0}", sys.version_info) log.debug("Running EmbyCon: {0}", ADDON_VERSION) log.debug("Kodi BuildVersion: {0}", xbmc.getInfoLabel("System.BuildVersion")) log.debug("Kodi Version: {0}", kodi_version) log.debug("Script argument data: {0}", sys.argv) try: params = get_params(sys.argv[2]) except: params = {} home_window = HomeWindow() if (len(params) == 0): windowParams = home_window.getProperty("Params") log.debug("windowParams: {0}", windowParams) # home_window.clearProperty("Params") if (windowParams): try: params = get_params(windowParams) except: params = {} log.debug("Script params: {0}", params) param_url = params.get('url', None) if param_url: param_url = urllib.unquote(param_url) mode = params.get("mode", None) if mode == "CHANGE_USER": checkServer(change_user=True, notify=False) elif mode== "CACHE_ARTWORK": CacheArtwork().cache_artwork_interactive() elif mode == "DETECT_SERVER": checkServer(force=True, notify=True) elif mode == "DETECT_SERVER_USER": checkServer(force=True, change_user=True, notify=False) elif sys.argv[1] == "markWatched": item_id = sys.argv[2] markWatched(item_id) elif sys.argv[1] == "markUnwatched": item_id = sys.argv[2] markUnwatched(item_id) elif sys.argv[1] == "markFavorite": item_id = sys.argv[2] markFavorite(item_id) elif sys.argv[1] == "unmarkFavorite": item_id = sys.argv[2] unmarkFavorite(item_id) #elif sys.argv[1] == "delete": # item_id = sys.argv[2] # delete(item_id) elif mode == "playTrailer": item_id = params["id"] playTrailer(item_id) elif mode == "MOVIE_ALPHA": showMovieAlphaList() elif mode == "GENRES": showGenreList(params) elif mode == "MOVIE_PAGES": showMoviePages(params) elif mode == "MOVIE_YEARS": showYearsList() elif mode == "WIDGETS": showWidgets() elif mode == "SHOW_MENU": showMenu(params) elif mode == "SHOW_SETTINGS": __addon__.openSettings() WINDOW = xbmcgui.getCurrentWindowId() if WINDOW == 10000: log.debug("Currently in home - refreshing to allow new settings to be taken") xbmc.executebuiltin("ActivateWindow(Home)") elif sys.argv[1] == "refresh": home_window.setProperty("force_data_reload", "true") xbmc.executebuiltin("Container.Refresh") elif mode == "WIDGET_CONTENT": getWidgetContent(int(sys.argv[1]), params) elif mode == "WIDGET_CONTENT_CAST": get_widget_content_cast(int(sys.argv[1]), params) elif mode == "WIDGET_CONTENT_SIMILAR": getWidgetContentSimilar(int(sys.argv[1]), params) elif mode == "WIDGET_CONTENT_NEXTUP": getWidgetContentNextUp(int(sys.argv[1]), params) elif mode == "WIDGET_CONTENT_SUGGESTIONS": getSuggestions(int(sys.argv[1]), params) elif mode == "WIDGET_CONTENT_URL": getWidgetUrlContent(int(sys.argv[1]), params) elif mode == "PARENT_CONTENT": checkServer(notify=False) showParentContent(params) elif mode == "SHOW_CONTENT": # plugin://plugin.video.embycon?mode=SHOW_CONTENT&item_type=Movie|Series checkServer(notify=False) showContent(sys.argv[0], int(sys.argv[1]), params) elif mode == "SEARCH": # plugin://plugin.video.embycon?mode=SEARCH checkServer(notify=False) xbmcplugin.setContent(int(sys.argv[1]), 'files') showSearch() elif mode == "NEW_SEARCH": checkServer(notify=False) searchResults(params) elif mode == "SHOW_SERVER_SESSIONS": checkServer(notify=False) showServerSessions() elif mode == "TRAKTTOKODI": checkServer(notify=False) trakttokodi.entry_point(params) else: checkServer(notify=False) log.debug("EmbyCon -> Mode: {0}", mode) log.debug("EmbyCon -> URL: {0}", param_url) if mode == "GET_CONTENT": getContent(param_url, params) elif mode == "PLAY": PLAY(params) else: displaySections() dataManager.canRefreshNow = True if (pr): pr.disable() fileTimeStamp = time.strftime("%Y%m%d-%H%M%S") tabFileName = __addondir__ + "profile(" + fileTimeStamp + ").txt" s = StringIO.StringIO() ps = pstats.Stats(pr, stream=s) ps = ps.sort_stats('cumulative') ps.print_stats() ps.strip_dirs() ps = ps.sort_stats('tottime') ps.print_stats() with open(tabFileName, 'wb') as f: f.write(s.getvalue()) log.debug("===== EmbyCon FINISHED =====")
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 mainEntryPoint(): log.debug("===== EmbyCon START =====") settings = xbmcaddon.Addon() profile_code = settings.getSetting('profile') == "true" pr = None if (profile_code): return_value = xbmcgui.Dialog().yesno("Profiling Enabled", "Do you want to run profiling?") if return_value: pr = cProfile.Profile() pr.enable() ADDON_VERSION = ClientInformation().getVersion() log.debug("Running Python: {0}", sys.version_info) log.debug("Running EmbyCon: {0}", ADDON_VERSION) log.debug("Kodi BuildVersion: {0}", xbmc.getInfoLabel("System.BuildVersion")) log.debug("Kodi Version: {0}", kodi_version) log.debug("Script argument data: {0}", sys.argv) try: params = get_params(sys.argv[2]) except: params = {} home_window = HomeWindow() if (len(params) == 0): windowParams = home_window.getProperty("Params") log.debug("windowParams: {0}", windowParams) # home_window.clearProperty("Params") if (windowParams): try: params = get_params(windowParams) except: params = {} log.debug("Script params: {0}", params) param_url = params.get('url', None) if param_url: param_url = urllib.unquote(param_url) mode = params.get("mode", None) if mode == "CHANGE_USER": checkServer(change_user=True, notify=False) elif mode== "CACHE_ARTWORK": cache_artwork() elif mode == "DETECT_SERVER": checkServer(force=True, notify=True) elif mode == "DETECT_SERVER_USER": checkServer(force=True, change_user=True, notify=False) elif sys.argv[1] == "markWatched": item_id = sys.argv[2] markWatched(item_id) elif sys.argv[1] == "markUnwatched": item_id = sys.argv[2] markUnwatched(item_id) elif sys.argv[1] == "markFavorite": item_id = sys.argv[2] markFavorite(item_id) elif sys.argv[1] == "unmarkFavorite": item_id = sys.argv[2] unmarkFavorite(item_id) #elif sys.argv[1] == "delete": # item_id = sys.argv[2] # delete(item_id) elif mode == "playTrailer": item_id = params["id"] playTrailer(item_id) elif mode == "MOVIE_ALPHA": showMovieAlphaList() elif mode == "GENRES": showGenreList(params) elif mode == "MOVIE_PAGES": showMoviePages(params) elif mode == "MOVIE_YEARS": showYearsList() elif mode == "WIDGETS": showWidgets() elif mode == "SHOW_MENU": showMenu(params) elif mode == "SHOW_SETTINGS": __addon__.openSettings() WINDOW = xbmcgui.getCurrentWindowId() if WINDOW == 10000: log.debug("Currently in home - refreshing to allow new settings to be taken") xbmc.executebuiltin("ActivateWindow(Home)") elif sys.argv[1] == "refresh": home_window.setProperty("force_data_reload", "true") xbmc.executebuiltin("Container.Refresh") elif mode == "WIDGET_CONTENT": getWidgetContent(int(sys.argv[1]), params) elif mode == "WIDGET_CONTENT_CAST": get_widget_content_cast(int(sys.argv[1]), params) elif mode == "WIDGET_CONTENT_SIMILAR": getWidgetContentSimilar(int(sys.argv[1]), params) elif mode == "WIDGET_CONTENT_NEXTUP": getWidgetContentNextUp(int(sys.argv[1]), params) elif mode == "WIDGET_CONTENT_SUGGESTIONS": getSuggestions(int(sys.argv[1]), params) elif mode == "WIDGET_CONTENT_URL": getWidgetUrlContent(int(sys.argv[1]), params) elif mode == "PARENT_CONTENT": checkServer(notify=False) showParentContent(params) elif mode == "SHOW_CONTENT": # plugin://plugin.video.embycon?mode=SHOW_CONTENT&item_type=Movie|Series checkServer(notify=False) showContent(sys.argv[0], int(sys.argv[1]), params) elif mode == "SEARCH": # plugin://plugin.video.embycon?mode=SEARCH checkServer(notify=False) xbmcplugin.setContent(int(sys.argv[1]), 'files') showSearch() elif mode == "NEW_SEARCH": checkServer(notify=False) searchResults(params) elif mode == "SHOW_SERVER_SESSIONS": checkServer(notify=False) showServerSessions() elif mode == "TRAKTTOKODI": checkServer(notify=False) trakttokodi.entry_point(params) else: checkServer(notify=False) log.debug("EmbyCon -> Mode: {0}", mode) log.debug("EmbyCon -> URL: {0}", param_url) if mode == "GET_CONTENT": getContent(param_url, params) elif mode == "PLAY": PLAY(params) else: displaySections() dataManager.canRefreshNow = True if (pr): pr.disable() fileTimeStamp = time.strftime("%Y%m%d-%H%M%S") tabFileName = __addondir__ + "profile(" + fileTimeStamp + ").txt" s = StringIO.StringIO() ps = pstats.Stats(pr, stream=s) ps = ps.sort_stats('cumulative') ps.print_stats() ps.strip_dirs() ps = ps.sort_stats('tottime') ps.print_stats() with open(tabFileName, 'wb') as f: f.write(s.getvalue()) log.debug("===== EmbyCon FINISHED =====")
def populateWidgetItems(itemsUrl, override_select_action=None): server = downloadUtils.getServer() if server is None: return [] settings = xbmcaddon.Addon() select_action = settings.getSetting("widget_select_action") if override_select_action is not None: select_action = str(override_select_action) log.debug("WIDGET_DATE_URL: {0}", itemsUrl) home_window = HomeWindow() # get the items data_manager = DataManager() result = data_manager.GetContent(itemsUrl) if result is not None and isinstance(result, dict) and result.get("Items") is not None: simmilarTo = result.get("BaselineItemName", None) result = result.get("Items") elif result is not None and isinstance(result, list) and len(result) > 0: simmilarTo = result[0].get("BaselineItemName", None) result = result[0].get("Items") else: result = [] itemCount = 1 listItems = [] for item in result: item_id = item["Id"] name = item["Name"] episodeDetails = "" log.debug("WIDGET_DATE_NAME: {0}", name) title = name tvshowtitle = "" item_type = item["Type"] series_name = item["SeriesName"] if item_type == "Episode" and series_name is not None: episode_number = item["IndexNumber"] if episode_number is None: episode_number = 0 season_number = item["ParentIndexNumber"] if season_number is None: season_number = 0 name = series_name + " " + episodeDetails name = "%s S%02dE%02d" % (series_name, season_number, episode_number) tvshowtitle = "S%02dE%02d" % (season_number, episode_number) title = series_name art = getArt(item, server) 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']) # list_item.setLabel2(episodeDetails) production_year = item["ProductionYear"] prem_year = item["PremiereDate"] if production_year is None and prem_year is not None: production_year = int(prem_year[:4]) # add progress percent userData = item["UserData"] if userData["Played"] == True: playCount = "1" overlay = "5" else: playCount = "0" overlay = "6" runtime = item["RunTimeTicks"] playBackTicks = userData["PlaybackPositionTicks"] if playBackTicks is not None and runtime is not None and runtime > 0: runtime = float(runtime) playBackTicks = float(playBackTicks) playBackPos = int(((playBackTicks / 1000) / 10000) / 60) list_item.setProperty('ResumeTime', str(playBackPos)) percentage = int((playBackTicks / runtime) * 100.0) list_item.setProperty("complete_percentage", str(percentage)) video_info_label = {"title": title, "tvshowtitle": tvshowtitle, "year": production_year, "Overlay": overlay, "playcount": playCount} list_item.setInfo(type="Video", infoLabels=video_info_label) list_item.setProperty('fanart_image', art['fanart']) # back compat list_item.setProperty('discart', art['discart']) # not avail to setArt list_item.setArt(art) # add count #list_item.setProperty("item_index", str(itemCount)) #itemCount = itemCount + 1 list_item.setProperty('IsPlayable', 'false') if runtime is not None: totalTime = str(int(float(runtime) / (10000000 * 60))) list_item.setProperty('TotalTime', str(totalTime)) list_item.setContentLookup(False) list_item.setProperty('id', item_id) if simmilarTo is not None: list_item.setProperty('suggested_from_watching', simmilarTo) session_id = "&session_id=" + home_window.getProperty("session_id") if select_action == "1": playurl = "plugin://plugin.video.embycon/?item_id=" + item_id + '&mode=PLAY' + session_id elif select_action == "0": playurl = "plugin://plugin.video.embycon/?item_id=" + item_id + '&mode=SHOW_MENU' + session_id itemTupple = (playurl, list_item, False) listItems.append(itemTupple) return listItems
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()
def downloadUrl(self, url, suppress=False, postBody=None, method="GET", authenticate=True, headers=None): log.debug("downloadUrl") return_data = "null" settings = xbmcaddon.Addon() username = settings.getSetting("username") 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("{field_filters}") != -1: filter_string = getDetailsString() url = url.replace("{field_filters}", filter_string) if url.find("{random_movies}") != -1: home_window = HomeWindow() random_movies = home_window.getProperty("random-movies") if not random_movies: return return_data url = url.replace("{random_movies}", random_movies) 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 return_data if authenticate and username == "": return return_data 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 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, "") settings.setSetting("username", "") settings.setSetting("password", "") log.error("HTTP response error: {0} {1}", data.status, data.reason) if suppress is False: xbmcgui.Dialog().notification(string_load(30316), string_load(30200) % str(data.reason), icon="special://home/addons/plugin.video.jellyfincon/icon.png") except Exception, msg: log.error("Unable to connect to {0} : {1}", server, msg) if suppress is False: xbmcgui.Dialog().notification(string_load(30316), str(msg), icon="special://home/addons/plugin.video.jellyfincon/icon.png")