mirror of
https://github.com/morpheus65535/bazarr
synced 2024-12-27 10:07:22 +00:00
parent
0e01c64079
commit
57f8973be2
1 changed files with 101 additions and 79 deletions
|
@ -52,9 +52,13 @@ class KtuvitSubtitle(Subtitle):
|
||||||
self.release = release
|
self.release = release
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<%s [%s] %r [%s:%s]>' % (
|
return "<%s [%s] %r [%s:%s]>" % (
|
||||||
self.__class__.__name__, self.subtitle_id, self.page_link, self.language, self._guessed_encoding)
|
self.__class__.__name__,
|
||||||
|
self.subtitle_id,
|
||||||
|
self.page_link,
|
||||||
|
self.language,
|
||||||
|
self._guessed_encoding,
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def id(self):
|
def id(self):
|
||||||
|
@ -125,7 +129,7 @@ class KtuvitProvider(Provider):
|
||||||
self.hashed_password = hashed_password
|
self.hashed_password = hashed_password
|
||||||
self.logged_in = False
|
self.logged_in = False
|
||||||
self.session = None
|
self.session = None
|
||||||
self.loginCookie = None
|
self.login_cookie = None
|
||||||
|
|
||||||
def initialize(self):
|
def initialize(self):
|
||||||
self.session = Session()
|
self.session = Session()
|
||||||
|
@ -135,13 +139,15 @@ class KtuvitProvider(Provider):
|
||||||
logger.info("Logging in")
|
logger.info("Logging in")
|
||||||
|
|
||||||
data = {"request": {"Email": self.email, "Password": self.hashed_password}}
|
data = {"request": {"Email": self.email, "Password": self.hashed_password}}
|
||||||
|
|
||||||
self.session.headers['Accept-Encoding'] = 'gzip'
|
self.session.headers["Accept-Encoding"] = "gzip"
|
||||||
self.session.headers['Accept-Language'] = 'en-us,en;q=0.5'
|
self.session.headers["Accept-Language"] = "en-us,en;q=0.5"
|
||||||
self.session.headers['Pragma'] = 'no-cache'
|
self.session.headers["Pragma"] = "no-cache"
|
||||||
self.session.headers['Cache-Control'] = 'no-cache'
|
self.session.headers["Cache-Control"] = "no-cache"
|
||||||
self.session.headers['Content-Type'] = 'application/json'
|
self.session.headers["Content-Type"] = "application/json"
|
||||||
self.session.headers['User-Agent']: os.environ.get("SZ_USER_AGENT", "Sub-Zero/2")
|
self.session.headers["User-Agent"]: os.environ.get(
|
||||||
|
"SZ_USER_AGENT", "Sub-Zero/2"
|
||||||
|
)
|
||||||
|
|
||||||
r = self.session.post(
|
r = self.session.post(
|
||||||
self.server_url + self.sign_in_url,
|
self.server_url + self.sign_in_url,
|
||||||
|
@ -149,31 +155,38 @@ class KtuvitProvider(Provider):
|
||||||
allow_redirects=False,
|
allow_redirects=False,
|
||||||
timeout=10,
|
timeout=10,
|
||||||
)
|
)
|
||||||
|
|
||||||
if r.content:
|
|
||||||
try:
|
|
||||||
responseContent = r.json()
|
|
||||||
except json.decoder.JSONDecodeError:
|
|
||||||
AuthenticationError("Unable to parse JSON return while authenticating to the provider.")
|
|
||||||
else:
|
|
||||||
isSuccess = False
|
|
||||||
if 'd' in responseContent:
|
|
||||||
responseContent = json.loads(responseContent['d'])
|
|
||||||
isSuccess = responseContent.get('IsSuccess', False)
|
|
||||||
if not isSuccess:
|
|
||||||
AuthenticationError("ErrorMessage: " + responseContent['d'].get("ErrorMessage", "[None]"))
|
|
||||||
else:
|
|
||||||
AuthenticationError("Incomplete JSON returned while authenticating to the provider.")
|
|
||||||
|
|
||||||
cookieSplit = r.headers["set-cookie"].split("Login=")
|
if r.content:
|
||||||
if len(cookieSplit) != 2:
|
is_success = False
|
||||||
self.logged_in = False
|
try:
|
||||||
AuthenticationError("Login Failed, didn't receive valid cookie in response")
|
is_success = self.parse_d_response(
|
||||||
|
r, "IsSuccess", False, "Authentication to the provider"
|
||||||
self.loginCookie = cookieSplit[1].split(";")[0]
|
)
|
||||||
logger.debug("Logged in with cookie: " + self.loginCookie)
|
except json.decoder.JSONDecodeError:
|
||||||
|
logger.info("Failed to Login to Ktuvit")
|
||||||
self.logged_in = True
|
if not is_success:
|
||||||
|
error_message = ''
|
||||||
|
try:
|
||||||
|
error_message = self.parse_d_response(r, "ErrorMessage", "[None]")
|
||||||
|
except json.decode.JSONDecoderError:
|
||||||
|
raise AuthenticationError(
|
||||||
|
"Error Logging in to Ktuvit Provider: " + str(r.content)
|
||||||
|
)
|
||||||
|
raise AuthenticationError(
|
||||||
|
"Error Logging in to Ktuvit Provider: " + error_message
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
cookie_split = r.headers["set-cookie"].split("Login=")
|
||||||
|
if len(cookie_split) != 2:
|
||||||
|
self.logged_in = False
|
||||||
|
raise AuthenticationError(
|
||||||
|
"Login Failed, didn't receive valid cookie in response"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.login_cookie = cookie_split[1].split(";")[0]
|
||||||
|
logger.debug("Logged in with cookie: " + self.login_cookie)
|
||||||
|
|
||||||
|
self.logged_in = True
|
||||||
|
|
||||||
def terminate(self):
|
def terminate(self):
|
||||||
self.session.close()
|
self.session.close()
|
||||||
|
@ -231,6 +244,10 @@ class KtuvitProvider(Provider):
|
||||||
def query(
|
def query(
|
||||||
self, title, season=None, episode=None, year=None, filename=None, imdb_id=None
|
self, title, season=None, episode=None, year=None, filename=None, imdb_id=None
|
||||||
):
|
):
|
||||||
|
if not self.logged_in:
|
||||||
|
logger.info("Not logged in to Ktuvit. Returning 0 results")
|
||||||
|
return {}
|
||||||
|
|
||||||
# search for the IMDB ID if needed.
|
# search for the IMDB ID if needed.
|
||||||
is_movie = not (season and episode)
|
is_movie = not (season and episode)
|
||||||
imdb_id = imdb_id or self._search_imdb_id(title, year, is_movie)
|
imdb_id = imdb_id or self._search_imdb_id(title, year, is_movie)
|
||||||
|
@ -265,33 +282,21 @@ class KtuvitProvider(Provider):
|
||||||
logger.debug("Getting the list of subtitles")
|
logger.debug("Getting the list of subtitles")
|
||||||
|
|
||||||
url = self.server_url + self.search_url
|
url = self.server_url + self.search_url
|
||||||
r = self.session.post(
|
r = self.session.post(url, json={"request": query}, timeout=10)
|
||||||
url, json={"request": query}, timeout=10
|
|
||||||
)
|
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
|
|
||||||
if r.content:
|
if r.content:
|
||||||
try:
|
results = self.parse_d_response(r, "Films", [], "Films/Series Information")
|
||||||
responseContent = r.json()
|
|
||||||
except json.decoder.JSONDecodeError:
|
|
||||||
json.decoder.JSONDecodeError("Unable to parse JSON returned while getting Film/Series Information.")
|
|
||||||
else:
|
|
||||||
isSuccess = False
|
|
||||||
if 'd' in responseContent:
|
|
||||||
responseContent = json.loads(responseContent['d'])
|
|
||||||
results = responseContent.get('Films', [])
|
|
||||||
else:
|
|
||||||
json.decoder.JSONDecodeError("Incomplete JSON returned while getting Film/Series Information.")
|
|
||||||
else:
|
else:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
# loop over results
|
# loop over results
|
||||||
subtitles = {}
|
subtitles = {}
|
||||||
for result in results:
|
for result in results:
|
||||||
imdb_link = result["IMDB_Link"]
|
imdb_link = result["IMDB_Link"]
|
||||||
imdb_link = imdb_link[0: -1] if imdb_link.endswith("/") else imdb_link
|
imdb_link = imdb_link[0:-1] if imdb_link.endswith("/") else imdb_link
|
||||||
results_imdb_id = imdb_link.split("/")[-1]
|
results_imdb_id = imdb_link.split("/")[-1]
|
||||||
|
|
||||||
if results_imdb_id != imdb_id:
|
if results_imdb_id != imdb_id:
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Subtitles is for IMDB %r but actual IMDB ID is %r",
|
"Subtitles is for IMDB %r but actual IMDB ID is %r",
|
||||||
|
@ -352,9 +357,11 @@ class KtuvitProvider(Provider):
|
||||||
|
|
||||||
for index, column in enumerate(columns):
|
for index, column in enumerate(columns):
|
||||||
if index == 0:
|
if index == 0:
|
||||||
sub['rls'] = column.get_text().strip().split("\n")[0]
|
sub["rls"] = column.get_text().strip().split("\n")[0]
|
||||||
if index == 5:
|
if index == 5:
|
||||||
sub['sub_id'] = column.find("input", attrs={"data-sub-id": True})["data-sub-id"]
|
sub["sub_id"] = column.find("input", attrs={"data-sub-id": True})[
|
||||||
|
"data-sub-id"
|
||||||
|
]
|
||||||
|
|
||||||
subs.append(sub)
|
subs.append(sub)
|
||||||
return subs
|
return subs
|
||||||
|
@ -370,14 +377,14 @@ class KtuvitProvider(Provider):
|
||||||
|
|
||||||
for row in sub_rows:
|
for row in sub_rows:
|
||||||
columns = row.find_all("td")
|
columns = row.find_all("td")
|
||||||
sub = {
|
sub = {"id": movie_id}
|
||||||
'id': movie_id
|
|
||||||
}
|
|
||||||
for index, column in enumerate(columns):
|
for index, column in enumerate(columns):
|
||||||
if index == 0:
|
if index == 0:
|
||||||
sub['rls'] = column.get_text().strip().split("\n")[0]
|
sub["rls"] = column.get_text().strip().split("\n")[0]
|
||||||
if index == 5:
|
if index == 5:
|
||||||
sub['sub_id'] = column.find("a", attrs={"data-subtitle-id": True})["data-subtitle-id"]
|
sub["sub_id"] = column.find("a", attrs={"data-subtitle-id": True})[
|
||||||
|
"data-subtitle-id"
|
||||||
|
]
|
||||||
|
|
||||||
subs.append(sub)
|
subs.append(sub)
|
||||||
return subs
|
return subs
|
||||||
|
@ -386,7 +393,6 @@ class KtuvitProvider(Provider):
|
||||||
season = episode = None
|
season = episode = None
|
||||||
year = video.year
|
year = video.year
|
||||||
filename = video.name
|
filename = video.name
|
||||||
imdb_id = video.imdb_id
|
|
||||||
|
|
||||||
if isinstance(video, Episode):
|
if isinstance(video, Episode):
|
||||||
titles = [video.series] + video.alternative_series
|
titles = [video.series] + video.alternative_series
|
||||||
|
@ -410,7 +416,7 @@ class KtuvitProvider(Provider):
|
||||||
|
|
||||||
def download_subtitle(self, subtitle):
|
def download_subtitle(self, subtitle):
|
||||||
if isinstance(subtitle, KtuvitSubtitle):
|
if isinstance(subtitle, KtuvitSubtitle):
|
||||||
downloadIdentifierRequest = {
|
download_identifier_request = {
|
||||||
"FilmID": subtitle.ktuvit_id,
|
"FilmID": subtitle.ktuvit_id,
|
||||||
"SubtitleID": subtitle.subtitle_id,
|
"SubtitleID": subtitle.subtitle_id,
|
||||||
"FontSize": 0,
|
"FontSize": 0,
|
||||||
|
@ -418,32 +424,22 @@ class KtuvitProvider(Provider):
|
||||||
"PredefinedLayout": -1,
|
"PredefinedLayout": -1,
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("Download Identifier Request data: " + str(json.dumps({"request": downloadIdentifierRequest})))
|
logger.debug(
|
||||||
|
"Download Identifier Request data: "
|
||||||
|
+ str(json.dumps({"request": download_identifier_request}))
|
||||||
|
)
|
||||||
|
|
||||||
# download
|
# download
|
||||||
url = self.server_url + self.request_download_id_url
|
url = self.server_url + self.request_download_id_url
|
||||||
r = self.session.post(
|
r = self.session.post(
|
||||||
url, json={"request": downloadIdentifierRequest}, timeout=10
|
url, json={"request": download_identifier_request}, timeout=10
|
||||||
)
|
)
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
|
|
||||||
if r.content:
|
if r.content:
|
||||||
try:
|
download_identifier = self.parse_d_response(r, "DownloadIdentifier")
|
||||||
responseContent = r.json()
|
|
||||||
except json.decoder.JSONDecodeError:
|
|
||||||
json.decoder.JSONDecodeError("Unable to parse JSON returned while getting Download Identifier.")
|
|
||||||
else:
|
|
||||||
isSuccess = False
|
|
||||||
if 'd' in responseContent:
|
|
||||||
responseContent = json.loads(responseContent['d'])
|
|
||||||
downloadIdentifier = responseContent.get('DownloadIdentifier', None)
|
|
||||||
|
|
||||||
if not downloadIdentifier:
|
url = self.server_url + self.download_link + download_identifier
|
||||||
json.decoder.JSONDecodeError("Missing Download Identifier.")
|
|
||||||
else:
|
|
||||||
json.decoder.JSONDecodeError("Incomplete JSON returned while getting Download Identifier.")
|
|
||||||
|
|
||||||
url = self.server_url + self.download_link + downloadIdentifier
|
|
||||||
|
|
||||||
r = self.session.get(url, timeout=10)
|
r = self.session.get(url, timeout=10)
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
|
@ -455,3 +451,29 @@ class KtuvitProvider(Provider):
|
||||||
return
|
return
|
||||||
|
|
||||||
subtitle.content = fix_line_ending(r.content)
|
subtitle.content = fix_line_ending(r.content)
|
||||||
|
|
||||||
|
def parse_d_response(self, response, field, default_value=None, message=None):
|
||||||
|
message = message if message else field
|
||||||
|
|
||||||
|
try:
|
||||||
|
response_content = response.json()
|
||||||
|
except json.decoder.JSONDecodeError as ex:
|
||||||
|
raise json.decoder.JSONDecodeError(
|
||||||
|
"Unable to parse JSON returned while getting " + message, ex.doc, ex.pos
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if "d" in response_content:
|
||||||
|
response_content = json.loads(response_content["d"])
|
||||||
|
value = response_content.get(field, default_value)
|
||||||
|
|
||||||
|
if not value:
|
||||||
|
raise json.decoder.JSONDecodeError(
|
||||||
|
"Missing " + message, str(response_content), 0
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise json.decoder.JSONDecodeError(
|
||||||
|
"Incomplete JSON returned while getting " + message,
|
||||||
|
str(response_content),
|
||||||
|
0
|
||||||
|
)
|
||||||
|
return value
|
||||||
|
|
Loading…
Reference in a new issue