diff --git a/DMAXBridge.php b/DMAXBridge.php index 7ee1b56..7a49b4c 100644 --- a/DMAXBridge.php +++ b/DMAXBridge.php @@ -2,114 +2,133 @@ class DMAXBridge extends BridgeAbstract { + const NAME = 'DMAX, HGTV, TLC Bridge'; + const URI = ''; + const API_URI = 'https://de-api.loma-cms.com/feloma/videos/'; + const DESCRIPTION = 'Gibt die neuesten Episoden einer DMAX, HGTV oder TLC Sendung zurück.'; + const MAINTAINER = 'Brawl, Akamaru'; - const MAINTAINER = 'Brawl'; - const NAME = 'DMAX'; - const URI = 'https://www.dmax.de/'; - const CACHE_TIMEOUT = 7200; // 7200 = 2h - const DESCRIPTION = 'Returns the newest episode of a DMAX show.'; - const PARAMETERS = array( - array( - 'show' => array( - 'name' => 'Show ID (e.g. "6023" for Steel Buddies, check website source code)', - 'type' => 'number', + const PARAMETERS = [ + 'Sendung' => [ + 'show' => [ + 'name' => 'Sendungs-Slug (z.B. "112-feuerwehr-im-einsatz")', + 'type' => 'text', 'required' => true - ), - ) - ); - const TOKEN_URI = 'https://eu1-prod.disco-api.com/token?realm=dmaxde'; - const DISCO_URI = 'https://eu1-prod.disco-api.com/content/videos//?include=primaryChannel,primaryChannel.images,show,show.images,genres,tags,images,contentPackages&sort=-seasonNumber,-episodeNumber&filter[show.id]=%d&filter[videoType]=EPISODE&page[number]=1&page[size]=100'; + ], + 'realm' => [ + 'name' => 'Plattform', + 'type' => 'list', + 'values' => [ + 'DMAX' => 'dmax', + 'HGTV' => 'hgtv', + 'TLC' => 'tlc' + ], + 'defaultValue' => 'dmax' + ] + ] + ]; + + const PLATFORM_URLS = [ + 'dmax' => 'https://www.dmax.de/', + 'hgtv' => 'https://de.hgtv.com/', + 'tlc' => 'https://tlc.de/' + ]; + + const PLATFORM_NAMES = [ + 'dmax' => 'DMAX', + 'hgtv' => 'HGTV', + 'tlc' => 'TLC' + ]; private $showName = ''; - private $pageUrl = self::URI . 'sendungen/'; - public function getName() - { + public function getName() { if (!empty($this->showName)) { return $this->showName; } - return parent::getName(); } - public function getIcon() - { - return self::URI . 'apple-touch-icon.png'; - } - - public function getURI() - { - return $this->pageUrl; - } - - public function collectData() - { - // Retrieve and check user input + public function collectData() { $show = $this->getInput('show'); - if (empty($show)) - returnClientError('Invalid show: ' . $show); + $realm = $this->getInput('realm'); - // Get Token - $tokenUrl = getSimpleHTMLDOM(self::TOKEN_URI) - or returnServerError('Could not request DMAX token.'); - - $token_json = json_decode($tokenUrl, true); - $token = $token_json['data']['attributes']['token']; - if (empty($token)) - returnServerError('Could not get DMAX token.'); - - // Retrieve discovery URI - $pageUrl = sprintf(self::DISCO_URI, $show); - $html = getSimpleHTMLDOM($pageUrl, array('Authorization: Bearer ' . $token)) - or returnServerError('Could not request DMAX discovery URI: ' . $pageUrl); - $json = json_decode($html, true); - - // Get show name - foreach ($json["included"] as $incl_element) { - if ($incl_element["type"] == "show") { - $this->showName = $incl_element['attributes']['name']; - $this->pageUrl = self::URI . 'sendungen/' . $incl_element['attributes']['alternateId']; - } + if (empty($show)) { + returnClientError('Ungültiger Sendungs-Slug.'); } - if (empty($this->showName)) - returnClientError('Show not found.'); + $apiUrl = self::API_URI . '?environment=' . $realm . '&v=2&filter[show.slug]=' . urlencode($show); + $json = json_decode(getContents($apiUrl), true); - // Process articles - foreach ($json['data'] as $element) { - - if (count($this->items) >= 10) { - break; - } - - $episodeTitle = trim($element['attributes']['name']); - if (array_key_exists('episodeNumber', $element['attributes']) // Both season + episode no. given - && array_key_exists('seasonNumber', $element['attributes'])) { - $article_title = sprintf($this->showName . ' S%02dE%02d: ' . $episodeTitle, - $element['attributes']['seasonNumber'], - $element['attributes']['episodeNumber']); - } elseif (array_key_exists('episodeNumber', $element['attributes']) // Only season no. given - && !array_key_exists('seasonNumber', $element['attributes'])) { - $article_title = sprintf($this->showName . ' E%02d: ' . $episodeTitle, - $element['attributes']['episodeNumber']); - } else { // Nothing given - $article_title = $this->showName . ' - ' . $episodeTitle; - } - $article_content = trim($element['attributes']['description']); - - $article_time = $element['attributes']['airDate']; - - // Store article in items array - if (!empty($article_title)) { - $item = array(); - $item['uri'] = $this->pageUrl . '/videos'; - $item['title'] = $article_title; - $item['enclosures'] = array(); - $item['content'] = $article_content; - $item['timestamp'] = $article_time; - $item['uid'] = $article_title; - $this->items[] = $item; - } + if (!$json) { + returnServerError('Keine Daten von der API erhalten.'); } + + // Extrahiere den Sendungsnamen aus dem JSON + $this->showName = $json['title'] ?? ''; + + // Die Episoden befinden sich in blocks[1]['items'] + if (!isset($json['blocks'][1]['items']) || !is_array($json['blocks'][1]['items'])) { + returnServerError('Keine Episoden gefunden.'); + } + + foreach ($json['blocks'][1]['items'] as $element) { + $item = []; + + // Erstelle den Episodentitel + $episodeTitle = $element['title'] ?? ''; + if (isset($element['seasonNumber']) && isset($element['episodeNumber'])) { + $item['title'] = sprintf( + '%s S%02dE%02d %s', + $this->showName, + $element['seasonNumber'], + $element['episodeNumber'], + $episodeTitle + ); + } else { + $item['title'] = sprintf('%s %s', $this->showName, $episodeTitle); + } + + // Setze die Beschreibung + $item['content'] = $element['description'] ?? ''; + + // Erstelle die Episode-URL + $episodeSlug = $element['alternateId'] ?? ''; + $item['uri'] = self::PLATFORM_URLS[$realm] . 'sendungen/' . $show . '/' . $episodeSlug; + + // Setze das Veröffentlichungsdatum + if (isset($element['publishStart'])) { + $item['timestamp'] = strtotime($element['publishStart']); + } + + // Setze die eindeutige ID + $item['uid'] = $element['id'] ?? ''; + + // Füge das Vorschaubild hinzu, falls vorhanden + if (isset($element['poster']['src'])) { + $item['enclosures'] = [$element['poster']['src']]; + } + + // Setze den Sender als Autor + $item['author'] = self::PLATFORM_NAMES[$realm]; + + $this->items[] = $item; + } + } + + public function getIcon() { + $realm = $this->getInput('realm'); + return self::PLATFORM_URLS[$realm] . 'favicon.ico'; + } + + public function getURI() { + $realm = $this->getInput('realm'); + $show = $this->getInput('show'); + + if (empty($show)) { + return self::PLATFORM_URLS[$realm]; + } + + return self::PLATFORM_URLS[$realm] . 'sendungen/' . $show; } }