Beispiel #1
0
def tvdb_series_id_episodes(
    token: str,
    id_tvdb: Union[str, int],
    page: int = 1,
    language: Optional[Language] = None,
    cache: bool = True,
) -> dict:
    """
    All episodes for a given series.

    Note: Paginated with 100 results per page.
    Online docs: api.thetvdb.com/swagger#!/Series/get_series_id_episodes.
    """
    Language.ensure_valid_for_tvdb(language)
    url = f"https://api.thetvdb.com/series/{id_tvdb}/episodes"
    headers = {"Authorization": f"Bearer {token}"}
    if language:
        headers["Accept-Language"] = language.a2
    parameters = {"page": page}
    status, content = request_json(
        url,
        parameters,
        headers=headers,
        cache=cache is True and language is None,
    )
    if status == 401:
        raise MnamerException("invalid token")
    elif status == 404:
        raise MnamerNotFoundException
    elif status != 200 or not content.get("data"):  # pragma: no cover
        raise MnamerNetworkException("TVDb down or unavailable?")
    return content
Beispiel #2
0
def tvdb_series_id_episodes_query(
    token: str,
    id_tvdb: Union[str, int],
    episode: Optional[int] = None,
    season: Optional[int] = None,
    page: int = 1,
    language: Optional[Language] = None,
    cache: bool = True,
) -> dict:
    """
    Allows the user to query against episodes for the given series.

    Note: Paginated with 100 results per page; omitted imdbId-- when would you
    ever need to query against both tvdb and imdb series ids?
    Online docs: api.thetvdb.com/swagger#!/Series/get_series_id_episodes_query.
    """
    Language.ensure_valid_for_tvdb(language)
    url = f"https://api.thetvdb.com/series/{id_tvdb}/episodes/query"
    headers = {"Authorization": f"Bearer {token}"}
    if language:
        headers["Accept-Language"] = language.a2
    parameters = {"airedSeason": season, "airedEpisode": episode, "page": page}
    status, content = request_json(
        url,
        parameters,
        headers=headers,
        cache=cache is True and language is None,
    )
    if status == 401:
        raise MnamerException("invalid token")
    elif status == 404:
        raise MnamerNotFoundException
    elif status != 200 or not content.get("data"):  # pragma: no cover
        raise MnamerNetworkException("TVDb down or unavailable?")
    return content
Beispiel #3
0
def tvdb_search_series(
    token: str,
    series: Optional[str] = None,
    id_imdb: Optional[str] = None,
    id_zap2it: Optional[str] = None,
    language: Optional[Language] = None,
    cache: bool = True,
) -> dict:
    """
    Allows the user to search for a series based on the following parameters.

    Online docs: https://api.thetvdb.com/swagger#!/Search/get_search_series
    Note: results a maximum of 100 entries per page, no option for pagination.
    """
    Language.ensure_valid_for_tvdb(language)
    url = "https://api.thetvdb.com/search/series"
    parameters = {"name": series, "imdbId": id_imdb, "zap2itId": id_zap2it}
    headers = {"Authorization": f"Bearer {token}"}
    if language:
        headers["Accept-Language"] = language.a2
    status, content = request_json(
        url, parameters, headers=headers, cache=cache is True and language is None
    )
    if status == 401:
        raise MnamerException("invalid token")
    elif status == 405:
        raise MnamerException(
            "series, id_imdb, id_zap2it parameters are mutually exclusive"
        )
    elif status == 404:
        raise MnamerNotFoundException
    elif status != 200 or not content.get("data"):  # pragma: no cover
        raise MnamerNetworkException("TVDb down or unavailable?")
    return content
Beispiel #4
0
def tvdb_series_id(
    token: str,
    id_tvdb: Union[str, int],
    language: Optional[Language] = None,
    cache: bool = True,
) -> dict:
    """
    Returns a series records that contains all information known about a
    particular series id.

    Online docs: api.thetvdb.com/swagger#!/Series/get_series_id.
    """
    Language.ensure_valid_for_tvdb(language)
    url = f"https://api.thetvdb.com/series/{id_tvdb}"
    headers = {"Authorization": f"Bearer {token}"}
    if language:
        headers["Accept-Language"] = language.a2
    status, content = request_json(
        url, headers=headers, cache=cache is True and language is None
    )
    if status == 401:
        raise MnamerException("invalid token")
    elif status == 404:
        raise MnamerNotFoundException
    elif status != 200 or not content.get("data"):  # pragma: no cover
        raise MnamerNetworkException("TVDb down or unavailable?")
    elif content["data"]["id"] == 0:
        raise MnamerNotFoundException
    return content
Beispiel #5
0
def test_tvdb_episodes_id__invalid_lang(tvdb_token):
    with pytest.raises(MnamerException):
        tvdb_episodes_id(
            tvdb_token,
            LOST_TVDB_ID_EPISODE,
            language=Language(JUNK_TEXT, JUNK_TEXT, JUNK_TEXT),
            cache=False,
        )
Beispiel #6
0
def test_tvdb_series_id_episodes_query__invalid_lang(tvdb_token):
    with pytest.raises(MnamerException):
        tvdb_series_id_episodes_query(
            tvdb_token,
            LOST_TVDB_ID_SERIES,
            language=Language(JUNK_TEXT, JUNK_TEXT, JUNK_TEXT),
            cache=False,
        )
