def _decorated(*args, **kwargs): method_class = args[0] for a in args[1:]: if isinstance(a, types.GeneratorType): raise UnsupportedCacheParamException("generator") for k, v in kwargs.items(): if isinstance(v, types.GeneratorType): raise UnsupportedCacheParamException("generator") if func.__name__ == "get_sources": overwrite_cache = kwargs.get("overwrite_cache", False) kwargs_cache_value = { k: v for k, v in kwargs.items() if not k == "overwrite_cache" } else: overwrite_cache = kwargs.pop("overwrite_cache", False) kwargs_cache_value = kwargs hours = kwargs.pop("cache_hours", cache_hours) global_cache_ignore = g.get_bool_runtime_setting( "ignore.cache", False) ignore_cache = kwargs.pop("ignore_cache", False) if ignore_cache or global_cache_ignore: return func(*args, **kwargs) checksum = _get_checksum(method_class.__class__.__name__, func.__name__) cache_str = "{}.{}.{}.{}".format( method_class.__class__.__name__, func.__name__, tools.md5_hash(args[1:]), tools.md5_hash(kwargs_cache_value)) cached_data = g.CACHE.get( cache_str, checksum=checksum ) if not overwrite_cache else CacheBase.NOT_CACHED if cached_data == CacheBase.NOT_CACHED: fresh_result = func(*args, **kwargs) if func.__name__ == "get_sources" and (not fresh_result or len( fresh_result[1]) == 0): return fresh_result try: g.CACHE.set( cache_str, fresh_result, expiration=datetime.timedelta(hours=hours), checksum=checksum, ) except TypeError: g.log_stacktrace() pass return fresh_result else: return cached_data
def __init__(self): self.session = requests.Session() self.session.mount("https://", HTTPAdapter(max_retries=self.retries)) self._load_settings() self.lang_code = g.get_language_code(False) self.languages = ([None, self.lang_code] if self.lang_code != "en" and any(self.lang_code == i["abbreviation"] for i in self.supported_languages) else [None]) if not self.jwToken: self.init_token() else: self.try_refresh_token() self.preferred_artwork_size = g.get_int_setting( "artwork.preferredsize") self.meta_hash = tools.md5_hash(( self.lang_code, self.art_map, self.baseUrl, self.imageBaseUrl, self.preferred_artwork_size, ))
def __init__(self): self.apiKey = g.get_setting("tvdb.apikey", "43VPI0R8323FB7TI") self.jwToken = g.get_setting("tvdb.jw") self.tokenExpires = g.get_float_setting("tvdb.expiry") self.lang_code = g.get_language_code(False) self.languages = ([None, self.lang_code] if self.lang_code != "en" and any(self.lang_code == i["abbreviation"] for i in self.supported_languages) else [None]) if not self.jwToken: self.init_token() else: self.try_refresh_token() self.preferred_artwork_size = g.get_int_setting( "artwork.preferredsize") self.meta_hash = tools.md5_hash(( self.lang_code, self.art_map, self.baseUrl, self.imageBaseUrl, self.preferred_artwork_size, ))
def meta_hash(self): return tools.md5_hash( [self.language, self.fanart_support, self.normalization, self.show_normalization, self.meta_objects, self.base_url])
def meta_hash(self): return tools.md5_hash( ( self.lang_code, self.art_map, self.baseUrl, self.imageBaseUrl, self.preferred_artwork_size, ) )
def __init__(self): self.language = g.get_language_code() self.client_key = g.get_setting('fanart.apikey') self.fanart_support = False if not self.client_key else True self.headers = {'client-key': self.client_key, 'api-key': self.api_key} self.meta_hash = tools.md5_hash([ self.language, self.fanart_support, self.normalization, self.show_normalization, self.meta_objects, self.base_url ])
def meta_hash(self): return tools.md5_hash(( self.lang_code, self.lang_full_code, self.lang_region_code, self.include_languages, self.preferred_artwork_size, self.append_to_response, self.baseUrl, self.imageBaseUrl, ))
def _integrity_check_db(self): db_file_checksum = tools.md5_hash(self._database_layout) with GlobalLock(self.__class__.__name__, self._threading_lock, True, db_file_checksum) as lock: if lock.runned_once(): return if g.read_all_text("{}.md5".format( self._db_file)) == db_file_checksum: return g.log("Integrity checked failed - {} - {} - rebuilding db".format( self._db_file, db_file_checksum)) self.rebuild_database() g.write_all_text("{}.md5".format(self._db_file), db_file_checksum)
def _integrity_check_db(self): db_file_checksum = tools.md5_hash(self._database_layout) try: with GlobalLock(self.__class__.__name__, True, db_file_checksum): if xbmcvfs.exists(self._db_file) and g.read_all_text( "{}.md5".format(self._db_file)) == db_file_checksum: return g.log("Integrity checked failed - {} - {} - rebuilding db". format(self._db_file, db_file_checksum)) self.rebuild_database() g.write_all_text("{}.md5".format(self._db_file), db_file_checksum) except RanOnceAlready: return
def __init__(self): self.language = g.get_language_code() self.client_key = g.get_setting('fanart.apikey') self.fanart_support = False if not self.client_key else True self.headers = {'client-key': self.client_key, 'api-key': self.api_key} self.meta_hash = tools.md5_hash( [self.language, self.fanart_support, self.normalization, self.show_normalization, self.meta_objects, self.base_url]) self.session = requests.Session() retries = Retry(total=5, backoff_factor=0.1, status_forcelist=[500, 502, 503, 504]) self.session.mount('https://', HTTPAdapter(max_retries=retries))
def __init__(self): self.apiKey = g.get_setting("tmdb.apikey", "9f3ca569aa46b6fb13931ec96ab8ae7e") self.lang_code = g.get_language_code() self.lang_full_code = g.get_language_code(True) self.lang_region_code = self.lang_full_code.split("-")[1] if self.lang_region_code == "": self.lang_full_code = self.lang_full_code.strip("-") self.include_languages = OrderedDict.fromkeys( [self.lang_code, "en", "null"]) self.preferred_artwork_size = g.get_int_setting( "artwork.preferredsize") self.artwork_size = {} self._set_artwork() self.art_normalization = [ ("backdrops", "fanart", None), ( "posters", "poster", lambda x: x["iso_639_1"] != "xx" and x["iso_639_1"] is not None, ), ( "posters", "keyart", lambda x: x["iso_639_1"] == "xx" or x["iso_639_1"] is None, ), ("stills", "fanart", None), ] self.meta_hash = tools.md5_hash(( self.lang_code, self.lang_full_code, self.lang_region_code, self.include_languages, self.preferred_artwork_size, self.append_to_response, self.baseUrl, self.imageBaseUrl, )) self.session = requests.Session() retries = Retry(total=5, backoff_factor=0.1, status_forcelist=[500, 502, 503, 504]) self.session.mount("https://", HTTPAdapter(max_retries=retries, pool_maxsize=100))
def __init__(self): self.apiKey = g.get_setting("tmdb.apikey", "9f3ca569aa46b6fb13931ec96ab8ae7e") self.lang_code = g.get_language_code() self.lang_full_code = g.get_language_code(True) self.lang_region_code = self.lang_full_code.split("-")[1] if self.lang_region_code == "": self.lang_full_code = self.lang_full_code.strip("-") self.include_languages = OrderedDict.fromkeys( [self.lang_code, "en", "null"]) self.preferred_artwork_size = g.get_int_setting( "artwork.preferredsize") self.artwork_size = {} self._set_artwork() self.art_normalization = [ ("backdrops", "fanart", None), ( "posters", "poster", lambda x: x["iso_639_1"] != "xx" and x["iso_639_1"] is not None, ), ( "posters", "keyart", lambda x: x["iso_639_1"] == "xx" or x["iso_639_1"] is None, ), ("stills", "fanart", None), ] self.meta_hash = tools.md5_hash(( self.lang_code, self.lang_full_code, self.lang_region_code, self.include_languages, self.preferred_artwork_size, self.append_to_response, self.baseUrl, self.imageBaseUrl, ))
def download(self, url, overwrite=False): """ :param url: Web Path to file eg:(http://google.com/images/randomimage.jpeg) :param overwrite: opt. This will trigger a removal any conflicting files prior to download :return: Bool - True = Completed successfully / False = Cancelled """ g.log("Downloading file: {}".format(url)) if not url or not url.startswith("http"): raise InvalidWebPath(url) if self.output_filename is None: self.output_filename = url.split("/")[-1] g.log( "Filename: {} - Location: {}".format( self.output_filename, self.storage_location ) ) output_file = self._create_file(url, overwrite) self._output_file = output_file g.log("Created file - {}".format(self._output_path)) head = requests.head(url) if head.status_code != 200: g.log("Server did not respond correctly to the head request") self._handle_failure() raise requests.exceptions.ConnectionError(head.status_code) self.url_hash = tools.md5_hash(url) if not self._add_download_to_dm(): g.log("Failed to create download manager task", "error") self._handle_failure() return self.file_size = int(head.headers.get("content-length", None)) self.progress = 0 self.speed = 0 self.status = "downloading" monitor = xbmc.Monitor() for chunk in requests.get(url, stream=True).iter_content(1024 * 1024): if monitor.abortRequested(): self._handle_failure() g.log( "Shutdown requested - Cancelling download: {}".format( self.output_filename ), "warning", ) self.cancel_download() if self._is_canceled(): g.log( "User cancellation - Cancelling download: {}".format( self.output_filename ), "warning", ) self.cancel_download() self.status = "canceled" return False result = output_file.write(chunk) if not result: self._handle_failure() self.status = "failed" g.log( "Failed to fetch chunk from remote server -" " Cancelling download: {}".format(self.output_filename), "error", ) raise GeneralIOError(self.output_filename) else: self._update_status(len(chunk)) g.log( "Download has completed successfully - Filename: {}".format( self.output_filename ) ) return True
def __init__( self, tmdb_api=None, tvdb_api=None, fanarttv_api=None, trakt_api=None, omdb_api=None, ): self.tmdb_api = tmdb_api if tmdb_api else TMDBAPI() self.tvdb_api = tvdb_api if tvdb_api else TVDBAPI() self.fanarttv_api = fanarttv_api if fanarttv_api else FanartTv() self.trakt_api = trakt_api if trakt_api else TraktAPI() self.omdb_api = omdb_api if omdb_api else OmdbApi() self.lang_code = g.get_language_code() self.lang_full_code = g.get_language_code(True) self.lang_region_code = self.lang_full_code.split("-")[:1] self.allowed_artwork_languages = {None, "en", self.lang_code} self.movies_poster_limit = g.get_int_setting("movies.poster_limit", 1) self.movies_fanart_limit = g.get_int_setting("movies.fanart_limit", 1) self.movies_keyart_limit = g.get_int_setting("movies.keyart_limit", 1) self.movies_characterart_limit = g.get_int_setting( "movies.characterart_limit", 1) self.movies_banner = g.get_bool_setting("movies.banner", "true") self.movies_clearlogo = g.get_bool_setting("movies.clearlogo", "true") self.movies_landscape = g.get_bool_setting("movies.landscape", "true") self.movies_clearart = g.get_bool_setting("movies.clearart", "true") self.movies_discart = g.get_bool_setting("movies.discart", "true") self.tvshows_poster_limit = g.get_int_setting("tvshows.poster_limit", 1) self.tvshows_fanart_limit = g.get_int_setting("tvshows.fanart_limit", 1) self.tvshows_keyart_limit = g.get_int_setting("tvshows.keyart_limit", 1) self.tvshows_characterart_limit = g.get_int_setting( "tvshows.characterart_limit", 1) self.tvshows_banner = g.get_bool_setting("tvshows.banner", "true") self.tvshows_clearlogo = g.get_bool_setting("tvshows.clearlogo", "true") self.tvshows_landscape = g.get_bool_setting("tvshows.landscape", "true") self.tvshows_clearart = g.get_bool_setting("tvshows.clearart", "true") self.season_poster = g.get_bool_setting("season.poster", "true") self.season_banner = g.get_bool_setting("season.banner", "true") self.season_landscape = g.get_bool_setting("season.landscape", "true") self.season_fanart = g.get_bool_setting("season.fanart", "true") self.episode_fanart = g.get_bool_setting("episode.fanart", "true") self.tvshows_preferred_art_source = g.get_int_setting( "tvshows.preferedsource", 1) self.movies_preferred_art_source = g.get_int_setting( "movies.preferedsource", 1) self.metadata_location = g.get_int_setting("general.metalocation", 1) self.preferred_artwork_size = g.get_int_setting( "artwork.preferredsize", 1) self.show_original_title = g.get_bool_setting( "general.meta.showoriginaltitle", False) self.genres = { "action": g.get_language_string(30534), "adventure": g.get_language_string(30535), "animation": g.get_language_string(30536), "anime": g.get_language_string(30537), "biography": g.get_language_string(30538), "children": g.get_language_string(30539), "comedy": g.get_language_string(30540), "crime": g.get_language_string(30541), "documentary": g.get_language_string(30542), "drama": g.get_language_string(30543), "family": g.get_language_string(30544), "fantasy": g.get_language_string(30545), "game-show": g.get_language_string(30546), "history": g.get_language_string(30547), "holiday": g.get_language_string(30548), "home-and-garden": g.get_language_string(30549), "horror": g.get_language_string(30550), "mini-series": g.get_language_string(30551), "music": g.get_language_string(30552), "musical": g.get_language_string(30553), "mystery": g.get_language_string(30554), "news": g.get_language_string(30555), "none": g.get_language_string(30556), "reality": g.get_language_string(30557), "romance": g.get_language_string(30558), "science-fiction": g.get_language_string(30559), "sci-fi": g.get_language_string(30559), "short": g.get_language_string(30560), "soap": g.get_language_string(30561), "special-interest": g.get_language_string(30562), "sporting-event": g.get_language_string(30563), "superhero": g.get_language_string(30564), "suspense": g.get_language_string(30565), "talk-show": g.get_language_string(30566), "talkshow": g.get_language_string(30566), "thriller": g.get_language_string(30567), "tv-movie": g.get_language_string(30568), "war": g.get_language_string(30569), "western": g.get_language_string(30570), } self.meta_hash = tools.md5_hash([ self.lang_code, self.movies_poster_limit, self.movies_fanart_limit, self.movies_keyart_limit, self.movies_characterart_limit, self.movies_banner, self.movies_clearlogo, self.movies_landscape, self.movies_clearart, self.movies_discart, self.tvshows_poster_limit, self.tvshows_fanart_limit, self.tvshows_keyart_limit, self.tvshows_characterart_limit, self.tvshows_banner, self.tvshows_clearlogo, self.tvshows_landscape, self.tvshows_clearart, self.season_poster, self.season_banner, self.season_landscape, self.season_fanart, self.episode_fanart, self.tvshows_preferred_art_source, self.tvshows_preferred_art_source, self.metadata_location, self.fanarttv_api.fanart_support, self.preferred_artwork_size, self.show_original_title, ])
def __init__(self): self.api_key = g.get_setting("omdb.apikey", None) self.omdb_support = False if not self.api_key else True self.meta_hash = tools.md5_hash((self.omdb_support, self.ApiUrl)) self.normalization = [ ( "@title", ("title", "sorttitle"), lambda d: d if not self._is_value_none(d) else None, ), ("@rated", "mpaa", lambda d: d if not self._is_value_none(d) else None), ( "@released", ("premiered", "aired"), lambda d: g.validate_date(d) if not self._is_value_none(d) else None, ), ( "@runtime", "duration", lambda d: int(d[:-4]) * 60 if not self._is_value_none(d) and len(d) > 4 and d[:-4].isdigit() else None, ), ( "@genre", "genre", lambda d: sorted( OrderedDict.fromkeys({x.strip() for x in d.split(",")})) if not self._is_value_none(d) else None, ), ( "@director", "director", lambda d: sorted( OrderedDict.fromkeys({ re.sub(r"\(.*?\)", "", x).strip() for x in d.split(",") })) if not self._is_value_none(d) else None, ), ( "@writer", "writer", lambda d: sorted( OrderedDict.fromkeys({ re.sub(r"\(.*?\)", "", x).strip() for x in d.split(",") })) if not self._is_value_none(d) else None, ), ("@plot", ("plot", "overview", "plotoutline"), None), ( "@country", "country", lambda d: d if not self._is_value_none(d) else None, ), ("@imdbID", ("imdbnumber", "imdb_id"), None), ( None, "rating.imdb", ( ("@imdbRating", "@imdbVotes"), lambda a, c: { "rating": tools.safe_round(tools.get_clean_number(a), 2 ), "votes": tools.get_clean_number(c), } if not self._is_value_none(a) and not self. _is_value_none(c) else None, ), ), ( "@Production", "studio", lambda d: d if not self._is_value_none(d) else None, ), ("@awards", "awards", lambda d: d if not self._is_value_none(d) else None), ( "@awards", "oscar_wins", lambda d: self._extract_awards(d, ("Won", "Oscar")), ), ( "@awards", "oscar_nominations", lambda d: self._extract_awards(d, ("Nominated for", "Oscar")), ), ( "@awards", "award_wins", lambda d: self._extract_awards(d, ("Another", "wins"), ("", "wins")), ), ( "@awards", "award_nominations", lambda d: self._extract_awards(d, ("wins &", "nominations"), ("", "nominations")), ), ( "@metascore", "metacritic_rating", lambda d: d if not self._is_value_none(d) else None, ), ( "@tomatoMeter", "rottentomatoes_rating", lambda d: d if not self._is_value_none(d) else None, ), ( "@tomatoImage", "rottentomatoes_image", lambda d: d if not self._is_value_none(d) else None, ), ( "@tomatoReviews", "rottentomatoes_reviewstotal", lambda d: tools.get_clean_number(d) if not self._is_value_none(d) else None, ), ( "@tomatoFresh", "rottentomatoes_reviewsfresh", lambda d: tools.get_clean_number(d) if not self._is_value_none(d) else None, ), ( "@tomatoRotten", "rottentomatoes_reviewsrotten", lambda d: tools.get_clean_number(d) if not self._is_value_none(d) else None, ), ( "@tomatoConsensus", "rottentomatoes_consensus", lambda d: d if not self._is_value_none(d) else None, ), ( "@tomatoUserMeter", "rottentomatoes_usermeter", lambda d: d if not self._is_value_none(d) else None, ), ( "@tomatoUserReviews", "rottentomatoes_userreviews", lambda d: tools.get_clean_number(d) if not self._is_value_none(d) else None, ), ] self.session = requests.Session() retries = Retry( total=5, backoff_factor=0.1, status_forcelist=[500, 503, 504, 520, 521, 522, 524], ) self.session.mount("https://", HTTPAdapter(max_retries=retries))
def meta_hash(self): return tools.md5_hash((self.omdb_support, self.ApiUrl))
def meta_hash(self): return tools.md5_hash((self.language, self.ApiUrl, self.username))