示例#1
0
        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
示例#2
0
    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,
        ))
示例#3
0
    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,
        ))
示例#4
0
 def meta_hash(self):
     return tools.md5_hash(
         [self.language,
          self.fanart_support,
          self.normalization,
          self.show_normalization,
          self.meta_objects,
          self.base_url])
示例#5
0
 def meta_hash(self):
     return tools.md5_hash(
         (
             self.lang_code,
             self.art_map,
             self.baseUrl,
             self.imageBaseUrl,
             self.preferred_artwork_size,
         )
     )
示例#6
0
    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
        ])
示例#7
0
 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,
     ))
示例#8
0
 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)
示例#9
0
 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
示例#10
0
    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))
示例#11
0
    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))
示例#12
0
    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,
        ])
示例#15
0
    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))
示例#16
0
 def meta_hash(self):
     return tools.md5_hash((self.omdb_support, self.ApiUrl))
示例#17
0
 def meta_hash(self):
     return tools.md5_hash((self.language, self.ApiUrl, self.username))