parent
24196d899f
commit
c9d63f717f
@ -0,0 +1,103 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import logging
|
||||
|
||||
from requests import HTTPError
|
||||
from requests import Session
|
||||
from subliminal_patch.core import Episode
|
||||
from subliminal_patch.language import PatchedAddic7edConverter
|
||||
from subliminal_patch.providers import Provider
|
||||
from subliminal_patch.providers.utils import update_matches
|
||||
from subliminal_patch.subtitle import Subtitle
|
||||
from subzero.language import Language
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_BASE_URL = "https://api.gestdown.info"
|
||||
|
||||
|
||||
class GestdownSubtitle(Subtitle):
|
||||
provider_name = "gestdown"
|
||||
hash_verifiable = False
|
||||
|
||||
def __init__(self, language, data: dict):
|
||||
super().__init__(language, hearing_impaired=data["hearingImpaired"])
|
||||
self.page_link = _BASE_URL + data["downloadUri"]
|
||||
self._id = data["subtitleId"]
|
||||
self.release_info = data["version"]
|
||||
self._matches = {"title", "series", "season", "episode"}
|
||||
|
||||
def get_matches(self, video):
|
||||
update_matches(self._matches, video, self.release_info)
|
||||
|
||||
return self._matches
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
return self._id
|
||||
|
||||
|
||||
class GestdownProvider(Provider):
|
||||
provider_name = "gestdown"
|
||||
|
||||
video_types = (Episode,)
|
||||
subtitle_class = GestdownSubtitle
|
||||
|
||||
# fmt: off
|
||||
languages = {Language('por', 'BR')} | {Language(l) for l in [
|
||||
'ara', 'aze', 'ben', 'bos', 'bul', 'cat', 'ces', 'dan', 'deu', 'ell', 'eng', 'eus', 'fas', 'fin', 'fra', 'glg',
|
||||
'heb', 'hrv', 'hun', 'hye', 'ind', 'ita', 'jpn', 'kor', 'mkd', 'msa', 'nld', 'nor', 'pol', 'por', 'ron', 'rus',
|
||||
'slk', 'slv', 'spa', 'sqi', 'srp', 'swe', 'tha', 'tur', 'ukr', 'vie', 'zho'
|
||||
]} | {Language.fromietf(l) for l in ["sr-Latn", "sr-Cyrl"]}
|
||||
languages.update(set(Language.rebuild(l, hi=True) for l in languages))
|
||||
# fmt: on
|
||||
|
||||
_converter = PatchedAddic7edConverter()
|
||||
|
||||
def initialize(self):
|
||||
self._session = Session()
|
||||
self._session.headers.update({"User-Agent": "Bazarr"})
|
||||
|
||||
def terminate(self):
|
||||
self._session.close()
|
||||
|
||||
def _subtitles_search(self, video, language: Language):
|
||||
json_data = {
|
||||
"search": f"{video.series} S{video.season:02}E{video.episode:02}",
|
||||
"language": self._converter.convert(language.alpha3),
|
||||
}
|
||||
|
||||
logger.debug("Post data: %s", json_data)
|
||||
response = self._session.post(f"{_BASE_URL}/subtitles/search", json=json_data)
|
||||
|
||||
# TODO: implement rate limiting
|
||||
response.raise_for_status()
|
||||
|
||||
matching_subtitles = response.json()["matchingSubtitles"]
|
||||
|
||||
if not matching_subtitles:
|
||||
logger.debug("No episodes found for '%s' language", language)
|
||||
return None
|
||||
|
||||
for subtitle_dict in matching_subtitles:
|
||||
sub = GestdownSubtitle(language, subtitle_dict)
|
||||
logger.debug("Found subtitle: %s", sub)
|
||||
yield sub
|
||||
|
||||
def list_subtitles(self, video, languages):
|
||||
subtitles = []
|
||||
for language in languages:
|
||||
try:
|
||||
subtitles += self._subtitles_search(video, language)
|
||||
except HTTPError as error:
|
||||
if error.response.status_code == 404:
|
||||
logger.debug("Couldn't find the show or its season/episode")
|
||||
return []
|
||||
raise
|
||||
|
||||
return subtitles
|
||||
|
||||
def download_subtitle(self, subtitle: GestdownSubtitle):
|
||||
response = self._session.get(subtitle.page_link, allow_redirects=True)
|
||||
response.raise_for_status()
|
||||
subtitle.content = response.content
|
@ -0,0 +1,77 @@
|
||||
import pytest
|
||||
|
||||
from subliminal_patch.providers.gestdown import GestdownProvider
|
||||
from subliminal_patch.providers.gestdown import GestdownSubtitle
|
||||
from subzero.language import Language
|
||||
|
||||
from subliminal_patch.language import PatchedAddic7edConverter
|
||||
|
||||
|
||||
def test_language_list_is_convertible():
|
||||
converter = PatchedAddic7edConverter()
|
||||
for language in GestdownProvider.languages:
|
||||
converter.convert(language.alpha3)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"episode_key,language,expected_any_release_info",
|
||||
[
|
||||
("breaking_bad_s01e01", Language.fromietf("en"), "BluRayREWARD"),
|
||||
("better_call_saul_s06e04", Language.fromietf("fr"), "AMZN-NTb"),
|
||||
],
|
||||
)
|
||||
def test_list_subtitles(episodes, episode_key, language, expected_any_release_info):
|
||||
with GestdownProvider() as provider:
|
||||
subtitles = provider.list_subtitles(episodes[episode_key], {language})
|
||||
assert any(
|
||||
subtitle.release_info == expected_any_release_info for subtitle in subtitles
|
||||
)
|
||||
|
||||
|
||||
def test_list_subtitles_hearing_impaired(episodes):
|
||||
with GestdownProvider() as provider:
|
||||
subtitles = provider.list_subtitles(
|
||||
episodes["better_call_saul_s06e04"], {Language.fromietf("en")}
|
||||
)
|
||||
assert not all(subtitle.hearing_impaired for subtitle in subtitles)
|
||||
assert any(subtitle.hearing_impaired for subtitle in subtitles)
|
||||
|
||||
|
||||
def test_list_subtitles_inexistent(episodes):
|
||||
with GestdownProvider() as provider:
|
||||
assert not provider.list_subtitles(
|
||||
episodes["inexistent"], {Language.fromietf("en")}
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def subtitle():
|
||||
return GestdownSubtitle(
|
||||
Language.fromietf("fr"),
|
||||
{
|
||||
"subtitleId": "d28b4d5b-7dcc-47b3-8232-fb02f081d135",
|
||||
"version": "480p.AMZN.WEB-DL.NTb",
|
||||
"hearingImpaired": False,
|
||||
"downloadUri": "/subtitles/download/d28b4d5b-7dcc-47b3-8232-fb02f081d135",
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def test_subtitle(subtitle):
|
||||
assert subtitle.language == Language.fromietf("fr")
|
||||
assert subtitle.id == "d28b4d5b-7dcc-47b3-8232-fb02f081d135"
|
||||
assert subtitle.hearing_impaired == False
|
||||
|
||||
|
||||
def test_subtitle_get_matches(subtitle, episodes):
|
||||
matches = subtitle.get_matches(episodes["better_call_saul_s06e04"])
|
||||
|
||||
assert matches.issuperset(("series", "title", "season", "episode", "source"))
|
||||
assert "resolution" not in matches
|
||||
|
||||
|
||||
def test_subtitle_download(subtitle):
|
||||
with GestdownProvider() as provider:
|
||||
provider.download_subtitle(subtitle)
|
||||
assert subtitle.content is not None
|
||||
assert subtitle.is_valid()
|
Loading…
Reference in new issue