diff --git a/JoynBridge.php b/JoynBridge.php new file mode 100644 index 0000000..a8675a6 --- /dev/null +++ b/JoynBridge.php @@ -0,0 +1,112 @@ + [ + 'name' => 'Serien-ID', + 'type' => 'text', + 'title' => 'ID der Serie (z.B. match-in-paradise)', + 'required' => true + ] + ] + ]; + + public function collectData() { + $series_id = $this->getInput('series_id'); + if (empty($series_id)) { + return; + } + + $url = 'https://www.joyn.de/serien/' . $series_id; + $html = getSimpleHTMLDOM($url); + + if (!$html) { + returnServerError('Could not load page'); + } + + $scriptTag = $html->find('script[id="__NEXT_DATA__"]', 0); + if (!$scriptTag) { + returnServerError('Could not find NEXT_DATA script tag'); + } + + $jsonData = json_decode($scriptTag->innertext, true); + if (!$jsonData) { + returnServerError('Could not parse JSON data'); + } + + $series = $jsonData['props']['pageProps']['initialData']['page']['series'] ?? null; + if (!$series) { + returnServerError('Could not find series data'); + } + + $episodeMap = []; + if (isset($series['freeSeasons'])) { + foreach ($series['freeSeasons'] as $season) { + if (isset($season['episodes'])) { + foreach ($season['episodes'] as $episode) { + $episode['seasonNumber'] = $season['number']; + $episode['__plus__'] = false; + $episodeMap[$episode['id']] = $episode; + } + } + } + } + // Joyn Plus (svodSeasons) ergänzen + if (isset($series['svodSeasons'])) { + foreach ($series['svodSeasons'] as $season) { + if (isset($season['episodes'])) { + foreach ($season['episodes'] as $episode) { + $episode['seasonNumber'] = $season['number']; + $episode['__plus__'] = true; + // Überschreibe ggf. free-Episode mit PLUS-Version + $episodeMap[$episode['id']] = $episode; + } + } + } + } + $allEpisodes = array_values($episodeMap); + // Sortiere nach Episodennummer absteigend (neueste zuerst) + usort($allEpisodes, function($a, $b) { + $seasonCompare = ($b['seasonNumber'] ?? 0) <=> ($a['seasonNumber'] ?? 0); + if ($seasonCompare !== 0) { + return $seasonCompare; + } + return ($b['number'] ?? 0) <=> ($a['number'] ?? 0); + }); + foreach ($allEpisodes as $episode) { + $seasonNumber = $episode['seasonNumber'] ?? 1; + $episodeNumber = $episode['number'] ?? 1; + $title = $episode['title'] ?? ''; + $airdate = $episode['airdate'] ?? null; + $path = $episode['path'] ?? ''; + $primaryImage = $episode['primaryImage']['url'] ?? ''; + $isPlus = !empty($episode['__plus__']); + $item = []; + $item['title'] = sprintf('%sS%02dE%02d "%s"', $isPlus ? '[Joyn PLUS+] ' : '', $seasonNumber, $episodeNumber, $title); + $item['content'] = '

Neue Folge verfügbar'; + if ($isPlus) { + $item['content'] .= ' Joyn PLUS+ (Abo benötigt)'; + } + $item['content'] .= '

'; + if ($primaryImage) { + $item['content'] .= '

' . htmlspecialchars($title) . '

'; + $item['enclosures'] = [$primaryImage]; + } + if ($airdate) { + $item['timestamp'] = $airdate; + } + if ($path) { + $item['uri'] = 'https://www.joyn.de' . $path; + } else { + $item['uri'] = $url; + } + $this->items[] = $item; + } + } +} \ No newline at end of file