forked from FairTrade/unshackle-services
Fixed title bug on KOWP
This commit is contained in:
parent
28e5dcf395
commit
97c4ded708
122
KOWP/__init__.py
122
KOWP/__init__.py
@ -13,7 +13,7 @@ from unshackle.core.service import Service
|
|||||||
from unshackle.core.search_result import SearchResult
|
from unshackle.core.search_result import SearchResult
|
||||||
from unshackle.core.titles import Episode, Series, Title_T, Titles_T
|
from unshackle.core.titles import Episode, Series, Title_T, Titles_T
|
||||||
from unshackle.core.tracks import Subtitle, Tracks
|
from unshackle.core.tracks import Subtitle, Tracks
|
||||||
|
from unshackle.core.utilities import is_close_match
|
||||||
|
|
||||||
class KOWP(Service):
|
class KOWP(Service):
|
||||||
"""
|
"""
|
||||||
@ -22,14 +22,10 @@ class KOWP(Service):
|
|||||||
|
|
||||||
Auth: Credential (username + password)
|
Auth: Credential (username + password)
|
||||||
Security: FHD@L3
|
Security: FHD@L3
|
||||||
|
|
||||||
Note:
|
|
||||||
Brightcove account_id and policy key (pk) are configurable per region.
|
|
||||||
Put the custom Brightcove account ID and policy key on the config.yaml if the following doesn't work
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
TITLE_RE = r"^(?:https?://(?:www\.)?kocowa\.com/[^/]+/season/)?(?P<title_id>\d+)"
|
TITLE_RE = r"^(?:https?://(?:www\.)?kocowa\.com/[^/]+/season/)?(?P<title_id>\d+)"
|
||||||
GEOFENCE = ("US", "CA", "PA")
|
GEOFENCE = ()
|
||||||
NO_SUBTITLES = False
|
NO_SUBTITLES = False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -43,9 +39,10 @@ class KOWP(Service):
|
|||||||
def __init__(self, ctx, title: str, extras: bool = False):
|
def __init__(self, ctx, title: str, extras: bool = False):
|
||||||
super().__init__(ctx)
|
super().__init__(ctx)
|
||||||
match = re.match(self.TITLE_RE, title)
|
match = re.match(self.TITLE_RE, title)
|
||||||
if not match:
|
if match:
|
||||||
raise ValueError("Invalid Kocowa title ID or URL")
|
|
||||||
self.title_id = match.group("title_id")
|
self.title_id = match.group("title_id")
|
||||||
|
else:
|
||||||
|
self.title_id = title # fallback to use as search keyword
|
||||||
self.include_extras = extras
|
self.include_extras = extras
|
||||||
self.brightcove_account_id = None
|
self.brightcove_account_id = None
|
||||||
self.brightcove_pk = None
|
self.brightcove_pk = None
|
||||||
@ -118,6 +115,7 @@ class KOWP(Service):
|
|||||||
all_episodes = []
|
all_episodes = []
|
||||||
offset = 0
|
offset = 0
|
||||||
limit = 20
|
limit = 20
|
||||||
|
series_title = None # Store the title from the first request
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
url = self.config["endpoints"]["metadata"].format(title_id=self.title_id)
|
url = self.config["endpoints"]["metadata"].format(title_id=self.title_id)
|
||||||
@ -131,6 +129,10 @@ class KOWP(Service):
|
|||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
data = r.json()["object"]
|
data = r.json()["object"]
|
||||||
|
|
||||||
|
# Extract the series title only from the very first page
|
||||||
|
if series_title is None and "meta" in data:
|
||||||
|
series_title = data["meta"]["title"]["en"]
|
||||||
|
|
||||||
page_objects = data.get("next_episodes", {}).get("objects", [])
|
page_objects = data.get("next_episodes", {}).get("objects", [])
|
||||||
if not page_objects:
|
if not page_objects:
|
||||||
break
|
break
|
||||||
@ -146,9 +148,11 @@ class KOWP(Service):
|
|||||||
if len(all_episodes) >= total or len(page_objects) < limit:
|
if len(all_episodes) >= total or len(page_objects) < limit:
|
||||||
break
|
break
|
||||||
|
|
||||||
episodes = []
|
# If we never got the series title, exit with an error
|
||||||
series_title = data["meta"]["title"].get("en") or "Unknown"
|
if series_title is None:
|
||||||
|
raise ValueError("Could not retrieve series metadata to get the title.")
|
||||||
|
|
||||||
|
episodes = []
|
||||||
for ep in all_episodes:
|
for ep in all_episodes:
|
||||||
meta = ep["meta"]
|
meta = ep["meta"]
|
||||||
ep_type = "Episode" if ep["detail_type"] == "episode" else ep["detail_type"].capitalize()
|
ep_type = "Episode" if ep["detail_type"] == "episode" else ep["detail_type"].capitalize()
|
||||||
@ -215,20 +219,20 @@ class KOWP(Service):
|
|||||||
self.widevine_license_url = widevine_url
|
self.widevine_license_url = widevine_url
|
||||||
tracks = DASH.from_url(dash_url, session=self.session).to_tracks(language=title.language)
|
tracks = DASH.from_url(dash_url, session=self.session).to_tracks(language=title.language)
|
||||||
|
|
||||||
# Add ALL subtitles from manifest
|
|
||||||
for sub in manifest.get("text_tracks", []):
|
for sub in manifest.get("text_tracks", []):
|
||||||
srclang = sub.get("srclang")
|
srclang = sub.get("srclang")
|
||||||
if not srclang or srclang == "thumbnails":
|
if not srclang or srclang == "thumbnails":
|
||||||
continue
|
continue
|
||||||
tracks.add(
|
|
||||||
Subtitle(
|
subtitle_track = Subtitle(
|
||||||
id_=sub["id"],
|
id_=sub["id"],
|
||||||
url=sub["src"],
|
url=sub["src"],
|
||||||
codec=Subtitle.Codec.WebVTT,
|
codec=Subtitle.Codec.WebVTT,
|
||||||
language=Language.get(srclang),
|
language=Language.get(srclang),
|
||||||
sdh=True,
|
sdh=True, # Kocowa subs are SDH - mark them as such
|
||||||
)
|
forced=False,
|
||||||
)
|
)
|
||||||
|
tracks.add(subtitle_track)
|
||||||
|
|
||||||
return tracks
|
return tracks
|
||||||
|
|
||||||
@ -246,52 +250,48 @@ class KOWP(Service):
|
|||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
return r.content
|
return r.content
|
||||||
|
|
||||||
# def search(self) -> List[SearchResult]:
|
def search(self) -> List[SearchResult]:
|
||||||
# if not hasattr(self, 'title_id') or not isinstance(self.title_id, str):
|
url = "https://prod-fms.kocowa.com/api/v01/fe/gks/autocomplete"
|
||||||
# query = getattr(self, 'title', '') # fallback if title_id isn't set yet
|
params = {
|
||||||
# else:
|
"search_category": "All",
|
||||||
# query = self.title_id
|
"search_input": self.title_id,
|
||||||
#
|
"include_webtoon": "true",
|
||||||
# url = "https://prod-fms.kocowa.com/api/v01/fe/gks/autocomplete"
|
}
|
||||||
# params = {
|
|
||||||
# "search_category": "All",
|
r = self.session.get(
|
||||||
# "search_input": query,
|
url,
|
||||||
# "include_webtoon": "true",
|
params=params,
|
||||||
# }
|
headers={
|
||||||
#
|
"Authorization": self.access_token,
|
||||||
# r = self.session.get(
|
"Origin": "https://www.kocowa.com ",
|
||||||
# url,
|
"Referer": "https://www.kocowa.com/ ",
|
||||||
# params=params,
|
}
|
||||||
# headers={
|
)
|
||||||
# "Authorization": self.access_token,
|
r.raise_for_status()
|
||||||
# "Origin": "https://www.kocowa.com ",
|
response = r.json()
|
||||||
# "Referer": "https://www.kocowa.com/ ",
|
contents = response.get("object", {}).get("contents", [])
|
||||||
# }
|
|
||||||
# )
|
results = []
|
||||||
# r.raise_for_status()
|
for item in contents:
|
||||||
# response = r.json()
|
if item.get("detail_type") != "season":
|
||||||
# contents = response.get("object", {}).get("contents", [])
|
continue
|
||||||
#
|
|
||||||
# results = []
|
meta = item["meta"]
|
||||||
# for item in contents:
|
title_en = meta["title"].get("en") or "[No Title]"
|
||||||
# if item.get("detail_type") != "season":
|
description_en = meta["description"].get("en") or ""
|
||||||
# continue # skip non-season items (e.g., actors, webtoons)
|
show_id = str(item["id"])
|
||||||
#
|
|
||||||
# meta = item["meta"]
|
results.append(
|
||||||
# title_en = meta["title"].get("en") or "[No Title]"
|
SearchResult(
|
||||||
# description_en = meta["description"].get("en") or ""
|
id_=show_id,
|
||||||
# show_id = str(item["id"])
|
title=title_en,
|
||||||
#
|
description=description_en,
|
||||||
# results.append(
|
label="season",
|
||||||
# SearchResult(
|
url=f"https://www.kocowa.com/en_us/season/{show_id}/"
|
||||||
# id_=show_id,
|
)
|
||||||
# title=title_en,
|
)
|
||||||
# description=description_en,
|
return results
|
||||||
# label="season",
|
|
||||||
# url=f"https://www.kocowa.com/en_us/season/{show_id}/placeholder"
|
|
||||||
# )
|
|
||||||
# )
|
|
||||||
# return results
|
|
||||||
|
|
||||||
def get_chapters(self, title: Title_T) -> list:
|
def get_chapters(self, title: Title_T) -> list:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user