diff --git a/GenshinImpactNewsBridge.php b/GenshinImpactNewsBridge.php new file mode 100644 index 0000000..e4b5ad3 --- /dev/null +++ b/GenshinImpactNewsBridge.php @@ -0,0 +1,101 @@ + array( + 'name' => 'Language', + 'type' => 'list', + 'values' => array( + 'English' => 'en-us', + '繁體中文' => 'zh-tw', + '한국어' => 'ko-kr', + '日本語' => 'ja-jp', + 'Français' => 'fr-fr', + 'Deutsch' => 'de-de', + 'Português' => 'pt-pt', + 'Español' => 'es-es', + 'Русский' => 'ru-ru', + 'Bahasa Indonesia' => 'id-id', + 'Tiếng Việt' => 'vi-vn', + 'ไทย' => 'th-th', + ), + 'required' => true + ), + 'limit' => array( + 'name' => 'Limit', + 'type' => 'number', + 'required' => false, + 'defaultValue' => 10 + ) + ) + ); + + private $pageUrl = self::URI; + + public function getURI() + { + return $this->pageUrl; + } + + public function collectData() + { + // Eingaben prüfen + $lang = $this->getInput('lang'); + if (empty($lang)) { + returnClientError('Ungültige Sprache: ' . $lang); + } + $limit = $this->getInput('limit'); + if (empty($limit)) { + $limit = 10; + } + + // Neue API-URL zusammenbauen + $query = http_build_query([ + 'iAppId' => 32, + 'iChanId' => 395, // Standard-News-Kanal, ggf. anpassbar + 'iPageSize' => $limit, + 'iPage' => 1, + 'sLangKey' => $lang + ]); + $jsonUrl = self::URI . '?' . $query; + $json = getContents($jsonUrl) + or returnServerError('Konnte die Genshin-News nicht abrufen.'); + $data = json_decode($json); + if (!isset($data->data->list)) { + returnServerError('Ungültige Antwortstruktur.'); + } + + $this->pageUrl = 'https://genshin.hoyoverse.com/' . $lang . '/news'; + + foreach ($data->data->list as $element) { + $article_title = $element->sTitle; + $article_uid = $element->iInfoId; + $article_uri = $this->pageUrl . '/detail/' . $article_uid; + $article_timestamp = strtotime($element->dtStartTime); + $article_content = $element->sIntro; + + $item = array(); + $item['uri'] = $article_uri; + $item['title'] = $article_title; + $item['timestamp'] = $article_timestamp; + $item['content'] = $article_content; + + // Thumbnail aus sExt->banner + if (!empty($element->sExt)) { + $ext = json_decode($element->sExt); + if (isset($ext->banner) && is_array($ext->banner) && isset($ext->banner[0]->url)) { + $item['enclosures'] = array($ext->banner[0]->url); + } + } + + $this->items[] = $item; + } + } +} diff --git a/HolonometriaMangaBridge.php b/HolonometriaMangaBridge.php new file mode 100644 index 0000000..6275188 --- /dev/null +++ b/HolonometriaMangaBridge.php @@ -0,0 +1,75 @@ + [ + 'name' => 'Manga', + 'type' => 'list', + 'values' => [ + 'Vesta de Cooking' => 'vestadecooking', + 'Underworld Academy Overload!!' => 'soreyukemakaigakko', + 'Yamato Phantasia' => 'yamatokasoukaiitan', + ] + ], + ], + ]; + + public function getIcon() + { + return 'https://holoearth.com/assets/img/favicon_holonometria.ico'; + } + + public function collectData() + { + $manga = $this->getInput('manga'); + $pageUrl = self::URI . $manga . '/'; + $html = getSimpleHTMLDOM($pageUrl) + or returnServerError('Konnte die Webseite nicht laden: ' . $pageUrl); + + $items = []; + foreach ($html->find('ul.manga-detail__list li.manga-detail__list-item') as $element) { + $a = $element->find('a.manga-detail__list-link', 0); + if (!$a) continue; + $item = []; + $item['uri'] = $a->href; + $title = $a->find('p.manga-detail__list-title', 0); + $date = $a->find('p.manga-detail__list-date', 0); + $timestamp = null; + $date_str = ''; + if ($date) { + $date_raw = trim(strip_tags($date->innertext)); + if (preg_match('/^(\d{4})\.(\d{2})\.(\d{2})$/', $date_raw, $m)) { + $timestamp = mktime(0, 0, 0, $m[2], $m[3], $m[1]); + } else { + $timestamp = strtotime($date_raw); + } + if ($timestamp && $timestamp > 0) { + $date_str = ' (' . date('d.m.Y', $timestamp) . ')'; + $item['timestamp'] = $timestamp; + } + } + $item['title'] = ($title ? trim(strip_tags($title->innertext)) : 'Kapitel') . $date_str; + $thumb = $a->find('p.manga-detail__list-thumb img', 0); + if ($thumb) { + $item['enclosures'] = [$thumb->src]; + $item['content'] = ''; + } + $item['uid'] = $item['uri']; + $items[] = $item; + } + // Nach Datum absteigend sortieren (neustes zuerst, ohne 0-Timestamps) + usort($items, function($a, $b) { + $at = isset($a['timestamp']) ? $a['timestamp'] : 0; + $bt = isset($b['timestamp']) ? $b['timestamp'] : 0; + return $bt <=> $at; + }); + $this->items = array_slice($items, 0, 15); + } +} diff --git a/PokemonGOBridge.php b/PokemonGOBridge.php new file mode 100644 index 0000000..3d892fa --- /dev/null +++ b/PokemonGOBridge.php @@ -0,0 +1,94 @@ + array( + 'name' => 'Language', + 'type' => 'list', + 'values' => array( + 'English' => 'en', + '繁體中文' => 'zh_hant', + 'Français' => 'fr', + 'Deutsch' => 'de', + 'Italiano' => 'it', + '日本語' => 'ja', + '한국어' => 'ko', + 'Português' => 'pt_br', + 'Español' => 'es', + 'Español (México)' => 'es_mx', + 'Polski' => 'pl', + 'Русский' => 'ru', + 'हिन्दी' => 'hi', + 'Bahasa Indonesia' => 'id', + 'ไทย' => 'th', + 'Türkçe' => 'tr', + ), + 'defaultValue' => 'en' + ) + ) + ); + + public function getIcon(){ + return 'https://pokemongo.com/img/icons/favicon.ico'; + } + + public function collectData() { + $lang = $this->getInput('lang'); + $pageUrl = self::URI . $lang . '/news'; + $html = getSimpleHTMLDOM($pageUrl) + or returnServerError('Konnte die Webseite nicht laden: ' . $pageUrl); + + // Finde alle News-Karten + foreach($html->find('a._newsCard_119ao_16') as $element) { + if(count($this->items) >= 10) break; + + // Titel + $contentDiv = $element->find('div._newsCardContent_119ao_59', 0); + $title = ''; + if ($contentDiv) { + $titleDiv = $contentDiv->find('div', 1); // Das zweite
ist der Titel + if ($titleDiv) { + $title = trim($titleDiv->plaintext); + } + } + + // Link + $href = $element->href; + if(strpos($href, 'http') !== 0) { + $uri = rtrim(self::URI, '/') . $href; + } else { + $uri = $href; + } + + // Datum + $dateElement = $element->find('pg-date-format', 0); + $timestamp = null; + if ($dateElement && isset($dateElement->timestamp)) { + $timestamp = intval($dateElement->timestamp / 1000); // JS ms -> s + } + + // Bild + $imgElement = $element->find('img', 0); + $imgHtml = ''; + if ($imgElement && isset($imgElement->src)) { + $imgHtml = ''; + } + + // Content (nur Bild, da kein Teasertext im Listing) + $content = $imgHtml; + + $item = array(); + $item['uri'] = $uri; + $item['title'] = $title; + if ($timestamp) $item['timestamp'] = $timestamp; + $item['content'] = $content; + $this->items[] = $item; + } + } +}