Beispiel #7
0
def test_tvdb_search_series__invalid_lang(tvdb_token):
    with pytest.raises(MnamerException):
        tvdb_search_series(
            tvdb_token,
            "Lost",
            language=Language(JUNK_TEXT, JUNK_TEXT, JUNK_TEXT),
            cache=False,
        )
Beispiel #8
0
def subtitle_prompt() -> Metadata:
    msg("select language")
    choices = [ChoiceHelper(language, language.name) for language in Language.all()]
    selector = SelectOne(choices + _abort_helpers(), **_chars())
    choice = selector.prompt()
    if choice in (MnamerAbortException, MnamerSkipException):
        raise choice
    else:
        return choice
Beispiel #9
0
        "media": "movie",
        "name": "Citizen Kane",
        "year": 1941,
    },
    "Les Misérables": {
        "id_imdb": "tt10199590",
        "id_tmdb": 586863,
        "media": "movie",
        "name": "Les Misérables",
        "year": 2019,
    },
}

TEST_DATE = date(2010, 12, 9)

RUSSIAN_LANG = Language.parse("ru")


class E2EResult(NamedTuple):
    code: int
    out: str


class MockRequestResponse:
    def __init__(self, status: int, content: str) -> None:
        self.status_code = status
        self.content = content

    def json(self) -> Dict[str, Any]:
        from json import loads
Beispiel #10
0
 def _parse(self, file_path: PurePath):
     path_data = {}
     options = {"type": self._settings.media}
     raw_data = dict(guessit(str(file_path), options))
     if isinstance(raw_data.get("season"), list):
         raw_data = dict(guessit(str(file_path.parts[-1]), options))
     for k, v in raw_data.items():
         if hasattr(v, "alpha3"):
             try:
                 path_data[k] = Language.parse(v)
             except MnamerException:
                 continue
         elif isinstance(v, (int, str, date)):
             path_data[k] = v
         elif isinstance(v, list) and all(
             [isinstance(_, (int, str)) for _ in v]
         ):
             path_data[k] = v[0]
     if self._settings.media:
         media_type = self._settings.media
     elif path_data.get("type"):
         media_type = MediaType(path_data["type"])
     else:
         media_type = None
     meta_cls = {
         MediaType.EPISODE: MetadataEpisode,
         MediaType.MOVIE: MetadataMovie,
         None: Metadata,
     }[media_type]
     self.metadata = meta_cls(language=self._settings.language)
     self.metadata.quality = (
         " ".join(
             path_data[key]
             for key in path_data
             if key
             in (
                 "audio_codec",
                 "audio_profile",
                 "screen_size",
                 "source",
                 "video_codec",
                 "video_profile",
             )
         )
         or None
     )
     self.metadata.group = path_data.get("release_group")
     self.metadata.container = file_path.suffix or None
     if not self.metadata.language:
         try:
             self.metadata.language = path_data.get("language")
         except MnamerException:
             pass
     try:
         self.metadata.language_sub = path_data.get("subtitle_language")
     except MnamerException:
         pass
     if self.metadata.media is MediaType.MOVIE:
         self.metadata.name = path_data.get("title")
         self.metadata.year = path_data.get("year")
     elif self.metadata.media is MediaType.EPISODE:
         self.metadata.date = path_data.get("date")
         self.metadata.episode = path_data.get("episode")
         self.metadata.season = path_data.get("season")
         self.metadata.series = path_data.get("title")
         alternative_title = path_data.get("alternative_title")
         if alternative_title:
             self.metadata.series = (
                 f"{self.metadata.series} {alternative_title}"
             )
Beispiel #11
0
def test_tvdb_episodes_id__language__invalid(tvdb_token):
    invalid_language = Language("invalid", "xy", "xyz")
    with pytest.raises(MnamerException):
        tvdb_episodes_id(tvdb_token, LOST_TVDB_ID_EPISODE, invalid_language)
Beispiel #12
0
def test_language_parse__str(value):
    expected = Language("English", "en", "eng")
    actual = Language.parse(value)
    assert actual == expected
Beispiel #13
0
def test_language_all():
    expected = (
        Language("English", "en", "eng"),
        Language("French", "fr", "fra"),
        Language("Spanish", "es", "spa"),
        Language("German", "de", "deu"),
        Language("Hindi", "hi", "hin"),
        Language("Chinese", "zh", "zho"),
        Language("Japanese", "ja", "jpn"),
        Language("Italian", "it", "ita"),
        Language("Russian", "ru", "rus"),
        Language("Arabic", "ar", "ara"),
        Language("Korean", "ko", "kor"),
        Language("Hebrew", "he", "heb"),
        Language("Portuguese", "pt", "por"),
        Language("Swedish", "sv", "swe"),
        Language("Latin", "la", "lat"),
        Language("Ukrainian", "uk", "ukr"),
        Language("Danish", "da", "dan"),
        Language("Persian", "fa", "fas"),
    )
    actual = Language.all()
    assert actual == expected
Beispiel #14
0
def test_language_parse__bl():
    expected = Language("English", "en", "eng")
    actual = Language.parse(BabelLang("eng"))
    assert actual == expected