From 0bc03325df94dad7002f86d740d689ba1d038f13 Mon Sep 17 00:00:00 2001 From: Akamaru Date: Thu, 9 Oct 2025 16:53:32 +0200 Subject: [PATCH] Neu: RSS Filter Bridge --- README.md | 14 ++++ RSSFilterBridge.php | 158 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 RSSFilterBridge.php diff --git a/README.md b/README.md index 1531763..c7e6502 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,20 @@ Diese Sammlung enthält verschiedene Bridge-Implementierungen für RSS-Bridge, u ### Pokémon GO Bridge (Von Brawl, Akamaru) - **Beschreibung**: Zeigt die neuesten offiziellen "Pokémon GO" Nachrichten +### RSS Filter Bridge (Von Akamaru) +- **Beschreibung**: Filtert und modifiziert Elemente aus beliebigen RSS/Atom-Feeds +- **Parameter**: + - **Feed URL**: URL des RSS/Atom-Feeds der gefiltert werden soll + - **Custom Icon URL**: Optional - Benutzerdefinierte Icon-URL (falls leer, wird das Favicon der Feed-Domain verwendet) + - **Remove Description**: Entfernt die Beschreibung aus Feed-Items + - **Remove Content**: Entfernt den Volltext-Content aus Feed-Items + - **Remove Author**: Entfernt Autor-Informationen + - **Remove Categories**: Entfernt Kategorien/Tags + - **Remove Enclosures**: Entfernt Anhänge/Medien (Bilder, Audio, Video) + - **Remove Timestamp**: Entfernt Datum/Zeit-Informationen + - **Title Only Mode**: Behält nur Titel und Link (entfernt alles andere) + - **Item Limit**: Maximale Anzahl der zurückgegebenen Items (Standard: 20) + ### Snowbreak News Bridge (Von Akamaru) - **Beschreibung**: Zeigt die neuesten Nachrichten von Snowbreak: Containment Zone diff --git a/RSSFilterBridge.php b/RSSFilterBridge.php new file mode 100644 index 0000000..8afbde5 --- /dev/null +++ b/RSSFilterBridge.php @@ -0,0 +1,158 @@ + [ + 'name' => 'Feed URL', + 'type' => 'text', + 'required' => true, + 'exampleValue' => 'https://example.com/rss.xml', + 'title' => 'URL of the RSS/Atom feed to filter' + ], + 'custom_icon' => [ + 'name' => 'Custom Icon URL', + 'type' => 'text', + 'required' => false, + 'exampleValue' => 'https://example.com/icon.png', + 'title' => 'Optional: Custom icon URL (if empty, will try to extract favicon from feed URL)' + ], + 'remove_description' => [ + 'name' => 'Remove Description', + 'type' => 'checkbox', + 'title' => 'Remove the description/content from feed items' + ], + 'remove_content' => [ + 'name' => 'Remove Content', + 'type' => 'checkbox', + 'title' => 'Remove the full content from feed items' + ], + 'remove_author' => [ + 'name' => 'Remove Author', + 'type' => 'checkbox', + 'title' => 'Remove author information' + ], + 'remove_categories' => [ + 'name' => 'Remove Categories', + 'type' => 'checkbox', + 'title' => 'Remove categories/tags' + ], + 'remove_enclosures' => [ + 'name' => 'Remove Enclosures', + 'type' => 'checkbox', + 'title' => 'Remove attachments/media (images, audio, video)' + ], + 'remove_timestamp' => [ + 'name' => 'Remove Timestamp', + 'type' => 'checkbox', + 'title' => 'Remove date/time information' + ], + 'title_only' => [ + 'name' => 'Title Only Mode', + 'type' => 'checkbox', + 'title' => 'Keep only title and link (removes everything else)' + ], + 'limit' => [ + 'name' => 'Item Limit', + 'type' => 'number', + 'required' => false, + 'defaultValue' => 20, + 'title' => 'Maximum number of items to return (default: 20)' + ] + ] + ]; + + public function collectData() { + $feedUrl = $this->getInput('feed_url'); + + if (empty($feedUrl)) { + returnClientError('Feed URL is required'); + } + + $this->collectExpandableDatas($feedUrl); + } + + protected function parseItem(array $item) { + $filteredItem = []; + + // Title and URI are always kept (required for RSS) + $filteredItem['title'] = $item['title'] ?? 'No title'; + $filteredItem['uri'] = $item['uri'] ?? $item['link'] ?? ''; + $filteredItem['uid'] = $item['uid'] ?? $item['guid'] ?? $filteredItem['uri']; + + // Title Only Mode - skip all other fields + if ($this->getInput('title_only')) { + return $filteredItem; + } + + // Content/Description filtering + if (!$this->getInput('remove_content') && !$this->getInput('remove_description')) { + $filteredItem['content'] = $item['content'] ?? $item['description'] ?? ''; + } elseif (!$this->getInput('remove_content') && isset($item['content'])) { + $filteredItem['content'] = $item['content']; + } elseif (!$this->getInput('remove_description') && isset($item['description'])) { + $filteredItem['content'] = $item['description']; + } + + // Author filtering + if (!$this->getInput('remove_author') && isset($item['author'])) { + $filteredItem['author'] = $item['author']; + } + + // Categories filtering + if (!$this->getInput('remove_categories') && isset($item['categories'])) { + $filteredItem['categories'] = $item['categories']; + } + + // Enclosures filtering (images, audio, video) + if (!$this->getInput('remove_enclosures') && isset($item['enclosures'])) { + $filteredItem['enclosures'] = $item['enclosures']; + } + + // Timestamp filtering + if (!$this->getInput('remove_timestamp') && isset($item['timestamp'])) { + $filteredItem['timestamp'] = $item['timestamp']; + } + + return $filteredItem; + } + + public function getItems() { + $items = parent::getItems(); + $limit = $this->getInput('limit') ?: 20; + + return array_slice($items, 0, $limit); + } + + public function getName() { + if ($this->getInput('feed_url')) { + return 'RSS Filter: ' . parse_url($this->getInput('feed_url'), PHP_URL_HOST); + } + return parent::getName(); + } + + public function getIcon() { + // Use custom icon if provided + if ($this->getInput('custom_icon')) { + return $this->getInput('custom_icon'); + } + + // Extract favicon from feed URL + $feedUrl = $this->getInput('feed_url'); + if ($feedUrl) { + $parsedUrl = parse_url($feedUrl); + if (isset($parsedUrl['scheme']) && isset($parsedUrl['host'])) { + return $parsedUrl['scheme'] . '://' . $parsedUrl['host'] . '/favicon.ico'; + } + } + + // Fallback to default + return parent::getIcon(); + } +}