def send_next_episode_details(item): next_episode = get_next_episode(item) if next_episode is None: log.debug("No next episode") return gui_options = {} gui_options["server"] = download_utils.getServer() gui_options["name_format"] = None gui_options["name_format_type"] = "" item_details = extract_item_info(item, gui_options) next_item_details = extract_item_info(next_episode, gui_options) current_item = {} current_item["id"] = item_details.id current_item["title"] = item_details.name current_item["image"] = item_details.art.get('tvshow.poster', '') current_item["thumb"] = item_details.art.get('thumb', '') current_item["fanartimage"] = item_details.art.get('tvshow.fanart', '') current_item["overview"] = item_details.plot current_item["tvshowtitle"] = item_details.series_name current_item["playcount"] = item_details.play_count current_item["season"] = item_details.season_number current_item["episode"] = item_details.episode_number current_item["rating"] = item_details.critic_rating current_item["year"] = item_details.year next_item = {} next_item["id"] = next_item_details.id next_item["title"] = next_item_details.name next_item["image"] = next_item_details.art.get('tvshow.poster', '') next_item["thumb"] = next_item_details.art.get('thumb', '') next_item["fanartimage"] = next_item_details.art.get('tvshow.fanart', '') next_item["overview"] = next_item_details.plot next_item["tvshowtitle"] = next_item_details.series_name next_item["playcount"] = next_item_details.play_count next_item["season"] = next_item_details.season_number next_item["episode"] = next_item_details.episode_number next_item["rating"] = next_item_details.critic_rating next_item["year"] = next_item_details.year next_info = { "current_item": current_item, "next_item": next_item } log.debug("send_next_episode_details: {0}", next_info) send_event_notification("embycon_next_episode", next_info)
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
class DataManager(): addon_dir = xbmc.translatePath(xbmcaddon.Addon().getAddonInfo('profile')) def __init__(self, *args): # log.debug("DataManager __init__") pass def loadJasonData(self, jsonData): return json.loads(jsonData, object_hook=lambda d: defaultdict(lambda: None, d)) def GetContent(self, url): jsonData = DownloadUtils().downloadUrl(url) result = self.loadJasonData(jsonData) return result def get_items(self, url, gui_options, use_cache=False): home_window = HomeWindow() log.debug("last_content_url : {0}", url) home_window.setProperty("last_content_url", url) user_id = DownloadUtils().getUserId() m = hashlib.md5() m.update(user_id + "|" + url) url_hash = m.hexdigest() cache_file = os.path.join(self.addon_dir, "cache_" + url_hash + ".pickle") #changed_url = url + "&MinDateLastSavedForUser="******"2019-09-16T13:45:30") #results = self.GetContent(changed_url) #log.debug("DataManager Changes Since Date : {0}", results) item_list = None baseline_name = None cache_thread = CacheManagerThread() cache_thread.gui_options = gui_options home_window.setProperty(cache_file, "true") clear_cache = home_window.getProperty("skip_cache_for_" + url) if clear_cache and os.path.isfile(cache_file): log.debug("Clearing cache data and loading new data") home_window.clearProperty("skip_cache_for_" + url) os.remove(cache_file) # try to load the list item data form the cache if os.path.isfile(cache_file) and use_cache: log.debug("Loading url data from cached pickle data") with open(cache_file, 'rb') as handle: try: cache_item = cPickle.load(handle) cache_thread.cached_item = cache_item item_list = cache_item.item_list except Exception, err: log.debug("Pickle Data Load Failed : {0}", err) item_list = None # we need to load the list item data form the server if item_list is None: log.debug("Loading url data from server") results = self.GetContent(url) if results is None: results = [] 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") item_list = [] for item in results: item_data = extract_item_info(item, gui_options) item_data.baseline_itemname = baseline_name item_list.append(item_data) cache_item = CacheItem() cache_item.item_list = item_list cache_item.file_path = cache_file cache_item.items_url = url cache_item.last_action = "fresh_data" cache_item.date_saved = time.time() cache_thread.cached_item = cache_item # copy.deepcopy(item_list) if use_cache: cache_thread.start() return cache_file, item_list
def run(self): log.debug("CacheManagerThread : Started") home_window = HomeWindow() is_fresh = False # if the data is fresh then just save it # if the data is to old do a reload if (self.cached_item.date_saved is not None and (time.time() - self.cached_item.date_saved) < 20 and self.cached_item.last_action == "fresh_data"): is_fresh = True if is_fresh: log.debug("CacheManagerThread : Saving fresh data") cached_hash = self.get_data_hash(self.cached_item.item_list) self.cached_item.item_list_hash = cached_hash self.cached_item.last_action = "cached_data" self.cached_item.date_saved = time.time() loops = self.wait_for_save(home_window, self.cached_item.file_path) log.debug("CacheManagerThread : Saving New Data loops({0})", loops) with open(self.cached_item.file_path, 'wb') as handle: cPickle.dump(self.cached_item, handle, protocol=cPickle.HIGHEST_PROTOCOL) home_window.clearProperty(self.cached_item.file_path) else: log.debug("CacheManagerThread : Reloading to recheck data hashes") cached_hash = self.cached_item.item_list_hash log.debug("CacheManagerThread : Cache Hash : {0}", cached_hash) data_manager = DataManager() results = data_manager.GetContent(self.cached_item.items_url) if results is None: results = [] if isinstance(results, dict) and results.get("Items") is not None: results = results.get("Items", []) elif isinstance(results, list) and len(results) > 0 and results[0].get("Items") is not None: results = results[0].get("Items") loaded_items = [] for item in results: item_data = extract_item_info(item, self.gui_options) loaded_items.append(item_data) loaded_hash = self.get_data_hash(loaded_items) log.debug("CacheManagerThread : Loaded Hash : {0}", loaded_hash) # if they dont match then save the data and trigger a content reload if cached_hash != loaded_hash: log.debug("CacheManagerThread : Hashes different, saving new data and reloading container") self.cached_item.item_list = loaded_items self.cached_item.item_list_hash = loaded_hash self.cached_item.last_action = "fresh_data" self.cached_item.date_saved = time.time() # we need to refresh but will wait until the main function has finished loops = self.wait_for_save(home_window, self.cached_item.file_path) with open(self.cached_item.file_path, 'wb') as handle: cPickle.dump(self.cached_item, handle, protocol=cPickle.HIGHEST_PROTOCOL) home_window.clearProperty(self.cached_item.file_path) log.debug("CacheManagerThread : Sending container refresh ({0})", loops) xbmc.executebuiltin("Container.Refresh") log.debug("CacheManagerThread : Exited")