Added geoblocking error on KNPY

This commit is contained in:
FairTrade 2025-11-26 15:13:19 +01:00
parent 4513b1c0d4
commit 630b2e1099

View File

@ -269,29 +269,38 @@ class KNPY(Service):
"visitorId": self._visitor_id
}
if "authorization" not in self.session.headers:
self.session.headers["authorization"] = f"Bearer {self._jwt}"
self.session.headers["x-version"] = self.API_VERSION
self.session.headers["user-agent"] = self.USER_AGENT
self.session.headers.setdefault("authorization", f"Bearer {self._jwt}")
self.session.headers.setdefault("x-version", self.API_VERSION)
self.session.headers.setdefault("user-agent", self.USER_AGENT)
r = self.session.post(
self.config["endpoints"]["plays"],
json=play_payload,
)
r = self.session.post(self.config["endpoints"]["plays"], json=play_payload)
response_json = None
try:
response_json = r.json()
except Exception:
pass
# Handle known errors gracefully
if r.status_code == 403:
if response_json and response_json.get("errorSubcode") == "playRegionRestricted":
self.log.error("Kanopy reports: This video is not available in your country.")
raise PermissionError(
"Playback blocked by region restriction. Try connecting through a supported country or verify your librarys access region."
)
else:
self.log.error(f"Access forbidden (HTTP 403). Response: {response_json}")
raise PermissionError("Kanopy denied access to this video. It may require a different library membership or authentication.")
# Raise for any other HTTP errors
r.raise_for_status()
play_data = r.json()
play_data = response_json or r.json()
manifest_url = None
for manifest in play_data.get("manifests", []):
if manifest["manifestType"] == "dash":
manifest_relative_url = manifest["url"]
if manifest_relative_url.startswith("/"):
manifest_url = f"https://kanopy.com{manifest_relative_url}"
else:
manifest_url = manifest_relative_url
url = manifest["url"]
manifest_url = f"https://kanopy.com{url}" if url.startswith("/") else url
drm_type = manifest.get("drmType")
if drm_type == "kanopyDrm":
play_id = play_data.get("playId")
self.widevine_license_url = self.config["endpoints"]["widevine_license"].format(license_id=f"{play_id}-0")
@ -311,7 +320,8 @@ class KNPY(Service):
self.log.info(f"Fetching DASH manifest from: {manifest_url}")
r = self.session.get(manifest_url)
r.raise_for_status()
# Refresh headers for manifest parsing
self.session.headers.clear()
self.session.headers.update({
"User-Agent": self.WIDEVINE_UA,
@ -319,23 +329,23 @@ class KNPY(Service):
"Accept-Encoding": "gzip, deflate",
"Connection": "keep-alive",
})
tracks = DASH.from_text(r.text, url=manifest_url).to_tracks(language=title.language)
for caption_data in play_data.get("captions", []):
lang_code = caption_data.get("language", "en")
lang = caption_data.get("language", "en")
for file_info in caption_data.get("files", []):
if file_info.get("type") == "webvtt":
tracks.add(Subtitle(
id_=f"caption-{lang_code}",
id_=f"caption-{lang}",
url=file_info["url"],
codec=Subtitle.Codec.WebVTT,
language=Language.get(lang_code)
language=Language.get(lang)
))
break
return tracks
def get_widevine_license(self, *, challenge: bytes, title: Title_T, track: AnyTrack) -> bytes:
if not self.widevine_license_url:
raise ValueError("Widevine license URL was not set. Call get_tracks first.")
@ -394,4 +404,4 @@ class KNPY(Service):
# return results
def get_chapters(self, title: Title_T) -> list:
return []
return []