Neu: Epic Games Store News Bridge
This commit is contained in:
205
EpicGamesStoreNewsBridge.php
Normal file
205
EpicGamesStoreNewsBridge.php
Normal file
@@ -0,0 +1,205 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
class EpicGamesStoreNewsBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'Akamaru';
|
||||
const NAME = 'Epic Games Store News';
|
||||
const URI = 'https://store.epicgames.com/news';
|
||||
const CACHE_TIMEOUT = 3600; // 1 hour
|
||||
const DESCRIPTION = 'Get the latest news from Epic Games Store';
|
||||
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'lang' => array(
|
||||
'name' => 'Language',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'Bahasa Indonesia' => 'id',
|
||||
'Bahasa Melayu' => 'ms',
|
||||
'Dansk' => 'da',
|
||||
'Deutsch' => 'de',
|
||||
'English' => 'en-US',
|
||||
'Español' => 'es-ES',
|
||||
'Español (Latam)' => 'es-MX',
|
||||
'Filipino' => 'fil',
|
||||
'Français' => 'fr',
|
||||
'Italiano' => 'it',
|
||||
'Magyar' => 'hu',
|
||||
'Nederlands' => 'nl',
|
||||
'Norsk' => 'no',
|
||||
'Polski' => 'pl',
|
||||
'Português (Brasil)' => 'pt-BR',
|
||||
'Português Europeu' => 'pt',
|
||||
'Română' => 'ro',
|
||||
'Suomi' => 'fi',
|
||||
'Svenska' => 'sv',
|
||||
'Tiếng Việt' => 'vi',
|
||||
'Türkçe' => 'tr',
|
||||
'Čeština' => 'cs',
|
||||
'Български' => 'bg',
|
||||
'Русский' => 'ru',
|
||||
'Українська' => 'uk',
|
||||
'العربية' => 'ar',
|
||||
'हिन्दी' => 'hi',
|
||||
'ไทย' => 'th',
|
||||
'日本語' => 'ja',
|
||||
'简体中文' => 'zh-CN',
|
||||
'繁體中文' => 'zh-Hant',
|
||||
'한국어' => 'ko',
|
||||
),
|
||||
'required' => true,
|
||||
'defaultValue' => 'en-US'
|
||||
),
|
||||
'limit' => array(
|
||||
'name' => 'Limit (non-sticky news)',
|
||||
'type' => 'number',
|
||||
'required' => false,
|
||||
'defaultValue' => 20
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
public function getIcon()
|
||||
{
|
||||
return 'https://www.google.com/s2/favicons?domain=store.epicgames.com&sz=32';
|
||||
}
|
||||
|
||||
public function getURI()
|
||||
{
|
||||
$lang = $this->getInput('lang');
|
||||
if (!empty($lang)) {
|
||||
return 'https://store.epicgames.com/' . $lang . '/news';
|
||||
}
|
||||
return self::URI;
|
||||
}
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
$lang = $this->getInput('lang');
|
||||
if (empty($lang)) {
|
||||
returnClientError('Language is required');
|
||||
}
|
||||
|
||||
$limit = $this->getInput('limit');
|
||||
if (empty($limit)) {
|
||||
$limit = 20;
|
||||
}
|
||||
|
||||
// Fetch sticky news
|
||||
$stickyUrl = 'https://store-content.ak.epicgames.com/api/' . $lang . '/content/blog/sticky';
|
||||
$stickyJson = getContents($stickyUrl);
|
||||
$stickyData = json_decode($stickyJson, true);
|
||||
|
||||
// Fetch regular news
|
||||
$regularUrl = 'https://store-content.ak.epicgames.com/api/' . $lang . '/content/blog?limit=' . $limit;
|
||||
$regularJson = getContents($regularUrl);
|
||||
$regularData = json_decode($regularJson, true);
|
||||
|
||||
// Combine both arrays, sticky news first
|
||||
$allNews = array_merge($stickyData ?? [], $regularData ?? []);
|
||||
|
||||
foreach ($allNews as $article) {
|
||||
$item = array();
|
||||
|
||||
// Build URL
|
||||
$item['uri'] = 'https://store.epicgames.com' . $article['urlPattern'];
|
||||
|
||||
// Title
|
||||
$item['title'] = $article['title'];
|
||||
|
||||
// Timestamp
|
||||
if (isset($article['date'])) {
|
||||
$item['timestamp'] = strtotime($article['date']);
|
||||
} elseif (isset($article['lastModified'])) {
|
||||
$item['timestamp'] = strtotime($article['lastModified']);
|
||||
}
|
||||
|
||||
// Author - clean up suffix like ", Autor" or ", Autorin"
|
||||
if (isset($article['author'])) {
|
||||
$item['author'] = $this->cleanAuthorName($article['author']);
|
||||
}
|
||||
|
||||
// Content
|
||||
if (isset($article['short'])) {
|
||||
$item['content'] = $article['short'];
|
||||
}
|
||||
|
||||
// Add full content if available
|
||||
if (isset($article['content'])) {
|
||||
$item['content'] = $article['content'];
|
||||
}
|
||||
|
||||
// Categories
|
||||
if (isset($article['cat'])) {
|
||||
$item['categories'] = array($article['cat']);
|
||||
}
|
||||
|
||||
// Enclosures (images)
|
||||
if (isset($article['trendingImage'])) {
|
||||
$item['enclosures'] = array($article['trendingImage']);
|
||||
} elseif (isset($article['_images_']) && is_array($article['_images_']) && count($article['_images_']) > 0) {
|
||||
$item['enclosures'] = array($article['_images_'][0]);
|
||||
}
|
||||
|
||||
$this->items[] = $item;
|
||||
}
|
||||
|
||||
// Sort items by timestamp (newest first)
|
||||
usort($this->items, function ($a, $b) {
|
||||
$timeA = $a['timestamp'] ?? 0;
|
||||
$timeB = $b['timestamp'] ?? 0;
|
||||
return $timeB - $timeA; // Descending order (newest first)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean author name by removing common suffixes and prefixes like ", Autor", ", Autorin", "寄稿者:", etc.
|
||||
* This is a best-effort approach as different languages have different patterns.
|
||||
*/
|
||||
private function cleanAuthorName($author)
|
||||
{
|
||||
// Trim whitespace first
|
||||
$author = trim($author);
|
||||
|
||||
// Common suffix patterns in different languages
|
||||
$suffixPatterns = array(
|
||||
', Contributor', // English
|
||||
', contributeur', // French
|
||||
', colaborador', // Spanish/Portuguese
|
||||
', collaboratore', // Italian
|
||||
', Autor', // German (masculine)
|
||||
', Autorin', // German (feminine)
|
||||
', Author', // English (alternative)
|
||||
', Auteur', // French (alternative)
|
||||
', Autore', // Italian (alternative)
|
||||
', Autora', // Spanish/Portuguese (feminine)
|
||||
', Escritor', // Spanish
|
||||
', Escritora', // Spanish (feminine)
|
||||
', 기고자', // Korean
|
||||
', Συγγραφέας', // Greek
|
||||
);
|
||||
|
||||
// Common prefix patterns (mainly Asian languages)
|
||||
$prefixPatterns = array(
|
||||
'寄稿者:', // Japanese (Contributor:)
|
||||
);
|
||||
|
||||
// Remove suffix patterns
|
||||
foreach ($suffixPatterns as $pattern) {
|
||||
if (str_ends_with($author, $pattern)) {
|
||||
return trim(substr($author, 0, -strlen($pattern)));
|
||||
}
|
||||
}
|
||||
|
||||
// Remove prefix patterns
|
||||
foreach ($prefixPatterns as $pattern) {
|
||||
if (str_starts_with($author, $pattern)) {
|
||||
return trim(substr($author, strlen($pattern)));
|
||||
}
|
||||
}
|
||||
|
||||
return $author;
|
||||
}
|
||||
}
|
||||
10
README.md
10
README.md
@@ -62,6 +62,16 @@ Diese Sammlung enthält verschiedene Bridge-Implementierungen für RSS-Bridge, u
|
||||
### [Echo Lederhecke Bridge](https://bridge.ponywave.de/#bridge-EchoLederheckeBridge) (Von Akamaru)
|
||||
- **Beschreibung**: Neue Ausgaben des Gemeindeblatts "Echo der Lederhecke" als RSS-Feed.
|
||||
|
||||
### [Epic Games Store News Bridge](https://bridge.ponywave.de/#bridge-EpicGamesStoreNewsBridge) (Von Akamaru)
|
||||
- **Beschreibung**: Zeigt die neuesten Nachrichten vom Epic Games Store
|
||||
- **Parameter**:
|
||||
- **Sprache**: Auswahl aus 32 Sprachen (Bahasa Indonesia, Bahasa Melayu, Dansk, Deutsch, English, Español, Español (Latam), Filipino, Français, Italiano, Magyar, Nederlands, Norsk, Polski, Português (Brasil), Português Europeu, Română, Suomi, Svenska, Tiếng Việt, Türkçe, Čeština, Български, Русский, Українська, العربية, हिन्दी, ไทย, 日本語, 简体中文, 繁體中文, 한국어)
|
||||
- **Limit** (optional): Maximale Anzahl an regulären News (Standard: 20)
|
||||
- **Hinweise**:
|
||||
- Kombiniert Sticky News und reguläre News
|
||||
- Automatische Bereinigung von Autornamen (entfernt Suffixe wie ", Autor", ", Contributor" usw.)
|
||||
- Sortiert nach Datum (neueste zuerst)
|
||||
|
||||
### [EverSD News Bridge](https://bridge.ponywave.de/#bridge-EverSDBridge) (Von Akamaru)
|
||||
- **Beschreibung**: EverSD News und Changelog.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user