From 04eb703d03cc1c730193484cfe11252dea8dd2d5 Mon Sep 17 00:00:00 2001 From: Akamaru Date: Wed, 26 Nov 2025 20:55:47 +0100 Subject: [PATCH] Neu: Arknights: Endfield News Bridge --- ArknightsEndfieldBridge.php | 171 ++++++++++++++++++++++++++++++++++++ README.md | 11 +++ 2 files changed, 182 insertions(+) create mode 100644 ArknightsEndfieldBridge.php diff --git a/ArknightsEndfieldBridge.php b/ArknightsEndfieldBridge.php new file mode 100644 index 0000000..0f3043a --- /dev/null +++ b/ArknightsEndfieldBridge.php @@ -0,0 +1,171 @@ + [ + 'name' => 'Language', + 'type' => 'list', + 'required' => true, + 'defaultValue' => 'de-de', + 'values' => [ + 'English' => 'en-us', + 'Deutsch' => 'de-de', + 'Français' => 'fr-fr', + 'Español' => 'es-es', + 'Português' => 'pt-br', + 'Русский' => 'ru-ru', + '日本語' => 'ja-jp', + '한국어' => 'ko-ko', + 'Italiano' => 'it-it', + 'Indonesia' => 'id-id', + 'ไทย' => 'th-th', + 'Tiếng Việt' => 'vi-vi', + '简体中文' => 'zh-cn', + '繁體中文' => 'zh-tw', + ] + ], + 'full_content' => [ + 'name' => 'Full News Content', + 'type' => 'checkbox', + 'title' => 'Enable to fetch full news content (requires additional API calls)', + 'defaultValue' => false + ], + 'limit' => [ + 'name' => 'Limit', + 'type' => 'number', + 'required' => false, + 'defaultValue' => 10, + 'title' => 'Maximum number of items to return (1-50)' + ] + ] + ]; + + public function collectData() + { + $language = $this->getInput('language'); + $fullContent = $this->getInput('full_content'); + $limit = min(max((int)$this->getInput('limit'), 1), 50); + + $listUrl = sprintf( + 'https://web-news.gryphline.com/api/bulletin?lang=%s&code=arknights_endfield_official&page=1&pageSize=%d', + $language, + $limit + ); + + $listJson = getContents($listUrl); + $listData = json_decode($listJson, true); + + if (!isset($listData['data']['list']) || !is_array($listData['data']['list'])) { + returnServerError('Unable to fetch news list or invalid response format'); + } + + foreach ($listData['data']['list'] as $newsItem) { + $item = []; + $item['title'] = $newsItem['title'] ?? ''; + $item['uri'] = sprintf( + 'https://endfield.gryphline.com/%s/news/%s', + $language, + $newsItem['cid'] ?? '' + ); + $item['timestamp'] = $newsItem['displayTime'] ?? null; + $item['author'] = 'Arknights: Endfield Official'; + + // Add cover image as enclosure + if (!empty($newsItem['cover'])) { + $item['enclosures'] = [$newsItem['cover']]; + } + + // Determine content based on full_content setting + if ($fullContent) { + // Fetch full content from detail API + $detailUrl = sprintf( + 'https://web-news.gryphline.com/api/bulletin/%s?lang=%s&code=arknights_endfield_official', + $newsItem['cid'] ?? '', + $language + ); + + $detailJson = getContents($detailUrl); + $detailData = json_decode($detailJson, true); + + if (isset($detailData['data']['data'])) { + $coverImage = $this->formatCoverImage($newsItem['cover'] ?? ''); + $item['content'] = $coverImage . $detailData['data']['data']; + } else { + // Fallback to brief if detail fetch fails + $item['content'] = $this->formatBrief($newsItem['brief'] ?? '', $newsItem['cover'] ?? ''); + } + } else { + // Use brief content from list API + $item['content'] = $this->formatBrief($newsItem['brief'] ?? '', $newsItem['cover'] ?? ''); + } + + $this->items[] = $item; + } + } + + /** + * Format cover image HTML + */ + private function formatCoverImage(string $coverUrl): string + { + if (empty($coverUrl)) { + return ''; + } + + return sprintf('

', $coverUrl); + } + + /** + * Format brief content with optional cover image + */ + private function formatBrief(string $brief, string $coverUrl): string + { + $content = $this->formatCoverImage($coverUrl); + $content .= nl2br(htmlspecialchars($brief)); + + return $content; + } + + public function getName() + { + $language = $this->getInput('language'); + + if (empty($language)) { + return self::NAME; + } + + $languageNames = [ + 'en-us' => 'English', + 'de-de' => 'Deutsch', + 'fr-fr' => 'Français', + 'es-es' => 'Español', + 'pt-br' => 'Português', + 'ru-ru' => 'Русский', + 'ja-jp' => '日本語', + 'ko-ko' => '한국어', + 'it-it' => 'Italiano', + 'id-id' => 'Indonesia', + 'th-th' => 'ไทย', + 'vi-vi' => 'Tiếng Việt', + 'zh-cn' => '简体中文', + 'zh-tw' => '繁體中文', + ]; + + return sprintf('%s (%s)', self::NAME, $languageNames[$language] ?? $language); + } +} diff --git a/README.md b/README.md index 97b0b5d..6a476c6 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,17 @@ Diese Sammlung enthält verschiedene Bridge-Implementierungen für RSS-Bridge, u - **App ID**: Die numerische App-ID aus der App Store URL (z.B. 383457673) - **Country Code** (optional): Zwei-Buchstaben-Ländercode (z.B. de, us, fr, jp). Standard: de +### [Arknights: Endfield News Bridge](https://bridge.ponywave.de/#bridge-ArknightsEndfieldBridge) (Von Akamaru) +- **Beschreibung**: Zeigt die neuesten Nachrichten und Ankündigungen von Arknights: Endfield +- **Parameter**: + - **Language**: Sprache auswählen (English, Deutsch, Français, Español, Português, Русский, 日本語, 한국어, Italiano, Indonesia, ไทย, Tiếng Việt, 简体中文, 繁體中文) + - **Full News Content**: Checkbox um vollständigen News-Content abzurufen (erfordert zusätzliche API-Calls) + - **Limit** (optional): Maximale Anzahl an News-Items (1-50, Standard: 10) +- **Hinweise**: + - Cover-Bilder werden im Content und als Enclosure angezeigt + - Ohne "Full News Content" wird nur die Kurzversion (brief) angezeigt + - Mit "Full News Content" wird der vollständige HTML-Content abgerufen + ### [Blue Archive News Bridge](https://bridge.ponywave.de/#bridge-BlueArchiveNewsBridge) (Von Akamaru) - **Beschreibung**: Zeigt die neuesten Ankündigungen, Updates und Events aus dem Blue Archive (EN) Forum - **Parameter**: