def do_refresh_series(series_id_str, config, debug): try: thetvdb = TheTvDb(config, debug) database = Database(config, debug) try: series_id = int(series_id_str) except: print "Argument is not a valid series id: %s" % (series_id_str, ) return 1 series = database.get_series(series_id) if series is not None: new_series = thetvdb.get_series_info(series.id) new_series.watch = series.watch database.clear_series(series.id) database.clear_all_episodes(series.id) database.add_series(new_series) episodes = get_episodes(thetvdb, database, new_series) else: new_series = thetvdb.get_series_info(series_id) series = new_series database.add_series(new_series) episodes = get_episodes(thetvdb, database, new_series) print "Metadata for series '%s' and its episodes has been cleared from the local cache and reloaded from TheTvDb.com." % (series.title, ) return 0 except: traceback.print_exc() return 11
def watch_series_guts(series_id_str, watch, config, debug): try: thetvdb = TheTvDb(config, debug) database = Database(config, debug) try: series_id = int(series_id_str) except: print "Argument is not a valid series id: %s" % (series_id_str, ) return 2 series = database.get_series(series_id) if series is None: series = thetvdb.get_series_info(series_id) if series is not None: database.add_series(series) if not series is None: database.watch_series(series, watch) return 0 else: print "No series with id '%i' exists in the local cache. Did you lookup the series?" % (series_id,) return 3 except: traceback.print_exc() return 11
def do_series_lookup(name, config, debug): try: thetvdb = TheTvDb(config, debug) database = Database(config, debug) results = thetvdb.lookup_series_info(name) for r in results: database.add_series(r) print "%i: %s" % (r.id, r.title) return 0 except: traceback.print_exc() return 11
def __init__(self): """Initialization and main code run""" self.win = xbmcgui.Window(10000) self.addon = xbmcaddon.Addon(ADDON_ID) self.thetvdb = TheTvDb() self.__set_dates() action, action_param = self.get_params() self.improve_dates = self.addon.getSetting("ImproveDates") == 'true' log_msg("MainModule called with action: %s - parameter: %s" % (action, action_param)) # launch module for action provided by this script try: getattr(self, action)(action_param) except Exception as exc: log_exception(__name__, exc) finally: self.close()
def __init__(self): '''Initialize and load all our helpers''' self._studiologos_path = "" self.cache = SimpleCache() self.addon = xbmcaddon.Addon(ADDON_ID) self.kodidb = KodiDb() self.omdb = Omdb(self.cache) self.tmdb = Tmdb(self.cache) self.channellogos = ChannelLogos(self.kodidb) self.fanarttv = FanartTv(self.cache) self.imdb = Imdb(self.cache) self.google = GoogleImages(self.cache) self.studiologos = StudioLogos(self.cache) self.animatedart = AnimatedArt(self.cache, self.kodidb) self.thetvdb = TheTvDb() self.musicart = MusicArtwork(self) self.pvrart = PvrArtwork(self) log_msg("Initialized")
def do_episode_lookup(episode_search_pattern, config, debug): try: thetvdb = TheTvDb(config, debug) database = Database(config, debug) split_pattern = episode_search_pattern.split(':') if len(split_pattern) < 1 or len(split_pattern) > 3: print "Search pattern must be of the form series_id[:season_number[:episode_number]]" return 1 series_id = split_pattern[0] series = database.get_series(series_id) if series is None: print "No series with id '%i' exists in the local cache. Did you lookup the series?" % (series_id,) return 2 existing_episode_list = database.get_all_episodes(series_id) if len(existing_episode_list) == 0: all_episodes = thetvdb.get_full_episode_list(series) for e in all_episodes: database.add_episode(e, series) if len(split_pattern) == 1: print_episodes(database.get_all_episodes(series_id)) elif len(split_pattern) == 2: season = int(split_pattern[1]) print_episodes(database.get_episodes(series_id, season)) elif len(split_pattern) == 3: season = int(split_pattern[1]) episode = int(split_pattern[2]) result = get_specific_episode(thetvdb, database, series, season, episode) if result is None: print "Could not locate an episode matching pattern: %s" % (episode_search_pattern, ) return 3 print_episodes([result]) return 0 except: traceback.print_exc() return 11
def __init__(self): '''Initialization and main code run''' self.win = xbmcgui.Window(10000) self.addon = xbmcaddon.Addon(ADDON_ID) self.thetvdb = TheTvDb() self.set_dates() action, action_param = self.get_params() self.improve_dates = self.addon.getSetting("ImproveDates") == 'true' log_msg("MainModule called with action: %s - parameter: %s" % (action, action_param)) # launch module for action provided by this script try: getattr(self, action)(action_param) except Exception as exc: log_exception(__name__, exc) finally: self.close()
class MainModule: '''mainmodule provides the script methods for the nextaired addon''' def __init__(self): '''Initialization and main code run''' self.win = xbmcgui.Window(10000) self.addon = xbmcaddon.Addon(ADDON_ID) self.thetvdb = TheTvDb() self.set_dates() action, action_param = self.get_params() self.improve_dates = self.addon.getSetting("ImproveDates") == 'true' log_msg("MainModule called with action: %s - parameter: %s" % (action, action_param)) # launch module for action provided by this script try: getattr(self, action)(action_param) except Exception as exc: log_exception(__name__, exc) finally: self.close() def close(self): '''Cleanup Kodi Cpython instances on exit''' del self.win del self.addon del self.thetvdb log_msg("MainModule exited") @staticmethod def get_params(): '''extract the action and it's parameter from the called script path''' action = "main" action_param = "" if len(sys.argv) > 1: arg = sys.argv[1] action = arg.split('=')[0].lower() action_param = arg.replace(action + "=", "").lower() return action, action_param def set_dates(self): '''set the date variables''' self.now = time() self.date = date.today() self.datestr = str(self.date) self.yesterday = self.date - timedelta(days=1) self.yesterstr = str(self.yesterday) self.tomorrow = self.date + timedelta(days=1) self.weekdays = [] for j in range(11, 18): self.weekdays.append(xbmc.getLocalizedString(j)) self.wdays = [] for j in range(41, 48): self.wdays.append(xbmc.getLocalizedString(j)) self.local_months = [] for j in range(51, 63): self.local_months.append(xbmc.getLocalizedString(j)) self.ampm = xbmc.getCondVisibility('String.Contains(System.Time,Am) | String.Contains(System.Time,Pm)') == 1 def reset(self, action_param): '''reset and force update of all data''' if action_param == "true": dialog = xbmcgui.Dialog() heading = self.addon.getAddonInfo("name").decode("utf-8") if dialog.yesno(heading, self.addon.getLocalizedString(32213)): dialog = xbmcgui.DialogProgress() dialog.create(heading, self.addon.getLocalizedString(32214)) self.update_data(True) dialog.close() del dialog def update_data(self, ignore_cache=False): '''updates all data we need in cache''' if self.win.getProperty("nextaired.update_data"): log_msg("Update data skipped, another update is in progress") else: self.win.setProperty("nextaired.update_data", "busy") # build details in cache for all continuing series in the kodi db log_msg("Updating TheTVDB info for all continuing Kodi tv shows...", xbmc.LOGNOTICE) self.thetvdb.ignore_cache = ignore_cache continuing_kodi_shows = self.thetvdb.get_kodishows_details(continuing_only=True) self.win.setProperty("NextAired.Total", "%s" % len(continuing_kodi_shows)) # build nextaired episodes listing in cache log_msg("Retrieving next airing episodes for all continuing Kodi tv shows...", xbmc.LOGNOTICE) want_yesterday = self.addon.getSetting("WantYesterday") == 'true' self.thetvdb.get_kodi_unaired_episodes(include_last_episode=want_yesterday) # set the window properties for the shows that are airing today prev_total = self.win.getProperty("NextAired.TodayTotal") prev_total = int(prev_total) if prev_total else 0 # clear previous properties for count in range(prev_total + 1): self.clear_properties("%s." % count) shows_airing_today = self.thetvdb.get_kodishows_airingtoday() all_titles = [] for count, show_details in enumerate(shows_airing_today): self.set_properties(show_details, "%s." % count) all_titles.append(show_details["title"]) self.win.setProperty("NextAired.TodayTotal", "%s" % len(shows_airing_today)) self.win.setProperty("NextAired.TodayShow", "[CR]".join(all_titles)) self.thetvdb.ignore_cache = False self.win.clearProperty("nextaired.update_data") log_msg("Update complete", xbmc.LOGNOTICE) def force(self, action_param): '''force update of data by script - calls update_data after user confirmation''' if action_param == "true": dialog = xbmcgui.DialogProgress() dialog.create(self.addon.getAddonInfo("name").decode("utf-8"), self.addon.getLocalizedString(32215)) self.update_data() dialog.close() del dialog def update(self, action_param): '''perform update of data in cache - called by the background service''' if action_param == "true": self.update_data() def updateshow(self, showtitle): '''force update of single show''' if showtitle: log_msg("Update show data requested for TV Show: %s" % showtitle) self.win.setProperty("nextaired.update_data", "busy") self.thetvdb.ignore_cache = True self.thetvdb.get_kodishow_details(showtitle) self.thetvdb.ignore_cache = False self.win.clearProperty("nextaired.update_data") def tvshowtitle(self, showtitle, prefix=""): '''set details for single show by name''' log_msg("Set NextAired properties for TV Show: %s" % showtitle) details = self.thetvdb.get_kodishow_details(showtitle) if not details or not showtitle: self.clear_properties(prefix) else: self.set_properties(details, prefix) def backend(self, action_param): '''start monitoring listitem details to set window properties''' if not action_param or action_param == "false" or self.win.getProperty("NextAired.backend"): log_msg("Start backend aborted, required param missing or backend already running") return log_msg("Monitoring of listitems started...") self.win.setProperty("NextAired.backend", "running") try: # try parsing the multi-attributes li_range_left, li_range_right = self.get_listitem_range(action_param) monitor = xbmc.Monitor() last_showtitle = "" while not monitor.abortRequested() and xbmc.getCondVisibility("Window.IsActive(10025)"): showtitle = xbmc.getInfoLabel("ListItem.TvShowTitle").decode("utf-8") if showtitle != last_showtitle: last_showtitle = showtitle self.tvshowtitle(showtitle) if li_range_left or li_range_right: # set properties for the given listitem range for count in range(li_range_left, li_range_right): showtitle = xbmc.getInfoLabel("ListItem(%s).TvShowTitle" % count).decode("utf-8") self.tvshowtitle(showtitle, "(%s)" % count) monitor.waitForAbort(0.5) # clear properties when exiting video library if not monitor.abortRequested(): self.clear_properties() if li_range_left or li_range_right: for count in range(li_range_left, li_range_right): self.clear_properties("(%s)" % count) del monitor except Exception as exc: log_exception(__name__, exc) finally: self.win.clearProperty("NextAired.backend") log_msg("Monitoring of listitems ended...") @staticmethod def get_listitem_range(paramstr): '''get the special range params from the parameter string''' li_range_left = 0 li_range_right = 0 if paramstr != "true": try: li_range_right = int(paramstr.split(" ")[1]) li_range_left = int(paramstr.split(" ")[0]) li_range_right += 1 except Exception: pass return li_range_left, li_range_right def set_properties(self, details, prefix=""): '''set the window properties for the given show''' self.win.setProperty("NextAired%s.Label" % prefix, details["title"]) self.win.setProperty("NextAired%s.Thumb" % prefix, details["art"].get("thumb")) self.win.setProperty("NextAired%s.AirTime" % prefix, details["airdaytime"]) self.win.setProperty("NextAired%s.Path" % prefix, details["file"]) self.win.setProperty("NextAired%s.Library" % prefix, "videodb://tvshows/titles/%s/" % details["tvshowid"]) self.win.setProperty("NextAired%s.Status" % prefix, details["status"]) self.win.setProperty("NextAired%s.Network" % prefix, " / ".join(details["studio"])) self.win.setProperty("NextAired%s.Started" % prefix, details["firstaired"]) self.win.setProperty("NextAired%s.Classification" % prefix, details["classification"]) self.win.setProperty("NextAired%s.Genre" % prefix, " / ".join(details["genre"])) self.win.setProperty("NextAired%s.Premiered" % prefix, str(details["year"])) self.win.setProperty("NextAired%s.Runtime" % prefix, str(details["runtime"])) self.win.setProperty("NextAired%s.FanArt" % prefix, details["art"]["fanart"]) if details.get("next_episode"): # set next airing episode details if exist self.win.setProperty("NextAired%s.NextDate" % prefix, details["next_episode"]["airdate"]) self.win.setProperty("NextAired%s.NextDay" % prefix, details["next_episode"]["airdate.long"]) self.win.setProperty("NextAired%s.NextTitle" % prefix, details["next_episode"]["title"]) nextnumber = "%sx%s" % (details["next_episode"]["season"], details["next_episode"]["episode"]) self.win.setProperty("NextAired%s.NextNumber" % prefix, nextnumber) self.win.setProperty("NextAired%s.NextEpisodeNumber" % prefix, str(details["next_episode"]["episode"])) self.win.setProperty("NextAired%s.NextSeasonNumber" % prefix, str(details["next_episode"]["season"])) else: # clear next episode properties if we don't have that data for prop in ["NextDate", "NextDay", "NextTitle", "NextNumber", "NextEpisodeNumber", "NextSeasonNumber"]: self.win.clearProperty("NextAired%s.%s" % (prefix, prop)) if details.get("last_episode"): self.win.setProperty("NextAired%s.LatestDate" % prefix, details["last_episode"]["airdate"]) self.win.setProperty("NextAired%s.LatestDay" % prefix, details["last_episode"]["airdate.long"]) self.win.setProperty("NextAired%s.LatestTitle" % prefix, details["last_episode"]["title"]) nextnumber = "%sx%s" % (details["last_episode"]["season"], details["last_episode"]["episode"]) self.win.setProperty("NextAired%s.LatestNumber" % prefix, nextnumber) self.win.setProperty("NextAired%s.LatestEpisodeNumber" % prefix, str(details["last_episode"]["episode"])) self.win.setProperty("NextAired%s.LatestSeasonNumber" % prefix, str(details["last_episode"]["season"])) else: # clear last episode properties if we don't have that data for prop in ["LatestDate", "LatestDay", "LatestTitle", "LatestNumber", "LatestEpisodeNumber", "LatestSeasonNumber"]: self.win.clearProperty("NextAired%s.%s" % (prefix, prop)) self.win.setProperty("NextAired%s.Airday" % prefix, details["airday"]) self.win.setProperty("NextAired%s.ShortTime" % prefix, details["airtime"]) self.win.setProperty("NextAired%s.Art(poster)" % prefix, details["art"].get("poster")) self.win.setProperty("NextAired%s.Art(banner)" % prefix, details["art"].get("banner")) self.win.setProperty("NextAired%s.Art(fanart)" % prefix, details["art"].get("fanart")) self.win.setProperty("NextAired%s.Art(landscape)" % prefix, details["art"].get("landscape")) self.win.setProperty("NextAired%s.Art(clearlogo)" % prefix, details["art"].get("clearlogo")) self.win.setProperty("NextAired%s.Art(characterart)" % prefix, details["art"].get("characterart")) def clear_properties(self, prefix=""): '''clears the nextaired window Properties''' props = ["label", "thumb", "airtime", "path", "library", "status", "statusid", "network", "started", "classification", "genre", "premiered", "country", "runtime", "fanart", "airstoday", "nextdate", "nextday", "nexttitle", "nextnumber", "nextepisodenumber", "nextseasonnumber", "latestdate", "latestday", "latesttitle", "latestnumber", "latestepisodenumber", "latestseasonnumber", "airday", "shorttime", "art(poster)", "art(banner)", "art(fanart)", "art(landscape)"] for prop in props: self.win.clearProperty("NextAired%s.%s" % (prefix, prop)) def main(self, action_param=None): '''show the NextAired dialog''' weekday = self.date.weekday() self.win.setProperty("NextAired.TodayText", xbmc.getLocalizedString(33006)) self.win.setProperty("NextAired.TomorrowText", xbmc.getLocalizedString(33007)) self.win.setProperty("NextAired.YesterdayText", self.addon.getLocalizedString(32018)) self.win.setProperty("NextAired.TodayDate", self.str_date(self.date, 'DropYear')) self.win.setProperty("NextAired.TomorrowDate", self.str_date(self.tomorrow, 'DropThisYear')) self.win.setProperty("NextAired.YesterdayDate", self.str_date(self.yesterday, 'DropThisYear')) for count in range(0, 7): wdate = self.date if count != weekday: wdate += timedelta(days=(count - weekday + 7) % 7) self.win.setProperty("NextAired.%d.Date" % (count + 1), self.str_date(wdate, 'DropThisYear')) from next_aired_dialog import NextAiredDialog today_style = self.addon.getSetting("TodayStyle") == 'true' scan_days = int(self.addon.getSetting("ScanDays2" if today_style else "ScanDays")) want_yesterday = self.addon.getSetting("WantYesterday") == 'true' eps_list = self.get_nextaired_listing(include_last_episode=want_yesterday) xml = "script-NextAired-TVGuide%s.xml" % (2 if today_style else "") xml_path = self.addon.getAddonInfo('path').decode('utf-8') dialog = NextAiredDialog( xml, xml_path, "Default", listing=eps_list, nice_date=self.nice_date, scan_days=scan_days, today_style=today_style, want_yesterday=want_yesterday) dialog.doModal() del dialog def get_nextaired_listing(self, include_last_episode=False): '''get the listing of all continuing series, include last episode and unaired episodes''' eps_list = self.thetvdb.get_kodi_unaired_episodes( single_episode_per_show=False, include_last_episode=include_last_episode) return eps_list def str_date(self, d, style=None): '''The style setting only affects "nice" dates, not the historic format.''' if d is None: return '' return self.nice_date(d, style) if self.improve_dates else d.strftime(DATE_FORMAT) def nice_date(self, d, style=None): '''Specify style DropThisYear, DropYear, or Short (or omit for the full info).''' tt = d.timetuple() if style == 'Short': fmt = NICE_SHORT_DATE elif style == 'DropYear' or (style == 'DropThisYear' and tt[0] == self.date.year): fmt = NICE_DATE_NO_YEAR else: fmt = NICE_DATE_FORMAT d = fmt % { 'year': tt[0], 'mm': tt[1], 'month': self.local_months[ tt[1] - 1], 'day': tt[2], 'wday': self.wdays[ tt[6]], 'unk': '??'} return d
class MainModule: """mainmodule provides the script methods for the nextaired addon""" def __init__(self): """Initialization and main code run""" self.win = xbmcgui.Window(10000) self.addon = xbmcaddon.Addon(ADDON_ID) self.thetvdb = TheTvDb() self.__set_dates() action, action_param = self.get_params() self.improve_dates = self.addon.getSetting("ImproveDates") == 'true' log_msg("MainModule called with action: %s - parameter: %s" % (action, action_param)) # launch module for action provided by this script try: getattr(self, action)(action_param) except Exception as exc: log_exception(__name__, exc) finally: self.close() def close(self): """Cleanup Kodi Cpython instances on exit""" del self.win del self.addon del self.thetvdb log_msg("MainModule exited") @staticmethod def get_params(): """extract the action and it's parameter from the called script path""" action = "main" action_param = "" if len(sys.argv) > 1: arg = sys.argv[1] action = arg.split('=')[0].lower() action_param = arg.replace(action + "=", "").lower() return action, action_param def __set_dates(self): """set the date variables""" self.now = time() self.date = date.today() self.datestr = str(self.date) self.yesterday = self.date - timedelta(days=1) self.yesterstr = str(self.yesterday) self.tomorrow = self.date + timedelta(days=1) self.weekdays = [] for j in range(11, 18): self.weekdays.append(xbmc.getLocalizedString(j)) self.wdays = [] for j in range(41, 48): self.wdays.append(xbmc.getLocalizedString(j)) self.local_months = [] for j in range(51, 63): self.local_months.append(xbmc.getLocalizedString(j)) self.ampm = xbmc.getCondVisibility('String.Contains(System.Time,Am) | String.Contains(System.Time,Pm)') == 1 def reset(self, action_param): """reset and force update of all data""" if action_param == "true": dialog = xbmcgui.Dialog() heading = self.addon.getAddonInfo("name").decode("utf-8") if dialog.yesno(heading, self.addon.getLocalizedString(32213)): dialog = xbmcgui.DialogProgress() dialog.create(heading, self.addon.getLocalizedString(32214)) self.update_data(True) dialog.close() del dialog def update_data(self, ignore_cache=False): """updates all data we need in cache""" if self.win.getProperty("nextaired.update_data"): log_msg("Update data skipped, another update is in progress") else: self.win.setProperty("nextaired.update_data", "busy") # build details in cache for all continuing series in the kodi db log_msg("Updating TheTVDB info for all continuing Kodi tv shows...", xbmc.LOGNOTICE) self.thetvdb.ignore_cache = ignore_cache continuing_kodi_shows = self.thetvdb.get_kodishows_details(continuing_only=True) self.win.setProperty("NextAired.Total", "%s" % len(continuing_kodi_shows)) # build nextaired episodes listing in cache log_msg("Retrieving next airing episodes for all continuing Kodi tv shows...", xbmc.LOGNOTICE) want_yesterday = self.addon.getSetting("WantYesterday") == 'true' self.thetvdb.get_kodi_unaired_episodes(include_last_episode=want_yesterday) # set the window properties for the shows that are airing today prev_total = self.win.getProperty("NextAired.TodayTotal") prev_total = int(prev_total) if prev_total else 0 # clear previous properties for count in range(prev_total + 1): self.clear_properties("%s." % count) shows_airing_today = self.thetvdb.get_kodishows_airingtoday() all_titles = [] for count, show_details in enumerate(shows_airing_today): self.set_properties(show_details, "%s." % count) all_titles.append(show_details["title"]) self.win.setProperty("NextAired.TodayTotal", "%s" % len(shows_airing_today)) self.win.setProperty("NextAired.TodayShow", "[CR]".join(all_titles)) self.thetvdb.ignore_cache = False self.win.clearProperty("nextaired.update_data") log_msg("Update complete", xbmc.LOGNOTICE) def force(self, action_param): """force update of data by script - calls update_data after user confirmation""" if action_param == "true": dialog = xbmcgui.DialogProgress() dialog.create(self.addon.getAddonInfo("name").decode("utf-8"), self.addon.getLocalizedString(32215)) self.update_data() dialog.close() del dialog def update(self, action_param): """perform update of data in cache - called by the background service""" if action_param == "true": self.update_data() def updateshow(self, showtitle): """force update of single show""" if showtitle: log_msg("Update show data requested for TV Show: %s" % showtitle) self.win.setProperty("nextaired.update_data", "busy") self.thetvdb.ignore_cache = True self.thetvdb.get_kodishow_details(showtitle) self.thetvdb.ignore_cache = False self.win.clearProperty("nextaired.update_data") def tvshowtitle(self, showtitle, prefix=""): """set details for single show by name""" log_msg("Set NextAired properties for TV Show: %s" % showtitle) details = self.thetvdb.get_kodishow_details(showtitle) if not details or not showtitle: self.clear_properties(prefix) else: self.set_properties(details, prefix) def backend(self, action_param): """start monitoring listitem details to set window properties""" if not action_param or action_param == "false" or self.win.getProperty("NextAired.backend"): log_msg("Start backend aborted, required param missing or backend already running") return log_msg("Monitoring of listitems started...") self.win.setProperty("NextAired.backend", "running") try: # try parsing the multi-attributes li_range_left, li_range_right = self.get_listitem_range(action_param) monitor = xbmc.Monitor() last_showtitle = "" while not monitor.abortRequested() and xbmc.getCondVisibility("Window.IsActive(10025)"): showtitle = xbmc.getInfoLabel("ListItem.TvShowTitle").decode("utf-8") if showtitle != last_showtitle: last_showtitle = showtitle self.tvshowtitle(showtitle) if li_range_left or li_range_right: # set properties for the given listitem range for count in range(li_range_left, li_range_right): showtitle = xbmc.getInfoLabel("ListItem(%s).TvShowTitle" % count).decode("utf-8") self.tvshowtitle(showtitle, "(%s)" % count) monitor.waitForAbort(0.5) # clear properties when exiting video library if not monitor.abortRequested(): self.clear_properties() if li_range_left or li_range_right: for count in range(li_range_left, li_range_right): self.clear_properties("(%s)" % count) del monitor except Exception as exc: log_exception(__name__, exc) finally: self.win.clearProperty("NextAired.backend") log_msg("Monitoring of listitems ended...") @staticmethod def get_listitem_range(paramstr): """get the special range params from the parameter string""" li_range_left = 0 li_range_right = 0 if paramstr != "true": try: li_range_right = int(paramstr.split(" ")[1]) li_range_left = int(paramstr.split(" ")[0]) li_range_right += 1 except Exception: pass return li_range_left, li_range_right def set_properties(self, details, prefix=""): """set the window properties for the given show""" self.win.setProperty("NextAired%s.Label" % prefix, details["title"]) self.win.setProperty("NextAired%s.Thumb" % prefix, details["art"].get("thumb")) self.win.setProperty("NextAired%s.AirTime" % prefix, details["airdaytime"]) self.win.setProperty("NextAired%s.Path" % prefix, details["file"]) self.win.setProperty("NextAired%s.Library" % prefix, "videodb://tvshows/titles/%s/" % details["tvshowid"]) self.win.setProperty("NextAired%s.Status" % prefix, details["status"]) self.win.setProperty("NextAired%s.Network" % prefix, " / ".join(details["studio"])) self.win.setProperty("NextAired%s.Started" % prefix, details["firstaired"]) self.win.setProperty("NextAired%s.Classification" % prefix, details["classification"]) self.win.setProperty("NextAired%s.Genre" % prefix, " / ".join(details["genre"])) self.win.setProperty("NextAired%s.Premiered" % prefix, str(details["year"])) self.win.setProperty("NextAired%s.Runtime" % prefix, str(details["runtime"])) self.win.setProperty("NextAired%s.FanArt" % prefix, details["art"]["fanart"]) if details.get("next_episode"): # set next airing episode details if exist self.win.setProperty("NextAired%s.NextDate" % prefix, details["next_episode"]["airdate"]) self.win.setProperty("NextAired%s.NextDay" % prefix, details["next_episode"]["airdate.long"]) self.win.setProperty("NextAired%s.NextTitle" % prefix, details["next_episode"]["title"]) nextnumber = "%sx%s" % (details["next_episode"]["season"], details["next_episode"]["episode"]) self.win.setProperty("NextAired%s.NextNumber" % prefix, nextnumber) self.win.setProperty("NextAired%s.NextEpisodeNumber" % prefix, str(details["next_episode"]["episode"])) self.win.setProperty("NextAired%s.NextSeasonNumber" % prefix, str(details["next_episode"]["season"])) else: # clear next episode properties if we don't have that data for prop in ["NextDate", "NextDay", "NextTitle", "NextNumber", "NextEpisodeNumber", "NextSeasonNumber"]: self.win.clearProperty("NextAired%s.%s" % (prefix, prop)) if details.get("last_episode"): self.win.setProperty("NextAired%s.LatestDate" % prefix, details["last_episode"]["airdate"]) self.win.setProperty("NextAired%s.LatestDay" % prefix, details["last_episode"]["airdate.long"]) self.win.setProperty("NextAired%s.LatestTitle" % prefix, details["last_episode"]["title"]) nextnumber = "%sx%s" % (details["last_episode"]["season"], details["last_episode"]["episode"]) self.win.setProperty("NextAired%s.LatestNumber" % prefix, nextnumber) self.win.setProperty("NextAired%s.LatestEpisodeNumber" % prefix, str(details["last_episode"]["episode"])) self.win.setProperty("NextAired%s.LatestSeasonNumber" % prefix, str(details["last_episode"]["season"])) else: # clear last episode properties if we don't have that data for prop in ["LatestDate", "LatestDay", "LatestTitle", "LatestNumber", "LatestEpisodeNumber", "LatestSeasonNumber"]: self.win.clearProperty("NextAired%s.%s" % (prefix, prop)) self.win.setProperty("NextAired%s.Airday" % prefix, details["airday"]) self.win.setProperty("NextAired%s.ShortTime" % prefix, details["airtime"]) self.win.setProperty("NextAired%s.Art(poster)" % prefix, details["art"].get("poster")) self.win.setProperty("NextAired%s.Art(banner)" % prefix, details["art"].get("banner")) self.win.setProperty("NextAired%s.Art(fanart)" % prefix, details["art"].get("fanart")) self.win.setProperty("NextAired%s.Art(landscape)" % prefix, details["art"].get("landscape")) self.win.setProperty("NextAired%s.Art(clearlogo)" % prefix, details["art"].get("clearlogo")) self.win.setProperty("NextAired%s.Art(characterart)" % prefix, details["art"].get("characterart")) def clear_properties(self, prefix=""): """clears the nextaired window Properties""" props = ["label", "thumb", "airtime", "path", "library", "status", "statusid", "network", "started", "classification", "genre", "premiered", "country", "runtime", "fanart", "airstoday", "nextdate", "nextday", "nexttitle", "nextnumber", "nextepisodenumber", "nextseasonnumber", "latestdate", "latestday", "latesttitle", "latestnumber", "latestepisodenumber", "latestseasonnumber", "airday", "shorttime", "art(poster)", "art(banner)", "art(fanart)", "art(landscape)"] for prop in props: self.win.clearProperty("NextAired%s.%s" % (prefix, prop)) def main(self, action_param=None): """show the NextAired dialog""" weekday = self.date.weekday() self.win.setProperty("NextAired.TodayText", xbmc.getLocalizedString(33006)) self.win.setProperty("NextAired.TomorrowText", xbmc.getLocalizedString(33007)) self.win.setProperty("NextAired.YesterdayText", self.addon.getLocalizedString(32018)) self.win.setProperty("NextAired.TodayDate", self.str_date(self.date, 'DropYear')) self.win.setProperty("NextAired.TomorrowDate", self.str_date(self.tomorrow, 'DropThisYear')) self.win.setProperty("NextAired.YesterdayDate", self.str_date(self.yesterday, 'DropThisYear')) for count in range(0, 7): wdate = self.date if count != weekday: wdate += timedelta(days=(count - weekday + 7) % 7) self.win.setProperty("NextAired.%d.Date" % (count + 1), self.str_date(wdate, 'DropThisYear')) from next_aired_dialog import NextAiredDialog today_style = self.addon.getSetting("TodayStyle") == 'true' scan_days = int(self.addon.getSetting("ScanDays2" if today_style else "ScanDays")) want_yesterday = self.addon.getSetting("WantYesterday") == 'true' eps_list = self.get_nextaired_listing(include_last_episode=want_yesterday) xml = "script-NextAired-TVGuide%s.xml" % (2 if today_style else "") xml_path = self.addon.getAddonInfo('path').decode('utf-8') dialog = NextAiredDialog( xml, xml_path, "Default", listing=eps_list, nice_date=self.nice_date, scan_days=scan_days, today_style=today_style, want_yesterday=want_yesterday) dialog.doModal() del dialog def get_nextaired_listing(self, include_last_episode=False): """get the listing of all continuing series, include last episode and unaired episodes""" eps_list = self.thetvdb.get_kodi_unaired_episodes( single_episode_per_show=False, include_last_episode=include_last_episode) return eps_list def str_date(self, d, style=None): """The style setting only affects "nice" dates, not the historic format.""" if d is None: return '' return self.nice_date(d, style) if self.improve_dates else d.strftime(DATE_FORMAT) def nice_date(self, d, style=None): """Specify style DropThisYear, DropYear, or Short (or omit for the full info).""" tt = d.timetuple() if style == 'Short': fmt = NICE_SHORT_DATE elif style == 'DropYear' or (style == 'DropThisYear' and tt[0] == self.date.year): fmt = NICE_DATE_NO_YEAR else: fmt = NICE_DATE_FORMAT d = fmt % { 'year': tt[0], 'mm': tt[1], 'month': self.local_months[ tt[1] - 1], 'day': tt[2], 'wday': self.wdays[ tt[6]], 'unk': '??'} return d
def thetvdb(self): '''public TheTvDb object - for lazy loading''' if not self._thetvdb: from thetvdb import TheTvDb self._thetvdb = TheTvDb() return self._thetvdb
from thetvdb import TheTvDb from koding import dolog api_key = '12E8AAC46571E4C1' tvdb = TheTvDb() Series_info = [] Seasons = [] Season_number = [] Season_Episodes = [] Season_Episode = [] Episode_ID = [] def get_series_info(ID): series_info = tvdb.get_series(ID) Series_info.append(series_info) ''' tvdb.get_series == {'rating': 7, 'art': {'posters': [u'http://thetvdb.com/banners/posters/79412-1.jpg', u'http://thetvdb.com/banners/posters/79412-2.jpg', u'http://thetvdb.com/banners/posters/79412-3.jpg'], 'banner': u'http://thetvdb.com/banners/graphical/79412-g.jpg', 'poster': u'http://thetvdb.com/banners/posters/79412-1.jpg'}, 'airdaytime.short': u'Fri ', 'airdaytime.label': u'Friday - Network: Tokyo MX', 'plot': u'Ten years after the Holy War in Hong Kong, Mochizuki Jirou, aka the Silver Blade, and the lone hero who fought and defeated the Kowloon Children despite the loss of his lover, returns to Japan with his young brother, Mochizuki Kotaro. The two quickly discover that the Kowloon Children who survived the Holy War are seeking to infiltrate the \u201cSpecial Zone\u201d\u2014a thriving city protected by an invisible barrier that will not allow Kowloon Children entrance\u2014unless they\u2019re invited. Red Bloods refer to the humans; Black Bloods are the vampires, and the Mochizuki Brothers are Old Blood\u2014the last descendants of an elite clan of vampires. When Kotaro is abducted by one of the Kowloon Children, Jirou has no choice but to fight once more.', 'votes': 12, 'network': u'Tokyo MX', 'airdaytime': u'Friday (Tokyo MX)', 'airtime': '', 'airday': u'Friday', 'status': u'Ended', 'rating.tvdb': 7, 'tvdb_id': 79412, 'imdbnumber': u'tt0878230', 'studio': [u'Tokyo MX'], 'genre': [u'Action', u'Animation', u'Comedy', u'Fantasy'], 'airdaytime.label.short': u'Fri - Network: Tokyo MX', 'votes.tvdb': 12, 'airday.short': u'Fri', 'title': u'Black Blood Brothers', 'firstaired': u'2006-09-08', 'runtime': 1500} ''' def get_seasons(ID): series_seasons = tvdb.get_series_episodes(ID) for results in series_seasons: season = results['airedSeason'] if season not in Seasons: Seasons.append(season) Season_number.append({'season_number': season})
debug(sys.argv) debug("----") try: params = parameters_string_to_dict(sys.argv[2]) mode = urllib.unquote_plus(params.get('mode', '')) series = urllib.unquote_plus(params.get('series', '')) season = urllib.unquote_plus(params.get('season', '')) debug("Parameter Holen geklappt") except: debug("Parameter Holen nicht geklappt") mode = "" debug("Mode ist : " + mode) if mode == "": title = gettitle() lastplayd_title, lastepisode_name, fehlen = get_episodedata(title) tvdb = TheTvDb("de-DE") wert = tvdb.search_series(title.decode("utf-8")) count = 0 gefunden = 0 wertnr = 0 x = 0 for serie in wert: serienname = serie["seriesName"] nummer = similar(title, serienname) if nummer >= wertnr: wertnr = nummer gefunden = count x = 1 count += 1 debug("1. +++suche++" + title) debug(wert)
class MetadataUtils(object): ''' Provides all kind of mediainfo for kodi media, returned as dict with details ''' close_called = False def __init__(self): '''Initialize and load all our helpers''' self._studiologos_path = "" self.cache = SimpleCache() self.addon = xbmcaddon.Addon(ADDON_ID) self.kodidb = KodiDb() self.omdb = Omdb(self.cache) self.tmdb = Tmdb(self.cache) self.channellogos = ChannelLogos(self.kodidb) self.fanarttv = FanartTv(self.cache) self.imdb = Imdb(self.cache) self.google = GoogleImages(self.cache) self.studiologos = StudioLogos(self.cache) self.animatedart = AnimatedArt(self.cache, self.kodidb) self.thetvdb = TheTvDb() self.musicart = MusicArtwork(self) self.pvrart = PvrArtwork(self) log_msg("Initialized") def close(self): '''Cleanup instances''' self.close_called = True self.cache.close() self.addon = None del self.addon del self.kodidb del self.omdb del self.tmdb del self.channellogos del self.fanarttv del self.imdb del self.google del self.studiologos del self.animatedart del self.thetvdb del self.musicart del self.pvrart log_msg("Exited") def __del__(self): '''make sure close is called''' if not self.close_called: self.close() @use_cache(14) def get_extrafanart(self, file_path): '''helper to retrieve the extrafanart path for a kodi media item''' from helpers.extrafanart import get_extrafanart return get_extrafanart(file_path) def get_music_artwork(self, artist, album="", track="", disc="", ignore_cache=False, flush_cache=False): '''method to get music artwork for the goven artist/album/song''' return self.musicart.get_music_artwork(artist, album, track, disc, ignore_cache=ignore_cache, flush_cache=flush_cache) def music_artwork_options(self, artist, album="", track="", disc=""): '''options for music metadata for specific item''' return self.musicart.music_artwork_options(artist, album, track, disc) @use_cache(14) def get_extended_artwork(self, imdb_id="", tvdb_id="", tmdb_id="", media_type=""): '''get extended artwork for the given imdbid or tvdbid''' from urllib import quote_plus result = {"art": {}} if "movie" in media_type and tmdb_id: result["art"] = self.fanarttv.movie(tmdb_id) elif "movie" in media_type and imdb_id: result["art"] = self.fanarttv.movie(imdb_id) elif media_type in ["tvshow", "tvshows", "seasons", "episodes"]: if not tvdb_id: if imdb_id and not imdb_id.startswith("tt"): tvdb_id = imdb_id elif imdb_id: tvdb_id = self.thetvdb.get_series_by_imdb_id(imdb_id).get( "tvdb_id") if tvdb_id: result["art"] = self.fanarttv.tvshow(tvdb_id) # add additional art with special path for arttype in ["fanarts", "posters", "clearlogos", "banners"]: if result["art"].get(arttype): result["art"][arttype] = "plugin://script.skin.helper.service/"\ "?action=extrafanart&fanarts=%s" % quote_plus(repr(result["art"][arttype])) return result @use_cache(14) def get_tmdb_details(self, imdb_id="", tvdb_id="", title="", year="", media_type="", preftype="", manual_select=False, ignore_cache=False): '''returns details from tmdb''' result = {} if imdb_id: result = self.tmdb.get_videodetails_by_externalid( imdb_id, "imdb_id") elif tvdb_id: result = self.tmdb.get_videodetails_by_externalid( tvdb_id, "tvdb_id") elif title and media_type in ["movies", "setmovies", "movie"]: result = self.tmdb.search_movie(title, year, manual_select=manual_select) elif title and media_type in ["tvshows", "tvshow"]: result = self.tmdb.search_tvshow(title, year, manual_select=manual_select) elif title: result = self.tmdb.search_video(title, year, preftype=preftype, manual_select=manual_select) if result.get("status"): result["status"] = self.translate_string(result["status"]) if result.get("runtime"): result["runtime"] = result["runtime"] / 60 result.update(self.get_duration(result["runtime"])) return result def get_moviesetdetails(self, title, set_id): '''get a nicely formatted dict of the movieset details which we can for example set as window props''' # get details from tmdb from helpers.moviesetdetails import get_moviesetdetails return get_moviesetdetails(self, title, set_id) @use_cache(14) def get_streamdetails(self, db_id, media_type, ignore_cache=False): '''get a nicely formatted dict of the streamdetails ''' from helpers.streamdetails import get_streamdetails return get_streamdetails(self.kodidb, db_id, media_type) def get_pvr_artwork(self, title, channel="", genre="", manual_select=False, ignore_cache=False): '''get artwork and mediadetails for PVR entries''' import requests, urllib, random print title.encode('utf8') r = requests.get( 'http://192.168.0.2:8081/api/teleguide/get_arts?title=' + urllib.quote_plus(title.encode('utf8'))) j = r.json() if j['arts']: data = { 'art': { 'fanarts': j['arts'], 'fanart': random.choice(j['arts']), 'thumb': random.choice(j['arts']) }, 'cachestr': "pvr_artwork.%s.%s" % (title.lower(), channel.lower()), 'pvrtitle': title, 'pvrchannel': channel, 'pvrgenre': genre, 'genre': [genre], 'thumbnail': random.choice(j['arts']) } else: data = self.pvrart.get_pvr_artwork(title, channel, genre, manual_select=manual_select, ignore_cache=ignore_cache) log_msg(data) return data def pvr_artwork_options(self, title, channel="", genre=""): '''options for pvr metadata for specific item''' return self.pvrart.pvr_artwork_options(title, channel, genre) @use_cache(14) def get_channellogo(self, channelname): '''get channellogo for the given channel name''' return self.channellogos.get_channellogo(channelname) def get_studio_logo(self, studio): '''get studio logo for the given studio''' # dont use cache at this level because of changing logospath return self.studiologos.get_studio_logo(studio, self.studiologos_path) @property def studiologos_path(self): '''path to use to lookup studio logos, must be set by the calling addon''' return self._studiologos_path @studiologos_path.setter def studiologos_path(self, value): '''path to use to lookup studio logos, must be set by the calling addon''' self._studiologos_path = value def get_animated_artwork(self, imdb_id, manual_select=False, ignore_cache=False): '''get animated artwork, perform extra check if local version still exists''' artwork = self.animatedart.get_animated_artwork( imdb_id, manual_select, ignore_cache=ignore_cache) if not (manual_select or ignore_cache): refresh_needed = False if artwork.get("animatedposter") and not xbmcvfs.exists( artwork["animatedposter"]): refresh_needed = True if artwork.get("animatedfanart") and not xbmcvfs.exists( artwork["animatedfanart"]): refresh_needed = True if refresh_needed: artwork = self.animatedart.get_animated_artwork( imdb_id, manual_select, ignore_cache=True) return {"art": artwork} @use_cache(14) def get_omdb_info(self, imdb_id="", title="", year="", content_type=""): '''Get (kodi compatible formatted) metadata from OMDB, including Rotten tomatoes details''' title = title.split(" (")[0] # strip year appended to title result = {} if imdb_id: result = self.omdb.get_details_by_imdbid(imdb_id) elif title and content_type in [ "seasons", "season", "episodes", "episode", "tvshows", "tvshow" ]: result = self.omdb.get_details_by_title(title, "", "tvshows") elif title and year: result = self.omdb.get_details_by_title(title, year, content_type) if result.get("status"): result["status"] = self.translate_string(result["status"]) if result.get("runtime"): result["runtime"] = result["runtime"] / 60 result.update(self.get_duration(result["runtime"])) return result @use_cache(7) def get_top250_rating(self, imdb_id): '''get the position in the IMDB top250 for the given IMDB ID''' return self.imdb.get_top250_rating(imdb_id) @use_cache(14) def get_duration(self, duration): '''helper to get a formatted duration''' if isinstance(duration, (str, unicode)) and ":" in duration: dur_lst = duration.split(":") return { "Duration": "%s:%s" % (dur_lst[0], dur_lst[1]), "Duration.Hours": dur_lst[0], "Duration.Minutes": dur_lst[1], "Runtime": str((int(dur_lst[0]) * 60) + int(dur_lst[1])), } else: return _get_duration(duration) @use_cache(2) def get_tvdb_details(self, imdbid="", tvdbid=""): '''get metadata from tvdb by providing a tvdbid or tmdbid''' result = {} self.thetvdb.days_ahead = 365 if not tvdbid and imdbid and not imdbid.startswith("tt"): # assume imdbid is actually a tvdbid... tvdbid = imdbid if tvdbid: result = self.thetvdb.get_series(tvdbid) elif imdbid: result = self.thetvdb.get_series_by_imdb_id(imdbid) if result: if result["status"] == "Continuing": # include next episode info result["nextepisode"] = self.thetvdb.get_nextaired_episode( result["tvdb_id"]) # include last episode info result["lastepisode"] = self.thetvdb.get_last_episode_for_series( result["tvdb_id"]) result["status"] = self.translate_string(result["status"]) if result.get("runtime"): result["runtime"] = result["runtime"] / 60 result.update(_get_duration(result["runtime"])) return result @use_cache(14) def get_imdbtvdb_id(self, title, content_type, year="", imdbid="", tvshowtitle=""): '''try to figure out the imdbnumber and/or tvdbid''' tvdbid = "" if content_type in ["seasons", "episodes"] or tvshowtitle: title = tvshowtitle content_type = "tvshows" if imdbid and not imdbid.startswith("tt"): if content_type in ["tvshows", "seasons", "episodes"]: tvdbid = imdbid imdbid = "" if not imdbid and year: imdbid = self.get_omdb_info("", title, year, content_type).get("imdbnumber", "") if not imdbid: # repeat without year imdbid = self.get_omdb_info("", title, "", content_type).get("imdbnumber", "") # return results return (imdbid, tvdbid) def translate_string(self, _str): '''translate the received english string from the various sources like tvdb, tmbd etc''' translation = _str _str = _str.lower() if "continuing" in _str: translation = self.addon.getLocalizedString(32037) elif "ended" in _str: translation = self.addon.getLocalizedString(32038) elif "released" in _str: translation = self.addon.getLocalizedString(32040) return translation
class MetadataUtils(object): ''' Provides all kind of mediainfo for kodi media, returned as dict with details ''' close_called = False def __init__(self): '''Initialize and load all our helpers''' self._studiologos_path = "" self.cache = SimpleCache() self.addon = xbmcaddon.Addon(ADDON_ID) self.kodidb = KodiDb() self.omdb = Omdb(self.cache) self.tmdb = Tmdb(self.cache) self.channellogos = ChannelLogos(self.kodidb) self.fanarttv = FanartTv(self.cache) self.imdb = Imdb(self.cache) self.google = GoogleImages(self.cache) self.studiologos = StudioLogos(self.cache) self.animatedart = AnimatedArt(self.cache, self.kodidb) self.thetvdb = TheTvDb() self.musicart = MusicArtwork(self) self.pvrart = PvrArtwork(self) log_msg("Initialized") def close(self): '''Cleanup instances''' self.close_called = True self.cache.close() self.addon = None del self.addon del self.kodidb del self.omdb del self.tmdb del self.channellogos del self.fanarttv del self.imdb del self.google del self.studiologos del self.animatedart del self.thetvdb del self.musicart del self.pvrart log_msg("Exited") def __del__(self): '''make sure close is called''' if not self.close_called: self.close() @use_cache(14) def get_extrafanart(self, file_path): '''helper to retrieve the extrafanart path for a kodi media item''' from helpers.extrafanart import get_extrafanart return get_extrafanart(file_path) def get_music_artwork(self, artist, album="", track="", disc="", ignore_cache=False, flush_cache=False): '''method to get music artwork for the goven artist/album/song''' return self.musicart.get_music_artwork( artist, album, track, disc, ignore_cache=ignore_cache, flush_cache=flush_cache) def music_artwork_options(self, artist, album="", track="", disc=""): '''options for music metadata for specific item''' return self.musicart.music_artwork_options(artist, album, track, disc) @use_cache(7) def get_extended_artwork(self, imdb_id="", tvdb_id="", tmdb_id="", media_type=""): '''get extended artwork for the given imdbid or tvdbid''' result = None if "movie" in media_type and tmdb_id: result = self.fanarttv.movie(tmdb_id) elif "movie" in media_type and imdb_id: result = self.fanarttv.movie(imdb_id) elif media_type in ["tvshow", "tvshows", "seasons", "episodes"]: if not tvdb_id: if imdb_id and not imdb_id.startswith("tt"): tvdb_id = imdb_id elif imdb_id: tvdb_id = self.thetvdb.get_series_by_imdb_id(imdb_id).get("tvdb_id") if tvdb_id: result = self.fanarttv.tvshow(tvdb_id) # add additional art with special path if result: result = {"art": result} for arttype in ["fanarts", "posters", "clearlogos", "banners"]: if result["art"].get(arttype): result["art"][arttype] = "plugin://script.skin.helper.service/"\ "?action=extrafanart&fanarts=%s" % quote_plus(repr(result["art"][arttype])) return result def get_tmdb_details(self, imdb_id="", tvdb_id="", title="", year="", media_type="", preftype="", manual_select=False, ignore_cache=False): '''returns details from tmdb''' result = {} if imdb_id: result = self.tmdb.get_videodetails_by_externalid( imdb_id, "imdb_id") elif tvdb_id: result = self.tmdb.get_videodetails_by_externalid( tvdb_id, "tvdb_id") elif title and media_type in ["movies", "setmovies", "movie"]: result = self.tmdb.search_movie( title, year, manual_select=manual_select) elif title and media_type in ["tvshows", "tvshow"]: result = self.tmdb.search_tvshow( title, year, manual_select=manual_select) elif title: result = self.tmdb.search_video( title, year, preftype=preftype, manual_select=manual_select) if result and result.get("status"): result["status"] = self.translate_string(result["status"]) if result and result.get("runtime"): result["runtime"] = result["runtime"] / 60 result.update(self.get_duration(result["runtime"])) return result def get_moviesetdetails(self, title, set_id): '''get a nicely formatted dict of the movieset details which we can for example set as window props''' # get details from tmdb from helpers.moviesetdetails import get_moviesetdetails return get_moviesetdetails(self, title, set_id) @use_cache(14) def get_streamdetails(self, db_id, media_type, ignore_cache=False): '''get a nicely formatted dict of the streamdetails ''' from helpers.streamdetails import get_streamdetails return get_streamdetails(self.kodidb, db_id, media_type) def get_pvr_artwork(self, title, channel="", genre="", manual_select=False, ignore_cache=False): '''get artwork and mediadetails for PVR entries''' return self.pvrart.get_pvr_artwork( title, channel, genre, manual_select=manual_select, ignore_cache=ignore_cache) def pvr_artwork_options(self, title, channel="", genre=""): '''options for pvr metadata for specific item''' return self.pvrart.pvr_artwork_options(title, channel, genre) def get_channellogo(self, channelname): '''get channellogo for the given channel name''' return self.channellogos.get_channellogo(channelname) def get_studio_logo(self, studio): '''get studio logo for the given studio''' # dont use cache at this level because of changing logospath return self.studiologos.get_studio_logo(studio, self.studiologos_path) @property def studiologos_path(self): '''path to use to lookup studio logos, must be set by the calling addon''' return self._studiologos_path @studiologos_path.setter def studiologos_path(self, value): '''path to use to lookup studio logos, must be set by the calling addon''' self._studiologos_path = value def get_animated_artwork(self, imdb_id, manual_select=False, ignore_cache=False): '''get animated artwork, perform extra check if local version still exists''' artwork = self.animatedart.get_animated_artwork( imdb_id, manual_select=manual_select, ignore_cache=ignore_cache) if not (manual_select or ignore_cache): refresh_needed = False if artwork.get("animatedposter") and not xbmcvfs.exists( artwork["animatedposter"]): refresh_needed = True if artwork.get("animatedfanart") and not xbmcvfs.exists( artwork["animatedfanart"]): refresh_needed = True return {"art": artwork} def get_omdb_info(self, imdb_id="", title="", year="", content_type=""): '''Get (kodi compatible formatted) metadata from OMDB, including Rotten tomatoes details''' title = title.split(" (")[0] # strip year appended to title result = {} if imdb_id: result = self.omdb.get_details_by_imdbid(imdb_id) elif title and content_type in ["seasons", "season", "episodes", "episode", "tvshows", "tvshow"]: result = self.omdb.get_details_by_title(title, "", "tvshows") elif title and year: result = self.omdb.get_details_by_title(title, year, content_type) if result and result.get("status"): result["status"] = self.translate_string(result["status"]) if result and result.get("runtime"): result["runtime"] = result["runtime"] / 60 result.update(self.get_duration(result["runtime"])) return result def get_top250_rating(self, imdb_id): '''get the position in the IMDB top250 for the given IMDB ID''' return self.imdb.get_top250_rating(imdb_id) @use_cache(14) def get_duration(self, duration): '''helper to get a formatted duration''' if isinstance(duration, (str, unicode)) and ":" in duration: dur_lst = duration.split(":") return { "Duration": "%s:%s" % (dur_lst[0], dur_lst[1]), "Duration.Hours": dur_lst[0], "Duration.Minutes": dur_lst[1], "Runtime": str((int(dur_lst[0]) * 60) + int(dur_lst[1])), } else: return _get_duration(duration) @use_cache(2) def get_tvdb_details(self, imdbid="", tvdbid=""): '''get metadata from tvdb by providing a tvdbid or tmdbid''' result = {} self.thetvdb.days_ahead = 365 if not tvdbid and imdbid and not imdbid.startswith("tt"): # assume imdbid is actually a tvdbid... tvdbid = imdbid if tvdbid: result = self.thetvdb.get_series(tvdbid) elif imdbid: result = self.thetvdb.get_series_by_imdb_id(imdbid) if result: if result["status"] == "Continuing": # include next episode info result["nextepisode"] = self.thetvdb.get_nextaired_episode(result["tvdb_id"]) # include last episode info result["lastepisode"] = self.thetvdb.get_last_episode_for_series(result["tvdb_id"]) result["status"] = self.translate_string(result["status"]) if result.get("runtime"): result["runtime"] = result["runtime"] / 60 result.update(_get_duration(result["runtime"])) return result @use_cache(90) def get_imdbtvdb_id(self, title, content_type, year="", imdbid="", tvshowtitle=""): '''try to figure out the imdbnumber and/or tvdbid''' tvdbid = "" if content_type in ["seasons", "episodes"] or tvshowtitle: title = tvshowtitle content_type = "tvshows" if imdbid and not imdbid.startswith("tt"): if content_type in ["tvshows", "seasons", "episodes"]: tvdbid = imdbid imdbid = "" if not imdbid and year: imdbid = self.get_omdb_info( "", title, year, content_type).get("imdbnumber", "") if not imdbid: # repeat without year imdbid = self.get_omdb_info("", title, "", content_type).get("imdbnumber", "") # return results return (imdbid, tvdbid) def translate_string(self, _str): '''translate the received english string from the various sources like tvdb, tmbd etc''' translation = _str _str = _str.lower() if "continuing" in _str: translation = self.addon.getLocalizedString(32037) elif "ended" in _str: translation = self.addon.getLocalizedString(32038) elif "released" in _str: translation = self.addon.getLocalizedString(32040) return translation