diff --git a/simplerss/po/SimpleRSS.pot b/simplerss/po/SimpleRSS.pot index 9d1ccfd465..2a1d9651fd 100644 --- a/simplerss/po/SimpleRSS.pot +++ b/simplerss/po/SimpleRSS.pot @@ -1,165 +1,184 @@ # SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # -#, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-04-16 19:06+0430\n" +"POT-Creation-Date: 2023-09-10 15:11+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" +"Last-Translator: Mr.Servo \n" "Language-Team: LANGUAGE \n" -"Language: \n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" +"Content-Type: text/plain; charset=cp1252\n" "Content-Transfer-Encoding: 8bit\n" +"Generated-By: pygettext.py 1.5\n" -#, python-format -msgid "%d Feed(s) were added to configuration." +#: ..\plugin.py:49 +msgid "Notification" msgstr "" -msgid "A simple to use RSS reader" +#: ..\plugin.py:49 +msgid "Preview" msgstr "" -msgid "Autoupdate" +#: ..\plugin.py:49 +msgid "Ticker" msgstr "" -msgid "Cancel" +#: ..\plugin.py:49 +msgid "none" msgstr "" -msgid "Close" +#: ..\plugin.py:164 ..\plugin.py:799 +msgid "New Items" msgstr "" -msgid "Delete" +#: ..\plugin.py:180 +msgid "Autoupdate" msgstr "" -msgid "Enclosures" +#: ..\plugin.py:180 +msgid "Feed URI" msgstr "" -msgid "Entries" +#: ..\plugin.py:182 ..\plugin.py:223 +msgid "Cancel" msgstr "" -#, python-format -msgid "Entry %s/%s" +#: ..\plugin.py:183 ..\plugin.py:224 +msgid "OK" msgstr "" -msgid "Error while parsing Feed, this usually means there is something wrong with it." +#: ..\plugin.py:192 ..\plugin.py:242 +msgid "Simple RSS Reader Setup" +msgstr "" + +#: ..\plugin.py:225 +msgid "New" msgstr "" -msgid "Failed to get subscriptions from Google Reader." +#: ..\plugin.py:226 +msgid "Delete" msgstr "" -msgid "Failed to login to Google Reader." +#: ..\plugin.py:227 +msgid "Import from '%sfeeds.xml" msgstr "" +#: ..\plugin.py:246 msgid "Feed" msgstr "" -#, python-format -msgid "Feed %s/%s" +#: ..\plugin.py:247 +msgid "Start automatically with Enigma2" msgstr "" -msgid "Feed URI" +#: ..\plugin.py:248 +msgid "Keep running in background" msgstr "" -msgid "Feed is empty." +#: ..\plugin.py:251 +msgid "Show new Messages as" msgstr "" -msgid "Fetch feeds from Google Reader?" +#: ..\plugin.py:251 +msgid "Update Interval (min)" msgstr "" -msgid "Found no Enclosure we can display." +#: ..\plugin.py:270 +msgid "" +"Really delete this entry?\n" +"It cannot be recovered!" msgstr "" -msgid "Google Password" +#: ..\plugin.py:312 +msgid "" +"Importing '%s'\n" +"%s feeds were imported successfully\n" +"%s feeds were double and not imported" msgstr "" -msgid "Google Username" +#: ..\plugin.py:387 +msgid "Error while parsing Feed, this usually means there is something wrong with it." msgstr "" -msgid "Keep running in background" +#: ..\plugin.py:396 +msgid "" +"Update is being done in Background.\n" +"Contents will automatically be updated when it's done." msgstr "" -msgid "New" +#: ..\plugin.py:454 ..\plugin.py:522 ..\plugin.py:633 +msgid "Entry %s/%s" msgstr "" -msgid "New Items" +#: ..\plugin.py:455 ..\plugin.py:527 +msgid "Enclosures" msgstr "" -msgid "New Items since last Auto-Update" +#: ..\plugin.py:475 ..\plugin.py:625 +msgid "Simple RSS Reader: %s" msgstr "" +#: ..\plugin.py:479 ..\plugin.py:529 msgid "No such Item." msgstr "" -msgid "Notification" +#: ..\plugin.py:636 ..\plugin.py:638 +msgid "Feed is empty." msgstr "" -msgid "OK" +#: ..\plugin.py:712 ..\plugin.py:743 +msgid "Entries" msgstr "" -msgid "Preview" +#: ..\plugin.py:713 ..\plugin.py:744 +msgid "Feed %s/%s" msgstr "" -msgid "" -"Really delete this entry?\n" -"It cannot be recovered!" +#: ..\plugin.py:720 +msgid "Simple RSS Reader" msgstr "" -#, python-format -msgid "Received %d new news item(s)." +#: ..\plugin.py:751 +msgid "Close" msgstr "" +#: ..\plugin.py:751 msgid "Setup" msgstr "" -msgid "Show new Messages as" -msgstr "" - -msgid "Simple RSS Reader" +#: ..\plugin.py:751 +msgid "Update Feed" msgstr "" -msgid "Simple RSS Reader Setup" +#: ..\plugin.py:752 +msgid "What to do?" msgstr "" -#, python-format -msgid "Simple RSS Reader: %s" +#: ..\plugin.py:799 +msgid "New Items since last Auto-Update" msgstr "" -#, python-format +#: ..\plugin.py:828 msgid "" "Sorry, this type of feed is unsupported:\n" "%s" msgstr "" -msgid "Start automatically with Enigma2" -msgstr "" - -msgid "Subscribe Newsfeed..." -msgstr "" - -msgid "Ticker" -msgstr "" - -msgid "Update Feed" +#: ..\plugin.py:891 +msgid "Received %d new news item(s)." msgstr "" -msgid "Update Interval (min)" +#: ..\plugin.py:1142 +msgid "trying to download the feed..." msgstr "" -msgid "" -"Update is being done in Background.\n" -"Contents will automatically be updated when it's done." +#: ..\plugin.py:1208 +msgid "A simple to use RSS reader" msgstr "" +#: ..\plugin.py:1210 msgid "View RSS..." msgstr "" - -msgid "What to do?" -msgstr "" - -msgid "none" -msgstr "" diff --git a/simplerss/po/de.po b/simplerss/po/de.po index d3223741c8..789be17f68 100644 --- a/simplerss/po/de.po +++ b/simplerss/po/de.po @@ -6,130 +6,175 @@ msgid "" msgstr "" "Project-Id-Version: Enigma2 SimpleRSS Plugin\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-11-26 12:31+0000\n" -"PO-Revision-Date: 2009-09-10 23:22+0100\n" -"Last-Translator: Moritz Venn \n" +"POT-Creation-Date: 2023-09-10 15:11+0200\n" +"PO-Revision-Date: 2023-09-11 14:15+0200\n" +"Last-Translator: Mr.Servo \n" "Language-Team: german \n" -"Language: \n" +"Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.3.2\n" -#, python-format -msgid "%d Feed(s) were added to configuration." -msgstr "%d Kanäle wurden der Konfiguration hinzugefügt." +#: ..\plugin.py:49 +msgid "Notification" +msgstr "Benachrichtigung" -msgid "A simple to use RSS reader" -msgstr "Ein einfacher Newsreader" +#: ..\plugin.py:49 +msgid "Preview" +msgstr "Vorschau" + +#: ..\plugin.py:49 +msgid "Ticker" +msgstr "Ticker" +#: ..\plugin.py:49 +msgid "none" +msgstr "Keins" + +#: ..\plugin.py:164 ..\plugin.py:799 +msgid "New Items" +msgstr "Neue Nachrichten" + +#: ..\plugin.py:180 msgid "Autoupdate" msgstr "Automatisch aktualisieren" +#: ..\plugin.py:180 +msgid "Feed URI" +msgstr "Adresse" + +#: ..\plugin.py:182 ..\plugin.py:223 msgid "Cancel" msgstr "Abbrechen" -msgid "Close" -msgstr "Schließen" - -msgid "Delete" -msgstr "Löschen" - -msgid "Enclosures" -msgstr "Anhänge" - -msgid "Entries" -msgstr "Einträge" +#: ..\plugin.py:183 ..\plugin.py:224 +msgid "OK" +msgstr "OK" -#, python-format -msgid "Entry %s/%s" -msgstr "Eintrag %s/%s" +#: ..\plugin.py:192 ..\plugin.py:242 +msgid "Simple RSS Reader Setup" +msgstr "Simple RSS Reader Einstellungen" -msgid "Error while parsing Feed, this usually means there is something wrong with it." -msgstr "Fehler während der Verarbeitung. Dies beudetet in der Regel, dass etwas mit dem Kanal nicht stimmt." +#: ..\plugin.py:225 +msgid "New" +msgstr "Neu" -msgid "Failed to get subscriptions from Google Reader." -msgstr "Konnte Abonnements nicht von Google Reader auslesen." +#: ..\plugin.py:226 +msgid "Delete" +msgstr "Löschen" -msgid "Failed to login to Google Reader." -msgstr "Anmeldung bei Google Reader fehlgeschlagen." +#: ..\plugin.py:227 +msgid "Import from '%sfeeds.xml" +msgstr "Import von '%sfeeds.xml" +#: ..\plugin.py:246 msgid "Feed" msgstr "Kanal" -#, python-format -msgid "Feed %s/%s" -msgstr "Kanal %s/%s" +#: ..\plugin.py:247 +msgid "Start automatically with Enigma2" +msgstr "Automatisch mit Enigma2 starten" -msgid "Feed URI" -msgstr "Adresse" +#: ..\plugin.py:248 +msgid "Keep running in background" +msgstr "Im Hintergrund aktiv bleiben" -msgid "Feed is empty." -msgstr "Kanal ist leer." +#: ..\plugin.py:251 +msgid "Show new Messages as" +msgstr "Neue Nachrichten als" -msgid "Fetch feeds from Google Reader?" -msgstr "Abonnements bei Google Reader auslesen?" +#: ..\plugin.py:251 +msgid "Update Interval (min)" +msgstr "Aktualisierungsinterval (min)" -msgid "Found no Enclosure we can display." -msgstr "Keine anzeigbaren Anhänge gefunden." +#: ..\plugin.py:270 +msgid "" +"Really delete this entry?\n" +"It cannot be recovered!" +msgstr "" +"Diesen Eintrag wirklich entfernen?\n" +"Diese Aktion ist unwiderruflich!" -msgid "Google Password" -msgstr "Google Passwort" +#: ..\plugin.py:312 +msgid "" +"Importing '%s'\n" +"%s feeds were imported successfully\n" +"%s feeds were double and not imported" +msgstr "" +"Importieren von '%s'\n" +"%s Feeds wurden erfolgreich importiert\n" +"%s Feeds waren doppelt und wurden nicht importiert" -msgid "Google Username" -msgstr "Google Benutzername" +#: ..\plugin.py:387 +msgid "" +"Error while parsing Feed, this usually means there is something wrong with " +"it." +msgstr "" +"Fehler während der Verarbeitung. Dies beudetet in der Regel, dass etwas mit " +"dem Kanal nicht stimmt." -msgid "Keep running in background" -msgstr "Im Hintergrund aktiv bleiben" +#: ..\plugin.py:396 +msgid "" +"Update is being done in Background.\n" +"Contents will automatically be updated when it's done." +msgstr "" +"Aktualisiere im Hintergrund.\n" +"Die Änderungen werden automatisch übernommen." -msgid "New" -msgstr "Neu" +#: ..\plugin.py:454 ..\plugin.py:522 ..\plugin.py:633 +msgid "Entry %s/%s" +msgstr "Eintrag %s/%s" -msgid "New Items" -msgstr "Neue Nachrichten" +#: ..\plugin.py:455 ..\plugin.py:527 +msgid "Enclosures" +msgstr "Anhänge" -msgid "New Items since last Auto-Update" -msgstr "Neue Nachrichten seit letzter Aktualisierung" +#: ..\plugin.py:475 ..\plugin.py:625 +msgid "Simple RSS Reader: %s" +msgstr "Simple RSS Reader: %s" +#: ..\plugin.py:479 ..\plugin.py:529 msgid "No such Item." msgstr "Keine derartige Nachricht." -msgid "Notification" -msgstr "Benachrichtigung" +#: ..\plugin.py:636 ..\plugin.py:638 +msgid "Feed is empty." +msgstr "Kanal ist leer." -msgid "OK" -msgstr "OK" +#: ..\plugin.py:712 ..\plugin.py:743 +msgid "Entries" +msgstr "Einträge" -msgid "Preview" -msgstr "Vorschau" +#: ..\plugin.py:713 ..\plugin.py:744 +msgid "Feed %s/%s" +msgstr "Kanal %s/%s" -msgid "" -"Really delete this entry?\n" -"It cannot be recovered!" -msgstr "" -"Diesen Eintrag wirklich entfernen?\n" -"Diese Aktion ist unwiderruflich!" +#: ..\plugin.py:720 +msgid "Simple RSS Reader" +msgstr "Simple RSS Reader" -#, python-format -msgid "Received %d new news item(s)." -msgstr "%d neue Nachrichten empfangen." +#: ..\plugin.py:751 +msgid "Close" +msgstr "Schließen" +#: ..\plugin.py:751 msgid "Setup" msgstr "Einstellungen" -msgid "Show new Messages as" -msgstr "Neue Nachrichten als" - -msgid "Simple RSS Reader" -msgstr "Simple RSS Reader" +#: ..\plugin.py:751 +msgid "Update Feed" +msgstr "Kanal aktualisieren" -msgid "Simple RSS Reader Setup" -msgstr "Simple RSS Reader Einstellungen" +#: ..\plugin.py:752 +msgid "What to do?" +msgstr "Was möchten Sie tun?" -#, python-format -msgid "Simple RSS Reader: %s" -msgstr "Simple RSS Reader: %s" +#: ..\plugin.py:799 +msgid "New Items since last Auto-Update" +msgstr "Neue Nachrichten seit letzter Aktualisierung" -#, python-format +#: ..\plugin.py:828 msgid "" "Sorry, this type of feed is unsupported:\n" "%s" @@ -137,33 +182,18 @@ msgstr "" "Derartige Kanäle werden nicht unterstützt:\n" "%s" -msgid "Start automatically with Enigma2" -msgstr "Automatisch mit Enigma2 starten" - -msgid "Subscribe Newsfeed..." -msgstr "Nachrichtenkanal abonieren..." - -msgid "Ticker" -msgstr "" - -msgid "Update Feed" -msgstr "Kanal aktualisieren" +#: ..\plugin.py:891 +msgid "Received %d new news item(s)." +msgstr "%d neue Nachrichten empfangen." -msgid "Update Interval (min)" -msgstr "Aktualisierungsinterval (min)" +#: ..\plugin.py:1142 +msgid "trying to download the feed..." +msgstr "versuche, den Feed herunterzuladen..." -msgid "" -"Update is being done in Background.\n" -"Contents will automatically be updated when it's done." -msgstr "" -"Aktualisiere im Hintergrund.\n" -"Die Änderungen werden automatisch übernommen." +#: ..\plugin.py:1208 +msgid "A simple to use RSS reader" +msgstr "Ein einfacher Newsreader" +#: ..\plugin.py:1210 msgid "View RSS..." msgstr "RSS Nachrichten anzeigen..." - -msgid "What to do?" -msgstr "Was möchten Sie tun?" - -msgid "none" -msgstr "Keins" diff --git a/simplerss/po/en.po b/simplerss/po/en.po index f2971d733b..57f36fb149 100644 --- a/simplerss/po/en.po +++ b/simplerss/po/en.po @@ -7,131 +7,176 @@ msgid "" msgstr "" "Project-Id-Version: enigma2-plugins 3.2.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-12-03 15:01+0000\n" -"PO-Revision-Date: 2012-12-03 15:01+0000\n" -"Last-Translator: Automatically generated\n" +"POT-Creation-Date: 2023-09-10 15:11+0200\n" +"PO-Revision-Date: 2023-09-11 14:16+0200\n" +"Last-Translator: Mr.Servo \n" "Language-Team: none\n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.3.2\n" -#, python-format -msgid "%d Feed(s) were added to configuration." -msgstr "%d Feed(s) were added to configuration." +#: ..\plugin.py:49 +msgid "Notification" +msgstr "Notification" -msgid "A simple to use RSS reader" -msgstr "A simple to use RSS reader" +#: ..\plugin.py:49 +msgid "Preview" +msgstr "Preview" +#: ..\plugin.py:49 +msgid "Ticker" +msgstr "Ticker" + +#: ..\plugin.py:49 +msgid "none" +msgstr "none" + +#: ..\plugin.py:164 ..\plugin.py:799 +msgid "New Items" +msgstr "New Items" + +#: ..\plugin.py:180 msgid "Autoupdate" msgstr "Autoupdate" +#: ..\plugin.py:180 +msgid "Feed URI" +msgstr "Feed URI" + +#: ..\plugin.py:182 ..\plugin.py:223 msgid "Cancel" msgstr "Cancel" -msgid "Close" -msgstr "Close" - -msgid "Delete" -msgstr "Delete" - -msgid "Enclosures" -msgstr "Enclosures" - -msgid "Entries" -msgstr "Entries" +#: ..\plugin.py:183 ..\plugin.py:224 +msgid "OK" +msgstr "OK" -#, python-format -msgid "Entry %s/%s" -msgstr "Entry %s/%s" +#: ..\plugin.py:192 ..\plugin.py:242 +msgid "Simple RSS Reader Setup" +msgstr "Simple RSS Reader Setup" -msgid "Error while parsing Feed, this usually means there is something wrong with it." -msgstr "Error while parsing Feed, this usually means there is something wrong with it." +#: ..\plugin.py:225 +msgid "New" +msgstr "New" -msgid "Failed to get subscriptions from Google Reader." -msgstr "Failed to get subscriptions from Google Reader." +#: ..\plugin.py:226 +msgid "Delete" +msgstr "Delete" -msgid "Failed to login to Google Reader." -msgstr "Failed to login to Google Reader." +#: ..\plugin.py:227 +msgid "Import from '%sfeeds.xml" +msgstr "Import from '%sfeeds.xml" +#: ..\plugin.py:246 msgid "Feed" msgstr "Feed" -#, python-format -msgid "Feed %s/%s" -msgstr "Feed %s/%s" +#: ..\plugin.py:247 +msgid "Start automatically with Enigma2" +msgstr "Start automatically with Enigma2" -msgid "Feed URI" -msgstr "Feed URI" +#: ..\plugin.py:248 +msgid "Keep running in background" +msgstr "Keep running in background" -msgid "Feed is empty." -msgstr "Feed is empty." +#: ..\plugin.py:251 +msgid "Show new Messages as" +msgstr "Show new Messages as" -msgid "Fetch feeds from Google Reader?" -msgstr "Fetch feeds from Google Reader?" +#: ..\plugin.py:251 +msgid "Update Interval (min)" +msgstr "Update Interval (min)" -msgid "Found no Enclosure we can display." -msgstr "Found no Enclosure we can display." +#: ..\plugin.py:270 +msgid "" +"Really delete this entry?\n" +"It cannot be recovered!" +msgstr "" +"Really delete this entry?\n" +"It cannot be recovered!" -msgid "Google Password" -msgstr "Google Password" +#: ..\plugin.py:312 +msgid "" +"Importing '%s'\n" +"%s feeds were imported successfully\n" +"%s feeds were double and not imported" +msgstr "" +"Importing '%s'\n" +"%s feeds were imported successfully\n" +"%s feeds were double and not imported" -msgid "Google Username" -msgstr "Google Username" +#: ..\plugin.py:387 +msgid "" +"Error while parsing Feed, this usually means there is something wrong with " +"it." +msgstr "" +"Error while parsing Feed, this usually means there is something wrong with " +"it." -msgid "Keep running in background" -msgstr "Keep running in background" +#: ..\plugin.py:396 +msgid "" +"Update is being done in Background.\n" +"Contents will automatically be updated when it's done." +msgstr "" +"Update is being done in Background.\n" +"Contents will automatically be updated when it's done." -msgid "New" -msgstr "New" +#: ..\plugin.py:454 ..\plugin.py:522 ..\plugin.py:633 +msgid "Entry %s/%s" +msgstr "Entry %s/%s" -msgid "New Items" -msgstr "New Items" +#: ..\plugin.py:455 ..\plugin.py:527 +msgid "Enclosures" +msgstr "Enclosures" -msgid "New Items since last Auto-Update" -msgstr "New Items since last Auto-Update" +#: ..\plugin.py:475 ..\plugin.py:625 +msgid "Simple RSS Reader: %s" +msgstr "Simple RSS Reader: %s" +#: ..\plugin.py:479 ..\plugin.py:529 msgid "No such Item." msgstr "No such Item." -msgid "Notification" -msgstr "Notification" +#: ..\plugin.py:636 ..\plugin.py:638 +msgid "Feed is empty." +msgstr "Feed is empty." -msgid "OK" -msgstr "OK" +#: ..\plugin.py:712 ..\plugin.py:743 +msgid "Entries" +msgstr "Entries" -msgid "Preview" -msgstr "Preview" +#: ..\plugin.py:713 ..\plugin.py:744 +msgid "Feed %s/%s" +msgstr "Feed %s/%s" -msgid "" -"Really delete this entry?\n" -"It cannot be recovered!" -msgstr "" -"Really delete this entry?\n" -"It cannot be recovered!" +#: ..\plugin.py:720 +msgid "Simple RSS Reader" +msgstr "Simple RSS Reader" -#, python-format -msgid "Received %d new news item(s)." -msgstr "Received %d new news item(s)." +#: ..\plugin.py:751 +msgid "Close" +msgstr "Close" +#: ..\plugin.py:751 msgid "Setup" msgstr "Setup" -msgid "Show new Messages as" -msgstr "Show new Messages as" - -msgid "Simple RSS Reader" -msgstr "Simple RSS Reader" +#: ..\plugin.py:751 +msgid "Update Feed" +msgstr "Update Feed" -msgid "Simple RSS Reader Setup" -msgstr "Simple RSS Reader Setup" +#: ..\plugin.py:752 +msgid "What to do?" +msgstr "What to do?" -#, python-format -msgid "Simple RSS Reader: %s" -msgstr "Simple RSS Reader: %s" +#: ..\plugin.py:799 +msgid "New Items since last Auto-Update" +msgstr "New Items since last Auto-Update" -#, python-format +#: ..\plugin.py:828 msgid "" "Sorry, this type of feed is unsupported:\n" "%s" @@ -139,33 +184,18 @@ msgstr "" "Sorry, this type of feed is unsupported:\n" "%s" -msgid "Start automatically with Enigma2" -msgstr "Start automatically with Enigma2" - -msgid "Subscribe Newsfeed..." -msgstr "Subscribe Newsfeed..." - -msgid "Ticker" -msgstr "Ticker" - -msgid "Update Feed" -msgstr "Update Feed" +#: ..\plugin.py:891 +msgid "Received %d new news item(s)." +msgstr "Received %d new news item(s)." -msgid "Update Interval (min)" -msgstr "Update Interval (min)" +#: ..\plugin.py:1142 +msgid "trying to download the feed..." +msgstr "trying to download the feed..." -msgid "" -"Update is being done in Background.\n" -"Contents will automatically be updated when it's done." -msgstr "" -"Update is being done in Background.\n" -"Contents will automatically be updated when it's done." +#: ..\plugin.py:1208 +msgid "A simple to use RSS reader" +msgstr "A simple to use RSS reader" +#: ..\plugin.py:1210 msgid "View RSS..." msgstr "View RSS..." - -msgid "What to do?" -msgstr "What to do?" - -msgid "none" -msgstr "none" diff --git a/simplerss/po/en_GB.po b/simplerss/po/en_GB.po index 7307c0b1fd..13a0dc311e 100644 --- a/simplerss/po/en_GB.po +++ b/simplerss/po/en_GB.po @@ -7,131 +7,176 @@ msgid "" msgstr "" "Project-Id-Version: enigma2-plugins 3.2.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-04-16 19:06+0430\n" -"PO-Revision-Date: 2012-03-16 16:33+0100\n" -"Last-Translator: Andy Blackburn \n" +"POT-Creation-Date: 2023-09-10 15:11+0200\n" +"PO-Revision-Date: 2023-09-11 14:16+0200\n" +"Last-Translator: Mr.Servo \n" "Language-Team: none\n" "Language: en_GB\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.3.2\n" -#, python-format -msgid "%d Feed(s) were added to configuration." -msgstr "%d Feed(s) were added to configuration." +#: ..\plugin.py:49 +msgid "Notification" +msgstr "Notification" -msgid "A simple to use RSS reader" -msgstr "A simple to use RSS reader" +#: ..\plugin.py:49 +msgid "Preview" +msgstr "Preview" +#: ..\plugin.py:49 +msgid "Ticker" +msgstr "Ticker" + +#: ..\plugin.py:49 +msgid "none" +msgstr "none" + +#: ..\plugin.py:164 ..\plugin.py:799 +msgid "New Items" +msgstr "New Items" + +#: ..\plugin.py:180 msgid "Autoupdate" msgstr "Autoupdate" +#: ..\plugin.py:180 +msgid "Feed URI" +msgstr "Feed URI" + +#: ..\plugin.py:182 ..\plugin.py:223 msgid "Cancel" msgstr "Cancel" -msgid "Close" -msgstr "Close" - -msgid "Delete" -msgstr "Delete" - -msgid "Enclosures" -msgstr "Enclosures" - -msgid "Entries" -msgstr "Entries" +#: ..\plugin.py:183 ..\plugin.py:224 +msgid "OK" +msgstr "OK" -#, python-format -msgid "Entry %s/%s" -msgstr "Entry %s/%s" +#: ..\plugin.py:192 ..\plugin.py:242 +msgid "Simple RSS Reader Setup" +msgstr "Simple RSS Reader Setup" -msgid "Error while parsing Feed, this usually means there is something wrong with it." -msgstr "Error while parsing Feed, this usually means there is something wrong with it." +#: ..\plugin.py:225 +msgid "New" +msgstr "New" -msgid "Failed to get subscriptions from Google Reader." -msgstr "Failed to get subscriptions from Google Reader." +#: ..\plugin.py:226 +msgid "Delete" +msgstr "Delete" -msgid "Failed to login to Google Reader." -msgstr "Failed to login to Google Reader." +#: ..\plugin.py:227 +msgid "Import from '%sfeeds.xml" +msgstr "Import from '%sfeeds.xml" +#: ..\plugin.py:246 msgid "Feed" msgstr "Feed" -#, python-format -msgid "Feed %s/%s" -msgstr "Feed %s/%s" +#: ..\plugin.py:247 +msgid "Start automatically with Enigma2" +msgstr "Start automatically with Enigma2" -msgid "Feed URI" -msgstr "Feed URI" +#: ..\plugin.py:248 +msgid "Keep running in background" +msgstr "Keep running in background" -msgid "Feed is empty." -msgstr "Feed is empty." +#: ..\plugin.py:251 +msgid "Show new Messages as" +msgstr "Show new Messages as" -msgid "Fetch feeds from Google Reader?" -msgstr "Fetch feeds from Google Reader?" +#: ..\plugin.py:251 +msgid "Update Interval (min)" +msgstr "Update Interval (min)" -msgid "Found no Enclosure we can display." -msgstr "Found no Enclosure we can display." +#: ..\plugin.py:270 +msgid "" +"Really delete this entry?\n" +"It cannot be recovered!" +msgstr "" +"Really delete this entry?\n" +"It cannot be recovered!" -msgid "Google Password" -msgstr "Google Password" +#: ..\plugin.py:312 +msgid "" +"Importing '%s'\n" +"%s feeds were imported successfully\n" +"%s feeds were double and not imported" +msgstr "" +"Importing '%s'\n" +"%s feeds were imported successfully\n" +"%s feeds were double and not imported" -msgid "Google Username" -msgstr "Google Username" +#: ..\plugin.py:387 +msgid "" +"Error while parsing Feed, this usually means there is something wrong with " +"it." +msgstr "" +"Error while parsing Feed, this usually means there is something wrong with " +"it." -msgid "Keep running in background" -msgstr "Keep running in background" +#: ..\plugin.py:396 +msgid "" +"Update is being done in Background.\n" +"Contents will automatically be updated when it's done." +msgstr "" +"Update is being done in Background.\n" +"Contents will automatically be updated when it's done." -msgid "New" -msgstr "New" +#: ..\plugin.py:454 ..\plugin.py:522 ..\plugin.py:633 +msgid "Entry %s/%s" +msgstr "Entry %s/%s" -msgid "New Items" -msgstr "New Items" +#: ..\plugin.py:455 ..\plugin.py:527 +msgid "Enclosures" +msgstr "Enclosures" -msgid "New Items since last Auto-Update" -msgstr "New Items since last Auto-Update" +#: ..\plugin.py:475 ..\plugin.py:625 +msgid "Simple RSS Reader: %s" +msgstr "Simple RSS Reader: %s" +#: ..\plugin.py:479 ..\plugin.py:529 msgid "No such Item." msgstr "No such Item." -msgid "Notification" -msgstr "Notification" +#: ..\plugin.py:636 ..\plugin.py:638 +msgid "Feed is empty." +msgstr "Feed is empty." -msgid "OK" -msgstr "OK" +#: ..\plugin.py:712 ..\plugin.py:743 +msgid "Entries" +msgstr "Entries" -msgid "Preview" -msgstr "Preview" +#: ..\plugin.py:713 ..\plugin.py:744 +msgid "Feed %s/%s" +msgstr "Feed %s/%s" -msgid "" -"Really delete this entry?\n" -"It cannot be recovered!" -msgstr "" -"Really delete this entry?\n" -"It cannot be recovered!" +#: ..\plugin.py:720 +msgid "Simple RSS Reader" +msgstr "Simple RSS Reader" -#, python-format -msgid "Received %d new news item(s)." -msgstr "Received %d new news item(s)." +#: ..\plugin.py:751 +msgid "Close" +msgstr "Close" +#: ..\plugin.py:751 msgid "Setup" msgstr "Setup" -msgid "Show new Messages as" -msgstr "Show new Messages as" - -msgid "Simple RSS Reader" -msgstr "Simple RSS Reader" +#: ..\plugin.py:751 +msgid "Update Feed" +msgstr "Update Feed" -msgid "Simple RSS Reader Setup" -msgstr "Simple RSS Reader Setup" +#: ..\plugin.py:752 +msgid "What to do?" +msgstr "What to do?" -#, python-format -msgid "Simple RSS Reader: %s" -msgstr "Simple RSS Reader: %s" +#: ..\plugin.py:799 +msgid "New Items since last Auto-Update" +msgstr "New Items since last Auto-Update" -#, python-format +#: ..\plugin.py:828 msgid "" "Sorry, this type of feed is unsupported:\n" "%s" @@ -139,33 +184,18 @@ msgstr "" "Sorry, this type of feed is unsupported:\n" "%s" -msgid "Start automatically with Enigma2" -msgstr "Start automatically with Enigma2" - -msgid "Subscribe Newsfeed..." -msgstr "Subscribe Newsfeed..." - -msgid "Ticker" -msgstr "Ticker" - -msgid "Update Feed" -msgstr "Update Feed" +#: ..\plugin.py:891 +msgid "Received %d new news item(s)." +msgstr "Received %d new news item(s)." -msgid "Update Interval (min)" -msgstr "Update Interval (min)" +#: ..\plugin.py:1142 +msgid "trying to download the feed..." +msgstr "trying to download the feed..." -msgid "" -"Update is being done in Background.\n" -"Contents will automatically be updated when it's done." -msgstr "" -"Update is being done in Background.\n" -"Contents will automatically be updated when it's done." +#: ..\plugin.py:1208 +msgid "A simple to use RSS reader" +msgstr "A simple to use RSS reader" +#: ..\plugin.py:1210 msgid "View RSS..." msgstr "View RSS..." - -msgid "What to do?" -msgstr "What to do?" - -msgid "none" -msgstr "none" diff --git a/simplerss/po/es.po b/simplerss/po/es.po index 8e0825cfd7..b56a2f8dca 100644 --- a/simplerss/po/es.po +++ b/simplerss/po/es.po @@ -7,131 +7,176 @@ msgid "" msgstr "" "Project-Id-Version: enigma 2-plugins\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-11-26 12:31+0000\n" -"PO-Revision-Date: 2009-01-09 13:40+0100\n" -"Last-Translator: José Juan Zapater \n" +"POT-Creation-Date: 2023-09-10 15:11+0200\n" +"PO-Revision-Date: 2023-09-11 14:16+0200\n" +"Last-Translator: Mr.Servo \n" "Language-Team: none\n" -"Language: \n" +"Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.3.2\n" -#, python-format -msgid "%d Feed(s) were added to configuration." -msgstr "%d Fuente(s) fueron añadidas a la configuración." +#: ..\plugin.py:49 +msgid "Notification" +msgstr "Notificación" -msgid "A simple to use RSS reader" -msgstr "Un lector simple de RSS" +#: ..\plugin.py:49 +msgid "Preview" +msgstr "Previsualizar" + +#: ..\plugin.py:49 +msgid "Ticker" +msgstr "Ticker" +#: ..\plugin.py:49 +msgid "none" +msgstr "ninguno" + +#: ..\plugin.py:164 ..\plugin.py:799 +msgid "New Items" +msgstr "Nuevos Elementos" + +#: ..\plugin.py:180 msgid "Autoupdate" msgstr "Autoactualizar" +#: ..\plugin.py:180 +msgid "Feed URI" +msgstr "URI de la Fuente" + +#: ..\plugin.py:182 ..\plugin.py:223 msgid "Cancel" msgstr "Cancelar" -msgid "Close" -msgstr "Cerrar" - -msgid "Delete" -msgstr "Borrar" - -msgid "Enclosures" -msgstr "Anexos" - -msgid "Entries" -msgstr "Entradas" +#: ..\plugin.py:183 ..\plugin.py:224 +msgid "OK" +msgstr "OK" -#, python-format -msgid "Entry %s/%s" -msgstr "Entrada %s/%s" +#: ..\plugin.py:192 ..\plugin.py:242 +msgid "Simple RSS Reader Setup" +msgstr "Configuración Simple RSS Reader" -msgid "Error while parsing Feed, this usually means there is something wrong with it." -msgstr "Error mientras analizaba la Fuente, esto significa normalmente que hay algo erróneo con él." +#: ..\plugin.py:225 +msgid "New" +msgstr "Nuevo" -msgid "Failed to get subscriptions from Google Reader." -msgstr "" +#: ..\plugin.py:226 +msgid "Delete" +msgstr "Borrar" -msgid "Failed to login to Google Reader." -msgstr "" +#: ..\plugin.py:227 +msgid "Import from '%sfeeds.xml" +msgstr "Importar de '%sfeeds.xml" +#: ..\plugin.py:246 msgid "Feed" msgstr "Fuente" -#, python-format -msgid "Feed %s/%s" -msgstr "Fuente %s/%s" +#: ..\plugin.py:247 +msgid "Start automatically with Enigma2" +msgstr "Comenzar automáticamente con Enigma2" -msgid "Feed URI" -msgstr "URI de la Fuente" +#: ..\plugin.py:248 +msgid "Keep running in background" +msgstr "Sigue ejecutándolo en segundo plano" -msgid "Feed is empty." -msgstr "La Fuente está vacía." +#: ..\plugin.py:251 +msgid "Show new Messages as" +msgstr "Muestra nuevos Mensajes como" -msgid "Fetch feeds from Google Reader?" -msgstr "" +#: ..\plugin.py:251 +msgid "Update Interval (min)" +msgstr "Intervalo de Actualización (min)" -msgid "Found no Enclosure we can display." -msgstr "No he encontrado Anexos que pueda visualizar." +#: ..\plugin.py:270 +msgid "" +"Really delete this entry?\n" +"It cannot be recovered!" +msgstr "" +"¿Seguro que quiere borrar esta entrada?\n" +"¡No podrá ser recuperada!" -msgid "Google Password" +#: ..\plugin.py:312 +msgid "" +"Importing '%s'\n" +"%s feeds were imported successfully\n" +"%s feeds were double and not imported" msgstr "" +"Importando '%s\n" +"%s feeds se importaron correctamente\n" +"%s feeds eran dobles y no se importaron" -msgid "Google Username" +#: ..\plugin.py:387 +msgid "" +"Error while parsing Feed, this usually means there is something wrong with " +"it." msgstr "" +"Error mientras analizaba la Fuente, esto significa normalmente que hay algo " +"erróneo con él." -msgid "Keep running in background" -msgstr "Sigue ejecutándolo en segundo plano" +#: ..\plugin.py:396 +msgid "" +"Update is being done in Background.\n" +"Contents will automatically be updated when it's done." +msgstr "" +"La Actualización se está ejecutando en segundo plano.\n" +"Los contenidos se actualizarán automáticamente cuando termine." -msgid "New" -msgstr "Nuevo" +#: ..\plugin.py:454 ..\plugin.py:522 ..\plugin.py:633 +msgid "Entry %s/%s" +msgstr "Entrada %s/%s" -msgid "New Items" -msgstr "Nuevos Elementos" +#: ..\plugin.py:455 ..\plugin.py:527 +msgid "Enclosures" +msgstr "Anexos" -msgid "New Items since last Auto-Update" -msgstr "Nuevos Elementos desde la última actualización" +#: ..\plugin.py:475 ..\plugin.py:625 +msgid "Simple RSS Reader: %s" +msgstr "Simple RSS Reader: %s" +#: ..\plugin.py:479 ..\plugin.py:529 msgid "No such Item." msgstr "No hay ningún elemento." -msgid "Notification" -msgstr "Notificación" +#: ..\plugin.py:636 ..\plugin.py:638 +msgid "Feed is empty." +msgstr "La Fuente está vacía." -msgid "OK" -msgstr "OK" +#: ..\plugin.py:712 ..\plugin.py:743 +msgid "Entries" +msgstr "Entradas" -msgid "Preview" -msgstr "Previsualizar" +#: ..\plugin.py:713 ..\plugin.py:744 +msgid "Feed %s/%s" +msgstr "Fuente %s/%s" -msgid "" -"Really delete this entry?\n" -"It cannot be recovered!" -msgstr "" -"¿Seguro que quiere borrar esta entrada?\n" -"¡No podrá ser recuperada!" +#: ..\plugin.py:720 +msgid "Simple RSS Reader" +msgstr "Simple RSS Reader" -#, python-format -msgid "Received %d new news item(s)." -msgstr "Recibí %d nuevos elementos de noticias." +#: ..\plugin.py:751 +msgid "Close" +msgstr "Cerrar" +#: ..\plugin.py:751 msgid "Setup" msgstr "Configurar" -msgid "Show new Messages as" -msgstr "Muestra nuevos Mensajes como" - -msgid "Simple RSS Reader" -msgstr "" +#: ..\plugin.py:751 +msgid "Update Feed" +msgstr "Actualizar Fuente" -msgid "Simple RSS Reader Setup" -msgstr "" +#: ..\plugin.py:752 +msgid "What to do?" +msgstr "¿Que hago?" -#, python-format -msgid "Simple RSS Reader: %s" -msgstr "" +#: ..\plugin.py:799 +msgid "New Items since last Auto-Update" +msgstr "Nuevos Elementos desde la última actualización" -#, python-format +#: ..\plugin.py:828 msgid "" "Sorry, this type of feed is unsupported:\n" "%s" @@ -139,33 +184,18 @@ msgstr "" "Lo siento, este tipo de fuente no está soportada:\n" "%s" -msgid "Start automatically with Enigma2" -msgstr "Comenzar automáticamente con Enigma2" - -msgid "Subscribe Newsfeed..." -msgstr "" - -msgid "Ticker" -msgstr "" - -msgid "Update Feed" -msgstr "Actualizar Fuente" +#: ..\plugin.py:891 +msgid "Received %d new news item(s)." +msgstr "Recibí %d nuevos elementos de noticias." -msgid "Update Interval (min)" -msgstr "Intervalo de Actualización (min)" +#: ..\plugin.py:1142 +msgid "trying to download the feed..." +msgstr "intentando descargar el feed..." -msgid "" -"Update is being done in Background.\n" -"Contents will automatically be updated when it's done." -msgstr "" -"La Actualización se está ejecutando en segundo plano.\n" -"Los contenidos se actualizarán automáticamente cuando termine." +#: ..\plugin.py:1208 +msgid "A simple to use RSS reader" +msgstr "Un lector simple de RSS" +#: ..\plugin.py:1210 msgid "View RSS..." -msgstr "" - -msgid "What to do?" -msgstr "¿Que hago?" - -msgid "none" -msgstr "ninguno" +msgstr "Ver RSS..." diff --git a/simplerss/po/fa.po b/simplerss/po/fa.po index 782d557d9d..2b917526f7 100644 --- a/simplerss/po/fa.po +++ b/simplerss/po/fa.po @@ -7,160 +7,184 @@ msgid "" msgstr "" "Project-Id-Version: simple rss Persian Translation\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-12-03 15:01+0000\n" -"PO-Revision-Date: 2012-07-26 01:21+0330\n" -"Last-Translator: mehdi \n" +"POT-Creation-Date: 2023-09-10 15:11+0200\n" +"PO-Revision-Date: 2023-09-11 14:17+0200\n" +"Last-Translator: Mr.Servo \n" "Language-Team: Persian Professionals \n" -"Language: \n" +"Language: fa_IR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Language: Persian\n" -"X-Poedit-Country: IRAN, ISLAMIC REPUBLIC OF\n" +"X-Generator: Poedit 3.3.2\n" -#, python-format -msgid "%d Feed(s) were added to configuration." -msgstr "" +#: ..\plugin.py:49 +msgid "Notification" +msgstr "اخطار" -msgid "A simple to use RSS reader" +#: ..\plugin.py:49 +msgid "Preview" +msgstr "پیش نمایش " + +#: ..\plugin.py:49 +msgid "Ticker" msgstr "" +#: ..\plugin.py:49 +msgid "none" +msgstr "هیچ چی" + +#: ..\plugin.py:164 ..\plugin.py:799 +msgid "New Items" +msgstr "گزینه جدید" + +#: ..\plugin.py:180 msgid "Autoupdate" msgstr "بروزرسانی خودکار" +#: ..\plugin.py:180 +msgid "Feed URI" +msgstr "" + +#: ..\plugin.py:182 ..\plugin.py:223 msgid "Cancel" msgstr "لغور کردن" -msgid "Close" -msgstr "بستن" +#: ..\plugin.py:183 ..\plugin.py:224 +msgid "OK" +msgstr "مورد تایید است" + +#: ..\plugin.py:192 ..\plugin.py:242 +msgid "Simple RSS Reader Setup" +msgstr "راه اندازی یک آر اس اس ساده" + +#: ..\plugin.py:225 +msgid "New" +msgstr "جدید" +#: ..\plugin.py:226 msgid "Delete" msgstr "حذف کردن" -msgid "Enclosures" -msgstr "ضمائم" - -msgid "Entries" -msgstr "نوشته ها" +#: ..\plugin.py:227 +msgid "Import from '%sfeeds.xml" +msgstr "" -#, python-format -msgid "Entry %s/%s" +#: ..\plugin.py:246 +msgid "Feed" msgstr "" -msgid "Error while parsing Feed, this usually means there is something wrong with it." -msgstr "اشکال تجزیه و تحلیل خبر ، که معمولا به معنی این است که خطایی همراه آن است " +#: ..\plugin.py:247 +msgid "Start automatically with Enigma2" +msgstr "راه اندازی خودکار همزمان با انیگما 2" -msgid "Failed to get subscriptions from Google Reader." -msgstr "ناموفق در گرفتن اشتراک از گوگل ریدر" +#: ..\plugin.py:248 +msgid "Keep running in background" +msgstr "در حال اجرا پس زمینه" -msgid "Failed to login to Google Reader." -msgstr "ناموفق در ورود به گوگل ریدر" +#: ..\plugin.py:251 +msgid "Show new Messages as" +msgstr "نمایش پیام جدید به عنوان ..." -msgid "Feed" -msgstr "" +#: ..\plugin.py:251 +msgid "Update Interval (min)" +msgstr "به روز رسانی بازه ی زمانی بر حسب دقیقه" -#, python-format -msgid "Feed %s/%s" +#: ..\plugin.py:270 +msgid "" +"Really delete this entry?\n" +"It cannot be recovered!" msgstr "" -msgid "Feed URI" +#: ..\plugin.py:312 +msgid "" +"Importing '%s'\n" +"%s feeds were imported successfully\n" +"%s feeds were double and not imported" msgstr "" -msgid "Feed is empty." +#: ..\plugin.py:387 +msgid "" +"Error while parsing Feed, this usually means there is something wrong with " +"it." msgstr "" +"اشکال تجزیه و تحلیل خبر ، که معمولا به معنی این است که خطایی همراه آن است " -msgid "Fetch feeds from Google Reader?" +#: ..\plugin.py:396 +msgid "" +"Update is being done in Background.\n" +"Contents will automatically be updated when it's done." msgstr "" -msgid "Found no Enclosure we can display." +#: ..\plugin.py:454 ..\plugin.py:522 ..\plugin.py:633 +msgid "Entry %s/%s" msgstr "" -msgid "Google Password" -msgstr "رمز عبور گوگل" - -msgid "Google Username" -msgstr "نام کاربری گوگل" - -msgid "Keep running in background" -msgstr "در حال اجرا پس زمینه" - -msgid "New" -msgstr "جدید" - -msgid "New Items" -msgstr "گزینه جدید" +#: ..\plugin.py:455 ..\plugin.py:527 +msgid "Enclosures" +msgstr "ضمائم" -msgid "New Items since last Auto-Update" -msgstr "گزینه جدید از زمان آخرین بروزرسانی" +#: ..\plugin.py:475 ..\plugin.py:625 +msgid "Simple RSS Reader: %s" +msgstr "" +#: ..\plugin.py:479 ..\plugin.py:529 msgid "No such Item." msgstr "نبود گزینه های زیاد" -msgid "Notification" -msgstr "اخطار" - -msgid "OK" -msgstr "مورد تایید است" +#: ..\plugin.py:636 ..\plugin.py:638 +msgid "Feed is empty." +msgstr "" -msgid "Preview" -msgstr "پیش نمایش " +#: ..\plugin.py:712 ..\plugin.py:743 +msgid "Entries" +msgstr "نوشته ها" -msgid "" -"Really delete this entry?\n" -"It cannot be recovered!" +#: ..\plugin.py:713 ..\plugin.py:744 +msgid "Feed %s/%s" msgstr "" -#, python-format -msgid "Received %d new news item(s)." -msgstr "" +#: ..\plugin.py:720 +msgid "Simple RSS Reader" +msgstr "یک آر اس اس ساده" + +#: ..\plugin.py:751 +msgid "Close" +msgstr "بستن" +#: ..\plugin.py:751 msgid "Setup" msgstr "راه اندازی" -msgid "Show new Messages as" -msgstr "نمایش پیام جدید به عنوان ..." - -msgid "Simple RSS Reader" -msgstr "یک آر اس اس ساده" +#: ..\plugin.py:751 +msgid "Update Feed" +msgstr "بروزرسانی اخبار سایت ..." -msgid "Simple RSS Reader Setup" -msgstr "راه اندازی یک آر اس اس ساده" +#: ..\plugin.py:752 +msgid "What to do?" +msgstr "چه کاری انجام دهید؟" -#, python-format -msgid "Simple RSS Reader: %s" -msgstr "" +#: ..\plugin.py:799 +msgid "New Items since last Auto-Update" +msgstr "گزینه جدید از زمان آخرین بروزرسانی" -#, python-format +#: ..\plugin.py:828 msgid "" "Sorry, this type of feed is unsupported:\n" "%s" msgstr "" -msgid "Start automatically with Enigma2" -msgstr "راه اندازی خودکار همزمان با انیگما 2" - -msgid "Subscribe Newsfeed..." -msgstr "اشتراک اخبار سایت ..." - -msgid "Ticker" +#: ..\plugin.py:891 +msgid "Received %d new news item(s)." msgstr "" -msgid "Update Feed" -msgstr "بروزرسانی اخبار سایت ..." - -msgid "Update Interval (min)" -msgstr "به روز رسانی بازه ی زمانی بر حسب دقیقه" +#: ..\plugin.py:1142 +msgid "trying to download the feed..." +msgstr "" -msgid "" -"Update is being done in Background.\n" -"Contents will automatically be updated when it's done." +#: ..\plugin.py:1208 +msgid "A simple to use RSS reader" msgstr "" +#: ..\plugin.py:1210 msgid "View RSS..." msgstr "نمایش آر اس اس" - -msgid "What to do?" -msgstr "چه کاری انجام دهید؟" - -msgid "none" -msgstr "هیچ چی" diff --git a/simplerss/po/it.po b/simplerss/po/it.po index abf1914c45..551507666e 100644 --- a/simplerss/po/it.po +++ b/simplerss/po/it.po @@ -2,134 +2,176 @@ msgid "" msgstr "" "Project-Id-Version: enigma2 - simplerss\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-11-26 12:31+0000\n" -"PO-Revision-Date: 2011-09-20 21:45+0100\n" -"Last-Translator: Spaeleus \n" +"POT-Creation-Date: 2023-09-10 15:11+0200\n" +"PO-Revision-Date: 2023-09-11 14:16+0200\n" +"Last-Translator: Mr.Servo \n" "Language-Team: www.linsat.net \n" -"Language: \n" +"Language: it_IT\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Poedit-Language: Italian\n" -"X-Poedit-Country: ITALY\n" "X-Poedit-SourceCharset: iso-8859-1\n" "X-Poedit-Basepath: .../enigma2-plugins/simplerss\n" +"X-Generator: Poedit 3.3.2\n" "X-Poedit-SearchPath-0: .../enigma2-plugins/simplerss\n" -#, python-format -msgid "%d Feed(s) were added to configuration." -msgstr "%d feed aggiunti alla configurazione. " +#: ..\plugin.py:49 +msgid "Notification" +msgstr "Notifica" -msgid "A simple to use RSS reader" -msgstr "Un semplice lettore RSS" +#: ..\plugin.py:49 +msgid "Preview" +msgstr "Anteprima" -msgid "Autoupdate" -msgstr "Aggiornamento automatico" +#: ..\plugin.py:49 +msgid "Ticker" +msgstr "Ticker" -msgid "Cancel" -msgstr "Annull." +#: ..\plugin.py:49 +msgid "none" +msgstr "nessuno" -msgid "Close" -msgstr "Chiudere" +#: ..\plugin.py:164 ..\plugin.py:799 +msgid "New Items" +msgstr "Nuovo elemento" -msgid "Delete" -msgstr "Canc." +#: ..\plugin.py:180 +msgid "Autoupdate" +msgstr "Aggiornamento automatico" -msgid "Enclosures" -msgstr "Allegati" +#: ..\plugin.py:180 +msgid "Feed URI" +msgstr "URI Feed" -msgid "Entries" -msgstr "Voci" +#: ..\plugin.py:182 ..\plugin.py:223 +msgid "Cancel" +msgstr "Annullare" -#, python-format -msgid "Entry %s/%s" -msgstr "Voce %s/%s" +#: ..\plugin.py:183 ..\plugin.py:224 +msgid "OK" +msgstr "Ok" + +#: ..\plugin.py:192 ..\plugin.py:242 +msgid "Simple RSS Reader Setup" +msgstr "Configurazione lettore Simple RSS" -msgid "Error while parsing Feed, this usually means there is something wrong with it." -msgstr "Errore nell'analisi del feed: normalmente indica qualcosa di errato in esso." +#: ..\plugin.py:225 +msgid "New" +msgstr "Nuovo" -msgid "Failed to get subscriptions from Google Reader." -msgstr "Impossibile ottenere sottoscrizioni da Google Reader." +#: ..\plugin.py:226 +msgid "Delete" +msgstr "Cancellare" -msgid "Failed to login to Google Reader." -msgstr "Connessione a GoogleReader fallita!" +#: ..\plugin.py:227 +msgid "Import from '%sfeeds.xml" +msgstr "Importazione da '%sfeeds.xml" +#: ..\plugin.py:246 msgid "Feed" msgstr "Feed" -#, python-format -msgid "Feed %s/%s" -msgstr "Feed %s/%s" +#: ..\plugin.py:247 +msgid "Start automatically with Enigma2" +msgstr "Avviare automaticamente con Enigma2" -msgid "Feed URI" -msgstr "URI Feed" +#: ..\plugin.py:248 +msgid "Keep running in background" +msgstr "Mantenere attivo in background" -msgid "Feed is empty." -msgstr "Feed vuoto!" +#: ..\plugin.py:251 +msgid "Show new Messages as" +msgstr "Mostrare nuovi messaggi come" -msgid "Fetch feeds from Google Reader?" -msgstr "Ottenere feed da Google Reader?" +#: ..\plugin.py:251 +msgid "Update Interval (min)" +msgstr "Intervallo aggiornamento (min)" -msgid "Found no Enclosure we can display." -msgstr "Nessun allegato visualizzabile trovato!" +#: ..\plugin.py:270 +msgid "" +"Really delete this entry?\n" +"It cannot be recovered!" +msgstr "Cancellare la voce? Non potrà essere recuperata!" -msgid "Google Password" -msgstr "Password Google" +#: ..\plugin.py:312 +msgid "" +"Importing '%s'\n" +"%s feeds were imported successfully\n" +"%s feeds were double and not imported" +msgstr "" +"Importazione di '%s'\n" +"%s feed sono stati importati con successo\n" +"%s feed erano doppi e non sono stati importati" -msgid "Google Username" -msgstr "Nome user Google" +#: ..\plugin.py:387 +msgid "" +"Error while parsing Feed, this usually means there is something wrong with " +"it." +msgstr "" +"Errore nell'analisi del feed: normalmente indica qualcosa di errato in esso." -msgid "Keep running in background" -msgstr "Mantenere attivo in background" +#: ..\plugin.py:396 +msgid "" +"Update is being done in Background.\n" +"Contents will automatically be updated when it's done." +msgstr "" +"L'aggiornamento verrà effettuato in background.\n" +"Al termine i contenuti verranno automaticamente aggiornati." -msgid "New" -msgstr "Nuovo" +#: ..\plugin.py:454 ..\plugin.py:522 ..\plugin.py:633 +msgid "Entry %s/%s" +msgstr "Voce %s/%s" -msgid "New Items" -msgstr "Nuovo elemento" +#: ..\plugin.py:455 ..\plugin.py:527 +msgid "Enclosures" +msgstr "Allegati" -msgid "New Items since last Auto-Update" -msgstr "Nuovo elemento dall'ultimo aggiornamento automatico" +#: ..\plugin.py:475 ..\plugin.py:625 +msgid "Simple RSS Reader: %s" +msgstr "Lettore Simple RSS: %s" +#: ..\plugin.py:479 ..\plugin.py:529 msgid "No such Item." msgstr "Elemento non trovato." -msgid "Notification" -msgstr "Notifica" +#: ..\plugin.py:636 ..\plugin.py:638 +msgid "Feed is empty." +msgstr "L'alimentazione è vuota." -msgid "OK" -msgstr "Ok" +#: ..\plugin.py:712 ..\plugin.py:743 +msgid "Entries" +msgstr "Voci" -msgid "Preview" -msgstr "Anteprima" +#: ..\plugin.py:713 ..\plugin.py:744 +msgid "Feed %s/%s" +msgstr "Feed %s/%s" -msgid "" -"Really delete this entry?\n" -"It cannot be recovered!" -msgstr "Cancellare la voce? Non potrà essere recuperata!" +#: ..\plugin.py:720 +msgid "Simple RSS Reader" +msgstr "Lettore Simple RSS" -#, python-format -msgid "Received %d new news item(s)." -msgstr "Nuovi argomenti ricevuti: %d." +#: ..\plugin.py:751 +msgid "Close" +msgstr "Chiudere" +#: ..\plugin.py:751 msgid "Setup" -msgstr "Conf." - -msgid "Show new Messages as" -msgstr "Mostrare nuovi messaggi come" +msgstr "Impostazione" -msgid "Simple RSS Reader" -msgstr "Lettore Simple RSS" +#: ..\plugin.py:751 +msgid "Update Feed" +msgstr "Aggiornare feed" -msgid "Simple RSS Reader Setup" -msgstr "Configurazione lettore Simple RSS" +#: ..\plugin.py:752 +msgid "What to do?" +msgstr "Che fare?" -#, python-format -msgid "Simple RSS Reader: %s" -msgstr "Lettore Simple RSS: %s" +#: ..\plugin.py:799 +msgid "New Items since last Auto-Update" +msgstr "Nuovo elemento dall'ultimo aggiornamento automatico" -#, python-format +#: ..\plugin.py:828 msgid "" "Sorry, this type of feed is unsupported:\n" "%s" @@ -137,33 +179,18 @@ msgstr "" "Feed non supportato:\n" "%s" -msgid "Start automatically with Enigma2" -msgstr "Avviare automaticamente con Enigma2" - -msgid "Subscribe Newsfeed..." -msgstr "Sottoscrivere feed News" - -msgid "Ticker" -msgstr "Ticker" - -msgid "Update Feed" -msgstr "Aggiornare feed" +#: ..\plugin.py:891 +msgid "Received %d new news item(s)." +msgstr "Nuovi argomenti ricevuti: %d." -msgid "Update Interval (min)" -msgstr "Intervallo aggiornamento (min)" +#: ..\plugin.py:1142 +msgid "trying to download the feed..." +msgstr "trying to download the feed..." -msgid "" -"Update is being done in Background.\n" -"Contents will automatically be updated when it's done." -msgstr "" -"L'aggiornamento verrà effettuato in background.\n" -"Al termine i contenuti verranno automaticamente aggiornati." +#: ..\plugin.py:1208 +msgid "A simple to use RSS reader" +msgstr "Un semplice lettore RSS" +#: ..\plugin.py:1210 msgid "View RSS..." -msgstr "Vedere RSS" - -msgid "What to do?" -msgstr "Che fare?" - -msgid "none" -msgstr "Nessuno" +msgstr "Vedi RSS..." diff --git a/simplerss/po/lt.po b/simplerss/po/lt.po index 8a5dc5741c..2a0b88d712 100644 --- a/simplerss/po/lt.po +++ b/simplerss/po/lt.po @@ -2,132 +2,177 @@ msgid "" msgstr "" "Project-Id-Version: SimpleRSS\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-04-16 19:06+0430\n" -"PO-Revision-Date: 2017-07-11 09:10+0300\n" -"Last-Translator: Vytenis P. \n" +"POT-Creation-Date: 2023-09-10 15:11+0200\n" +"PO-Revision-Date: 2023-09-11 14:17+0200\n" +"Last-Translator: Mr.Servo \n" "Language-Team: Vytenis P. \n" "Language: lt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.0.2\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"(n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Poedit 3.3.2\n" -#, python-format -msgid "%d Feed(s) were added to configuration." -msgstr "Į konfigūraciją įtraukti %d šaltiniai." +#: ..\plugin.py:49 +msgid "Notification" +msgstr "Pranešimas" -msgid "A simple to use RSS reader" -msgstr "Naudotis RSS skaitytuvu paprasta" +#: ..\plugin.py:49 +msgid "Preview" +msgstr "Peržiūra" + +#: ..\plugin.py:49 +msgid "Ticker" +msgstr "Ticker" +#: ..\plugin.py:49 +msgid "none" +msgstr "jokio" + +#: ..\plugin.py:164 ..\plugin.py:799 +msgid "New Items" +msgstr "Nauji elementai" + +#: ..\plugin.py:180 msgid "Autoupdate" msgstr "Automatinis atnaujinimas" +#: ..\plugin.py:180 +msgid "Feed URI" +msgstr "Šaltinių internetinis adresas" + +#: ..\plugin.py:182 ..\plugin.py:223 msgid "Cancel" msgstr "Atšaukti" -msgid "Close" -msgstr "Uždaryti" - -msgid "Delete" -msgstr "Pašalinti" - -msgid "Enclosures" -msgstr "Priedų" - -msgid "Entries" -msgstr "Įrašai" +#: ..\plugin.py:183 ..\plugin.py:224 +msgid "OK" +msgstr "Gerai" -#, python-format -msgid "Entry %s/%s" -msgstr "Įrašas %s/%s" +#: ..\plugin.py:192 ..\plugin.py:242 +msgid "Simple RSS Reader Setup" +msgstr "RSS skaitytuvo sąranka" -msgid "Error while parsing Feed, this usually means there is something wrong with it." -msgstr "Klaida, nuskaitant šaltinius. Dažniausiai tai reiškia, kad ten kažkas negerai." +#: ..\plugin.py:225 +msgid "New" +msgstr "Naujas" -msgid "Failed to get subscriptions from Google Reader." -msgstr "Nepavyko gauti Google Reader prenumeratos." +#: ..\plugin.py:226 +msgid "Delete" +msgstr "Pašalinti" -msgid "Failed to login to Google Reader." -msgstr "Prie Google Reader prisijungti nepavyko." +#: ..\plugin.py:227 +msgid "Import from '%sfeeds.xml" +msgstr "Importas iš '%sfeeds.xml" +#: ..\plugin.py:246 msgid "Feed" msgstr "Šaltinis" -#, python-format -msgid "Feed %s/%s" -msgstr "Šaltinis %s/%s" +#: ..\plugin.py:247 +msgid "Start automatically with Enigma2" +msgstr "Paleisti su Enigma2 automatiškai" -msgid "Feed URI" -msgstr "Šaltinių internetinis adresas" +#: ..\plugin.py:248 +msgid "Keep running in background" +msgstr "Leisti ir fone" -msgid "Feed is empty." -msgstr "Šaltiniai tušti." +#: ..\plugin.py:251 +msgid "Show new Messages as" +msgstr "Naujus pranešimus rodyti, kaip" -msgid "Fetch feeds from Google Reader?" -msgstr "Parsiųsti šaltinius iš Google Reader?" +#: ..\plugin.py:251 +msgid "Update Interval (min)" +msgstr "Atnaujinimo intervalas (min.)" -msgid "Found no Enclosure we can display." -msgstr "Galimų parodyti priedų nerasta." +#: ..\plugin.py:270 +msgid "" +"Really delete this entry?\n" +"It cannot be recovered!" +msgstr "" +"Tikrai pašalinti šį įrašą?\n" +"Tai neatstatoma!" -msgid "Google Password" -msgstr "Google slaptažodis" +#: ..\plugin.py:312 +msgid "" +"Importing '%s'\n" +"%s feeds were imported successfully\n" +"%s feeds were double and not imported" +msgstr "" +"Importuoti \"%s\n" +"%s kanalai sėkmingai importuoti\n" +"%s kanalai buvo dvigubi ir neimportuoti" -msgid "Google Username" -msgstr "Google vartotojas" +#: ..\plugin.py:387 +msgid "" +"Error while parsing Feed, this usually means there is something wrong with " +"it." +msgstr "" +"Klaida, nuskaitant šaltinius. Dažniausiai tai reiškia, kad ten kažkas " +"negerai." -msgid "Keep running in background" -msgstr "Leisti ir fone" +#: ..\plugin.py:396 +msgid "" +"Update is being done in Background.\n" +"Contents will automatically be updated when it's done." +msgstr "" +"Fone vyksta atnaujinimas.\n" +"Po to turinys atsinaujins automatiškai." -msgid "New" -msgstr "Naujas" +#: ..\plugin.py:454 ..\plugin.py:522 ..\plugin.py:633 +msgid "Entry %s/%s" +msgstr "Įrašas %s/%s" -msgid "New Items" -msgstr "Nauji elementai" +#: ..\plugin.py:455 ..\plugin.py:527 +msgid "Enclosures" +msgstr "Priedų" -msgid "New Items since last Auto-Update" -msgstr "Nauji elementai nuo paskutinio autoatnaujinimo" +#: ..\plugin.py:475 ..\plugin.py:625 +msgid "Simple RSS Reader: %s" +msgstr "Paprastas RSS skaitytuvas: %s" +#: ..\plugin.py:479 ..\plugin.py:529 msgid "No such Item." -msgstr "Tokio elemento nėra" +msgstr "Tokio elemento nėra." -msgid "Notification" -msgstr "Pranešimas" +#: ..\plugin.py:636 ..\plugin.py:638 +msgid "Feed is empty." +msgstr "Šaltiniai tušti." -msgid "OK" -msgstr "Gerai" +#: ..\plugin.py:712 ..\plugin.py:743 +msgid "Entries" +msgstr "Įrašai" -msgid "Preview" -msgstr "Peržiūra" +#: ..\plugin.py:713 ..\plugin.py:744 +msgid "Feed %s/%s" +msgstr "Šaltinis %s/%s" -msgid "" -"Really delete this entry?\n" -"It cannot be recovered!" -msgstr "" -"Tikrai pašalinti šį įrašą?\n" -"Tai neatstatoma!" +#: ..\plugin.py:720 +msgid "Simple RSS Reader" +msgstr "Paprastas RSS skaitytuvas" -#, python-format -msgid "Received %d new news item(s)." -msgstr "Parsiųsta %d naujienų įrašų." +#: ..\plugin.py:751 +msgid "Close" +msgstr "Uždaryti" +#: ..\plugin.py:751 msgid "Setup" msgstr "Sąranka" -msgid "Show new Messages as" -msgstr "Naujus pranešimus rodyti, kaip" - -msgid "Simple RSS Reader" -msgstr "Paprastas RSS skaitytuvas" +#: ..\plugin.py:751 +msgid "Update Feed" +msgstr "Atnaujinti šaltinius" -msgid "Simple RSS Reader Setup" -msgstr "RSS skaitytuvo sąranka" +#: ..\plugin.py:752 +msgid "What to do?" +msgstr "Ką daryti?" -#, python-format -msgid "Simple RSS Reader: %s" -msgstr "Paprastas RSS skaitytuvas: %s" +#: ..\plugin.py:799 +msgid "New Items since last Auto-Update" +msgstr "Nauji elementai nuo paskutinio autoatnaujinimo" -#, python-format +#: ..\plugin.py:828 msgid "" "Sorry, this type of feed is unsupported:\n" "%s" @@ -135,33 +180,18 @@ msgstr "" "Atleiskite, šis šaltinių tipas netinka:\n" "%s" -msgid "Start automatically with Enigma2" -msgstr "Paleisti su Enigma2 automatiškai" - -msgid "Subscribe Newsfeed..." -msgstr "Prenumeruoti naujienas..." - -msgid "Ticker" -msgstr "" - -msgid "Update Feed" -msgstr "Atnaujinti šaltinius" +#: ..\plugin.py:891 +msgid "Received %d new news item(s)." +msgstr "Parsiųsta %d naujienų įrašų." -msgid "Update Interval (min)" -msgstr "Atnaujinimo intervalas (min.)" +#: ..\plugin.py:1142 +msgid "trying to download the feed..." +msgstr "bando atsisiųsti kanalą..." -msgid "" -"Update is being done in Background.\n" -"Contents will automatically be updated when it's done." -msgstr "" -"Fone vyksta atnaujinimas.\n" -"Po to turinys atsinaujins automatiškai." +#: ..\plugin.py:1208 +msgid "A simple to use RSS reader" +msgstr "Naudotis RSS skaitytuvu paprasta" +#: ..\plugin.py:1210 msgid "View RSS..." msgstr "Peržiūrėti RSS..." - -msgid "What to do?" -msgstr "Ką daryti?" - -msgid "none" -msgstr "jokio" diff --git a/simplerss/po/nl.po b/simplerss/po/nl.po index f9c6e6eb86..a329608349 100644 --- a/simplerss/po/nl.po +++ b/simplerss/po/nl.po @@ -7,133 +7,173 @@ msgid "" msgstr "" "Project-Id-Version: SimpleRSS\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-11-26 12:31+0000\n" -"PO-Revision-Date: 2011-12-05 16:10+0100\n" -"Last-Translator: R.L. van der Does\n" +"POT-Creation-Date: 2023-09-10 15:11+0200\n" +"PO-Revision-Date: 2023-09-11 14:17+0200\n" +"Last-Translator: Mr.Servo \n" "Language-Team: Rob van der Does\n" -"Language: \n" +"Language: nl_NL\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.11.4\n" -"X-Poedit-Language: Dutch\n" -"X-Poedit-Country: NETHERLANDS\n" +"X-Generator: Poedit 3.3.2\n" -#, python-format -msgid "%d Feed(s) were added to configuration." -msgstr "%d Feed(s) zijn toegevoegd aan de configuratie." +#: ..\plugin.py:49 +msgid "Notification" +msgstr "Bericht" -msgid "A simple to use RSS reader" -msgstr "Een simpel te gebruiken RSS reader" +#: ..\plugin.py:49 +msgid "Preview" +msgstr "Vooruitblik" +#: ..\plugin.py:49 +msgid "Ticker" +msgstr "Ponsband" + +#: ..\plugin.py:49 +msgid "none" +msgstr "geen" + +#: ..\plugin.py:164 ..\plugin.py:799 +msgid "New Items" +msgstr "Nieuwe items" + +#: ..\plugin.py:180 msgid "Autoupdate" msgstr "Autoupdate" +#: ..\plugin.py:180 +msgid "Feed URI" +msgstr "Feed url" + +#: ..\plugin.py:182 ..\plugin.py:223 msgid "Cancel" msgstr "Annuleren" -msgid "Close" -msgstr "Sluiten" - -msgid "Delete" -msgstr "Verwijderen" - -msgid "Enclosures" -msgstr "Bijlages" - -msgid "Entries" -msgstr "Ingaves" +#: ..\plugin.py:183 ..\plugin.py:224 +msgid "OK" +msgstr "OK" -#, python-format -msgid "Entry %s/%s" -msgstr "Ingave %s%s" +#: ..\plugin.py:192 ..\plugin.py:242 +msgid "Simple RSS Reader Setup" +msgstr "Simple RSS Reader instellingen" -msgid "Error while parsing Feed, this usually means there is something wrong with it." -msgstr "Fout tijdens verwerken feed, dit betekent meestal dat er iets fout is." +#: ..\plugin.py:225 +msgid "New" +msgstr "Nieuw" -msgid "Failed to get subscriptions from Google Reader." -msgstr "Verkrijgen van inschrijving bij Google Reader mislukt." +#: ..\plugin.py:226 +msgid "Delete" +msgstr "Verwijderen" -msgid "Failed to login to Google Reader." -msgstr "Login Google Reader mislukt." +#: ..\plugin.py:227 +msgid "Import from '%sfeeds.xml" +msgstr "Importeren uit '%sfeeds.xml" +#: ..\plugin.py:246 msgid "Feed" msgstr "Feed" -#, python-format -msgid "Feed %s/%s" -msgstr "Feed %s/%s" +#: ..\plugin.py:247 +msgid "Start automatically with Enigma2" +msgstr "Start automatisch met Enigma2" -msgid "Feed URI" -msgstr "Feed url" +#: ..\plugin.py:248 +msgid "Keep running in background" +msgstr "Op de achtergrond uitvoeren" -msgid "Feed is empty." -msgstr "Feed is leeg." +#: ..\plugin.py:251 +msgid "Show new Messages as" +msgstr "Laat nieuwe berichten zien als" -msgid "Fetch feeds from Google Reader?" -msgstr "Verkrijg feeds van Google Reader?" +#: ..\plugin.py:251 +msgid "Update Interval (min)" +msgstr "Update interval (min)" -msgid "Found no Enclosure we can display." -msgstr "Geen bijlage gevonden die we kunnen laten zien." +#: ..\plugin.py:270 +msgid "" +"Really delete this entry?\n" +"It cannot be recovered!" +msgstr "" +"Deze entry echt verwijderen?\n" +"Dit kan niet worden hersteld!" -msgid "Google Password" -msgstr "Google Wachtwoord" +#: ..\plugin.py:312 +msgid "" +"Importing '%s'\n" +"%s feeds were imported successfully\n" +"%s feeds were double and not imported" +msgstr "" +"Importeren van '%s'\n" +"%s feeds zijn succesvol geïmporteerd\n" +"%s feeds waren dubbel en niet geïmporteerd" -msgid "Google Username" -msgstr "Google Gebruikersnaam" +#: ..\plugin.py:387 +msgid "" +"Error while parsing Feed, this usually means there is something wrong with " +"it." +msgstr "Fout tijdens verwerken feed, dit betekent meestal dat er iets fout is." -msgid "Keep running in background" -msgstr "Op de achtergrond uitvoeren" +#: ..\plugin.py:396 +msgid "" +"Update is being done in Background.\n" +"Contents will automatically be updated when it's done." +msgstr "" +"Update wordt op de achtergrond uitgevoerd.\n" +"De inhoud wordt automatisch ververst als het gereed is." -msgid "New" -msgstr "Nieuw" +#: ..\plugin.py:454 ..\plugin.py:522 ..\plugin.py:633 +msgid "Entry %s/%s" +msgstr "Ingave %s%s" -msgid "New Items" -msgstr "Nieuwe items" +#: ..\plugin.py:455 ..\plugin.py:527 +msgid "Enclosures" +msgstr "Bijlages" -msgid "New Items since last Auto-Update" -msgstr "Nieuwe items sinds laatste auto-update" +#: ..\plugin.py:475 ..\plugin.py:625 +msgid "Simple RSS Reader: %s" +msgstr "Simple RSS Reader: %s" +#: ..\plugin.py:479 ..\plugin.py:529 msgid "No such Item." -msgstr "Geen beschikbaar item/" +msgstr "Geen dergelijk item." -msgid "Notification" -msgstr "Bericht" +#: ..\plugin.py:636 ..\plugin.py:638 +msgid "Feed is empty." +msgstr "Feed is leeg." -msgid "OK" -msgstr "OK" +#: ..\plugin.py:712 ..\plugin.py:743 +msgid "Entries" +msgstr "Ingaves" -msgid "Preview" -msgstr "Vooruitblik" +#: ..\plugin.py:713 ..\plugin.py:744 +msgid "Feed %s/%s" +msgstr "Feed %s/%s" -msgid "" -"Really delete this entry?\n" -"It cannot be recovered!" -msgstr "" -"Deze entry echt verwijderen?\n" -"Dit kan niet worden hersteld!" +#: ..\plugin.py:720 +msgid "Simple RSS Reader" +msgstr "Simple RSS Reader" -#, python-format -msgid "Received %d new news item(s)." -msgstr "%d nieuwe nieuws item(s) ontvangen." +#: ..\plugin.py:751 +msgid "Close" +msgstr "Sluiten" +#: ..\plugin.py:751 msgid "Setup" msgstr "Instellingen" -msgid "Show new Messages as" -msgstr "Laat nieuwe berichten zien als" - -msgid "Simple RSS Reader" -msgstr "Simple RSS Reader" +#: ..\plugin.py:751 +msgid "Update Feed" +msgstr "Feed bijwerken" -msgid "Simple RSS Reader Setup" -msgstr "Simple RSS Reader instellingen" +#: ..\plugin.py:752 +msgid "What to do?" +msgstr "Wat te doen?" -#, python-format -msgid "Simple RSS Reader: %s" -msgstr "Simple RSS Reader: %s" +#: ..\plugin.py:799 +msgid "New Items since last Auto-Update" +msgstr "Nieuwe items sinds laatste auto-update" -#, python-format +#: ..\plugin.py:828 msgid "" "Sorry, this type of feed is unsupported:\n" "%s" @@ -141,33 +181,18 @@ msgstr "" "Sorry, dit type feed wordt niet ondersteund:\n" "%s" -msgid "Start automatically with Enigma2" -msgstr "Start automatisch met Enigma2" - -msgid "Subscribe Newsfeed..." -msgstr "Inschrijven op Newsfeed..." - -msgid "Ticker" -msgstr "Ponsband" - -msgid "Update Feed" -msgstr "Feed " +#: ..\plugin.py:891 +msgid "Received %d new news item(s)." +msgstr "%d nieuwe nieuws item(s) ontvangen." -msgid "Update Interval (min)" -msgstr "Update interval (min)" +#: ..\plugin.py:1142 +msgid "trying to download the feed..." +msgstr "probeer de feed te downloaden..." -msgid "" -"Update is being done in Background.\n" -"Contents will automatically be updated when it's done." -msgstr "" -"Update wordt op de achtergrond uitgevoerd.\n" -"De inhoud wordt automatisch ververst als het gereed is." +#: ..\plugin.py:1208 +msgid "A simple to use RSS reader" +msgstr "Een simpel te gebruiken RSS reader" +#: ..\plugin.py:1210 msgid "View RSS..." msgstr "Bekijk RSS..." - -msgid "What to do?" -msgstr "Wat te doen?" - -msgid "none" -msgstr "geen" diff --git a/simplerss/po/sr.po b/simplerss/po/sr.po index 7b1ac80518..f38378f033 100644 --- a/simplerss/po/sr.po +++ b/simplerss/po/sr.po @@ -6,133 +6,172 @@ msgid "" msgstr "" "Project-Id-Version: Enigma2 SimpleRSS Plugin\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-11-26 12:31+0000\n" -"PO-Revision-Date: 2009-09-27 18:13+0100\n" -"Last-Translator: maja \n" +"POT-Creation-Date: 2023-09-10 15:11+0200\n" +"PO-Revision-Date: 2023-09-11 14:17+0200\n" +"Last-Translator: Mr.Servo \n" "Language-Team: veselin & majevica CRNABERZA \n" -"Language: \n" +"Language: sr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Language: Serbian\n" -"X-Poedit-Country: SERBIA\n" "X-Poedit-SourceCharset: utf-8\n" +"X-Generator: Poedit 3.3.2\n" -#, python-format -msgid "%d Feed(s) were added to configuration." -msgstr "%d Fid(ova) su dodati u konfiguraciju." +#: ..\plugin.py:49 +msgid "Notification" +msgstr "Obaveštenje" -msgid "A simple to use RSS reader" -msgstr "Jednostavan RSS čitač" +#: ..\plugin.py:49 +msgid "Preview" +msgstr "Pregled" + +#: ..\plugin.py:49 +msgid "Ticker" +msgstr "Ticker" +#: ..\plugin.py:49 +msgid "none" +msgstr "nijedan" + +#: ..\plugin.py:164 ..\plugin.py:799 +msgid "New Items" +msgstr "Novi artikli" + +#: ..\plugin.py:180 msgid "Autoupdate" msgstr "Autoažuriranje" +#: ..\plugin.py:180 +msgid "Feed URI" +msgstr "Fid URI" + +#: ..\plugin.py:182 ..\plugin.py:223 msgid "Cancel" msgstr "Otkaži" -msgid "Close" -msgstr "Zatvori" - -msgid "Delete" -msgstr "Obriši" - -msgid "Enclosures" -msgstr "Prilozi" - -msgid "Entries" -msgstr "Unosi" +#: ..\plugin.py:183 ..\plugin.py:224 +msgid "OK" +msgstr "OK" -#, python-format -msgid "Entry %s/%s" -msgstr "Unos %s/%s" +#: ..\plugin.py:192 ..\plugin.py:242 +msgid "Simple RSS Reader Setup" +msgstr "Podešavanje jednostavnog RSS Čitača" -msgid "Error while parsing Feed, this usually means there is something wrong with it." -msgstr "Greška kod analiziranja fida.ovo obično znači da nešto s njim nije u redu." +#: ..\plugin.py:225 +msgid "New" +msgstr "Novi" -msgid "Failed to get subscriptions from Google Reader." -msgstr "Neuspešno dobijanje odobrenja od Gugl Čitača." +#: ..\plugin.py:226 +msgid "Delete" +msgstr "Obriši" -msgid "Failed to login to Google Reader." -msgstr "Neuspelo registrovanje u Gugl Čitač." +#: ..\plugin.py:227 +msgid "Import from '%sfeeds.xml" +msgstr "" +#: ..\plugin.py:246 msgid "Feed" msgstr "Fid" -#, python-format -msgid "Feed %s/%s" -msgstr "Fidl %s/%s" +#: ..\plugin.py:247 +msgid "Start automatically with Enigma2" +msgstr "Pokreni automatski sa Enigmom2" -msgid "Feed URI" -msgstr "Fid URI" +#: ..\plugin.py:248 +msgid "Keep running in background" +msgstr "Nastavi rad u pozadini" -msgid "Feed is empty." -msgstr "Fid je prazan." +#: ..\plugin.py:251 +msgid "Show new Messages as" +msgstr "Pokaži nove poruke kao" -msgid "Fetch feeds from Google Reader?" -msgstr "Dobavljati fidove sa Gugl Čitača?" +#: ..\plugin.py:251 +msgid "Update Interval (min)" +msgstr "Ažuriraj interval (min)" -msgid "Found no Enclosure we can display." -msgstr "Nije nađen nijedan prilog koji se može prikazati." +#: ..\plugin.py:270 +msgid "" +"Really delete this entry?\n" +"It cannot be recovered!" +msgstr "" +"Stvarno obrisati ovaj unos?\n" +"On ne može biti obnovljen!" -msgid "Google Password" -msgstr "Gugl lozinka" +#: ..\plugin.py:312 +msgid "" +"Importing '%s'\n" +"%s feeds were imported successfully\n" +"%s feeds were double and not imported" +msgstr "" -msgid "Google Username" -msgstr "Gugl korisničko ime" +#: ..\plugin.py:387 +msgid "" +"Error while parsing Feed, this usually means there is something wrong with " +"it." +msgstr "" +"Greška kod analiziranja fida.ovo obično znači da nešto s njim nije u redu." -msgid "Keep running in background" -msgstr "Nastavi rad u pozadini" +#: ..\plugin.py:396 +msgid "" +"Update is being done in Background.\n" +"Contents will automatically be updated when it's done." +msgstr "" +"Ažuriranje se obavlja u pozadini.\n" +"Sadržaj će automatski biti ažuriran kad se završi." -msgid "New" -msgstr "Novi" +#: ..\plugin.py:454 ..\plugin.py:522 ..\plugin.py:633 +msgid "Entry %s/%s" +msgstr "Unos %s/%s" -msgid "New Items" -msgstr "Novi artikli" +#: ..\plugin.py:455 ..\plugin.py:527 +msgid "Enclosures" +msgstr "Prilozi" -msgid "New Items since last Auto-Update" -msgstr "Novi artikli od zadnjeg autoažuriranja" +#: ..\plugin.py:475 ..\plugin.py:625 +msgid "Simple RSS Reader: %s" +msgstr "Jednostavni RSS Čitač: %s" +#: ..\plugin.py:479 ..\plugin.py:529 msgid "No such Item." msgstr "Nema takvog artikla." -msgid "Notification" -msgstr "Obaveštenje" +#: ..\plugin.py:636 ..\plugin.py:638 +msgid "Feed is empty." +msgstr "Fid je prazan." -msgid "OK" -msgstr "OK" +#: ..\plugin.py:712 ..\plugin.py:743 +msgid "Entries" +msgstr "Unosi" -msgid "Preview" -msgstr "Pregled" +#: ..\plugin.py:713 ..\plugin.py:744 +msgid "Feed %s/%s" +msgstr "Fidl %s/%s" -msgid "" -"Really delete this entry?\n" -"It cannot be recovered!" -msgstr "" -"Stvarno obrisati ovaj unos?\n" -"On ne može biti obnovljen!" +#: ..\plugin.py:720 +msgid "Simple RSS Reader" +msgstr "Jednostavni RSS Čitač" -#, python-format -msgid "Received %d new news item(s)." -msgstr "Primljeno %d novih artikala vest(i)." +#: ..\plugin.py:751 +msgid "Close" +msgstr "Zatvori" +#: ..\plugin.py:751 msgid "Setup" -msgstr "podešavanje" +msgstr "Podešavanje" -msgid "Show new Messages as" -msgstr "Pokaži nove poruke kao" - -msgid "Simple RSS Reader" -msgstr "Jednostavni RSS Čitač" +#: ..\plugin.py:751 +msgid "Update Feed" +msgstr "Ažuriraj fid" -msgid "Simple RSS Reader Setup" -msgstr "Podešavanje jednostavnog RSS Čitača" +#: ..\plugin.py:752 +msgid "What to do?" +msgstr "Šta činiti?" -#, python-format -msgid "Simple RSS Reader: %s" -msgstr "Jednostavni RSS Čitač: %s" +#: ..\plugin.py:799 +msgid "New Items since last Auto-Update" +msgstr "Novi artikli od zadnjeg autoažuriranja" -#, python-format +#: ..\plugin.py:828 msgid "" "Sorry, this type of feed is unsupported:\n" "%s" @@ -140,33 +179,18 @@ msgstr "" "Žao mi je, ovaj tip fida nije podržant:\n" "%s" -msgid "Start automatically with Enigma2" -msgstr "Pokreni automatski sa Enigmom2 " - -msgid "Subscribe Newsfeed..." -msgstr "Pretplati se na fid vesti..." +#: ..\plugin.py:891 +msgid "Received %d new news item(s)." +msgstr "Primljeno %d novih artikala vest(i)." -msgid "Ticker" +#: ..\plugin.py:1142 +msgid "trying to download the feed..." msgstr "" -msgid "Update Feed" -msgstr "Ažuriraj fid" - -msgid "Update Interval (min)" -msgstr "Ažuriraj interval (min)" - -msgid "" -"Update is being done in Background.\n" -"Contents will automatically be updated when it's done." -msgstr "" -"Ažuriranje se obavlja u pozadini.\n" -"Sadržaj će automatski biti ažuriran kad se završi." +#: ..\plugin.py:1208 +msgid "A simple to use RSS reader" +msgstr "Jednostavan RSS čitač" +#: ..\plugin.py:1210 msgid "View RSS..." msgstr "Vidi RSS ..." - -msgid "What to do?" -msgstr "Šta činiti?" - -msgid "none" -msgstr "nijedan" diff --git a/simplerss/po/tr.po b/simplerss/po/tr.po index 0f5a78192d..d72928b60b 100644 --- a/simplerss/po/tr.po +++ b/simplerss/po/tr.po @@ -2,133 +2,176 @@ msgid "" msgstr "" "Project-Id-Version: SimpleRSS Turkish Locale\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2011-11-26 12:31+0000\n" +"POT-Creation-Date: 2023-09-10 15:11+0200\n" "PO-Revision-Date: \n" -"Last-Translator: Zülfikar VEYİSOĞLU \n" +"Last-Translator: Mr.Servo \n" "Language-Team: http://hobiagaci.com \n" -"Language: \n" +"Language: tr_TR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Language: Turkish\n" -"X-Poedit-Country: TURKEY\n" "X-Poedit-SourceCharset: utf-8\n" +"X-Generator: Poedit 3.3.2\n" -#, python-format -msgid "%d Feed(s) were added to configuration." -msgstr "%d besleme(leri) eklendi." +#: ..\plugin.py:49 +msgid "Notification" +msgstr "Bilgilendirme" -msgid "A simple to use RSS reader" -msgstr "Kolay kullanımlı RSS okuyucu" +#: ..\plugin.py:49 +msgid "Preview" +msgstr "Önizleme" + +#: ..\plugin.py:49 +msgid "Ticker" +msgstr "Ticker" +#: ..\plugin.py:49 +msgid "none" +msgstr "yok" + +#: ..\plugin.py:164 ..\plugin.py:799 +msgid "New Items" +msgstr "Yeni maddeler" + +#: ..\plugin.py:180 msgid "Autoupdate" msgstr "Otomatik güncelleme" +#: ..\plugin.py:180 +msgid "Feed URI" +msgstr "Besleme Adresi" + +#: ..\plugin.py:182 ..\plugin.py:223 msgid "Cancel" msgstr "Vazgeç" -msgid "Close" -msgstr "Kapat" - -msgid "Delete" -msgstr "Sil" - -msgid "Enclosures" -msgstr "İlişkili bildiri" - -msgid "Entries" -msgstr "Bildirim" +#: ..\plugin.py:183 ..\plugin.py:224 +msgid "OK" +msgstr "Tamam" -#, python-format -msgid "Entry %s/%s" -msgstr "Bildiri %s/%s" +#: ..\plugin.py:192 ..\plugin.py:242 +msgid "Simple RSS Reader Setup" +msgstr "Kolay RSS Okuyucu Kurulumu" -msgid "Error while parsing Feed, this usually means there is something wrong with it." -msgstr "Besleme ayrıştırılırken hata oluştu, bu durum genellikle hatalı yapılandırmadan kaynaklanır." +#: ..\plugin.py:225 +msgid "New" +msgstr "Yeni" -msgid "Failed to get subscriptions from Google Reader." -msgstr "Google Reader abonelik bilgileri alınamadı." +#: ..\plugin.py:226 +msgid "Delete" +msgstr "Sil" -msgid "Failed to login to Google Reader." -msgstr "Google Reader oturumu açılamadı." +#: ..\plugin.py:227 +msgid "Import from '%sfeeds.xml" +msgstr "'%sfeeds.xml'den içe aktar" +#: ..\plugin.py:246 msgid "Feed" msgstr "Besleme" -#, python-format -msgid "Feed %s/%s" -msgstr "Besleme %s/%s" +#: ..\plugin.py:247 +msgid "Start automatically with Enigma2" +msgstr "Enigma2 ile birlikte otomatik başlat" -msgid "Feed URI" -msgstr "Besleme Adresi" +#: ..\plugin.py:248 +msgid "Keep running in background" +msgstr "Arkaplanda çalışmaya devam et" -msgid "Feed is empty." -msgstr "Besleme boş." +#: ..\plugin.py:251 +msgid "Show new Messages as" +msgstr "Yeni mesajların gösterilme şekli" -msgid "Fetch feeds from Google Reader?" -msgstr "Google Reader beslemeleri alınsın mı?" +#: ..\plugin.py:251 +msgid "Update Interval (min)" +msgstr "Güncelleme Aralığı (dk)" -msgid "Found no Enclosure we can display." -msgstr "Gösterilmek üzere ilişkili bildiri bulunamadı." +#: ..\plugin.py:270 +msgid "" +"Really delete this entry?\n" +"It cannot be recovered!" +msgstr "" +"Bu bildirimi silmek istiyor musunuz?\n" +"Silindiğinde geri getirilemez!" -msgid "Google Password" -msgstr "Google parola" +#: ..\plugin.py:312 +msgid "" +"Importing '%s'\n" +"%s feeds were imported successfully\n" +"%s feeds were double and not imported" +msgstr "" +"'%s' içe aktarılıyor\n" +"s beslemeleri başarıyla içe aktarıldı\n" +"s beslemeleri çiftti ve içe aktarılmadı" -msgid "Google Username" -msgstr "Google kullanıcı adı" +#: ..\plugin.py:387 +msgid "" +"Error while parsing Feed, this usually means there is something wrong with " +"it." +msgstr "" +"Besleme ayrıştırılırken hata oluştu, bu durum genellikle hatalı " +"yapılandırmadan kaynaklanır." -msgid "Keep running in background" -msgstr "Arkaplanda çalışmaya devam et" +#: ..\plugin.py:396 +msgid "" +"Update is being done in Background.\n" +"Contents will automatically be updated when it's done." +msgstr "" +"Güncelleme arkaplanda yapılıyor.\n" +"Tamamlandığında, içerik otomatik olarak güncellenecektir." -msgid "New" -msgstr "Yeni" +#: ..\plugin.py:454 ..\plugin.py:522 ..\plugin.py:633 +msgid "Entry %s/%s" +msgstr "Bildiri %s/%s" -msgid "New Items" -msgstr "Yeni maddeler" +#: ..\plugin.py:455 ..\plugin.py:527 +msgid "Enclosures" +msgstr "İlişkili bildiri" -msgid "New Items since last Auto-Update" -msgstr "Son otomatik güncellemeden sonraki yeni bildirimler" +#: ..\plugin.py:475 ..\plugin.py:625 +msgid "Simple RSS Reader: %s" +msgstr "Kolay RSS Okuyucu: %s" +#: ..\plugin.py:479 ..\plugin.py:529 msgid "No such Item." msgstr "Yeni bildirim yok." -msgid "Notification" -msgstr "Bilgilendirme" +#: ..\plugin.py:636 ..\plugin.py:638 +msgid "Feed is empty." +msgstr "Besleme boş." -msgid "OK" -msgstr "Tamam" +#: ..\plugin.py:712 ..\plugin.py:743 +msgid "Entries" +msgstr "Bildirim" -msgid "Preview" -msgstr "Önizleme" +#: ..\plugin.py:713 ..\plugin.py:744 +msgid "Feed %s/%s" +msgstr "Besleme %s/%s" -msgid "" -"Really delete this entry?\n" -"It cannot be recovered!" -msgstr "" -"Bu bildirimi silmek istiyor musunuz?\n" -"Silindiğinde geri getirilemez!" +#: ..\plugin.py:720 +msgid "Simple RSS Reader" +msgstr "Kolay RSS Okuyucu" -#, python-format -msgid "Received %d new news item(s)." -msgstr "%d yeni bildirim alındı." +#: ..\plugin.py:751 +msgid "Close" +msgstr "Kapat" +#: ..\plugin.py:751 msgid "Setup" msgstr "Kurulum" -msgid "Show new Messages as" -msgstr "Yeni mesajların gösterilme şekli" - -msgid "Simple RSS Reader" -msgstr "Kolay RSS Okuyucu" +#: ..\plugin.py:751 +msgid "Update Feed" +msgstr "Beslemeyi Güncelle" -msgid "Simple RSS Reader Setup" -msgstr "Kolay RSS Okuyucu Kurulumu" +#: ..\plugin.py:752 +msgid "What to do?" +msgstr "Ne yapmak istiyorsunuz?" -#, python-format -msgid "Simple RSS Reader: %s" -msgstr "Kolay RSS Okuyucu: %s" +#: ..\plugin.py:799 +msgid "New Items since last Auto-Update" +msgstr "Son otomatik güncellemeden sonraki yeni bildirimler" -#, python-format +#: ..\plugin.py:828 msgid "" "Sorry, this type of feed is unsupported:\n" "%s" @@ -136,33 +179,18 @@ msgstr "" "Üzgünüm, bu besleme tipi desteklenmiyor:\n" "%s" -msgid "Start automatically with Enigma2" -msgstr "Enigma2 ile birlikte otomatik başlat" - -msgid "Subscribe Newsfeed..." -msgstr "Haber beslemesine abone ol..." - -msgid "Ticker" -msgstr "" - -msgid "Update Feed" -msgstr "Beslemeyi Güncelle" +#: ..\plugin.py:891 +msgid "Received %d new news item(s)." +msgstr "%d yeni bildirim alındı." -msgid "Update Interval (min)" -msgstr "Güncelleme Aralığı (dk)" +#: ..\plugin.py:1142 +msgid "trying to download the feed..." +msgstr "beslemeyi indirmeye çalışıyorum..." -msgid "" -"Update is being done in Background.\n" -"Contents will automatically be updated when it's done." -msgstr "" -"Güncelleme arkaplanda yapılıyor.\n" -"Tamamlandığında, içerik otomatik olarak güncellenecektir." +#: ..\plugin.py:1208 +msgid "A simple to use RSS reader" +msgstr "Kolay kullanımlı RSS okuyucu" +#: ..\plugin.py:1210 msgid "View RSS..." msgstr "RSS'lere bak..." - -msgid "What to do?" -msgstr "Ne yapmak istiyorsunuz?" - -msgid "none" -msgstr "yok" diff --git a/simplerss/src/RSSFeed.py b/simplerss/src/RSSFeed.py deleted file mode 100644 index 3c0dd191a0..0000000000 --- a/simplerss/src/RSSFeed.py +++ /dev/null @@ -1,219 +0,0 @@ -# -*- coding: utf-8 -*- -# PYTHON IMPORTS -from six import PY3 - -# ENIGMA IMPORTS -from Components.Scanner import ScanFile -from Plugins.SystemPlugins.Toolkit.TagStrip import strip, strip_readable - -NS_RDF = "{http://www.w3.org/1999/02/22-rdf-syntax-ns#}" -NS_RSS_09 = "{http://my.netscape.com/rdf/simple/0.9/}" -NS_RSS_10 = "{http://purl.org/rss/1.0/}" - -# based on http://effbot.org/zone/element-rss-wrapper.htm - - -class ElementWrapper: - def __init__(self, element, ns=""): - self._element = element - self._ns = ns - - def __getattr__(self, tag): - if tag.startswith('__'): - raise AttributeError(tag) - return self._element.findtext(self._ns + tag) - - -class RSSEntryWrapper(ElementWrapper): - def __getattr__(self, tag): - if tag == "enclosures": - myl = [] - for elem in self._element.findall(self._ns + 'enclosure'): - length = elem.get("length") - if length: - length = int(length) / 1048576 - myl.append(ScanFile(elem.get("url"), mimetype=elem.get("type"), size=length, autodetect=False)) - return myl - elif tag == "id": - return self._element.findtext(self._ns + 'guid', self.title + self.link) - elif tag == "updated": - tag = "lastBuildDate" - elif tag == "summary": - tag = "description" - return ElementWrapper.__getattr__(self, tag) - - -class PEAEntryWrapper(ElementWrapper): - def __getattr__(self, tag): - if tag == "link": - for elem in self._element.findall(self._ns + tag): - if not elem.get("rel") == "enclosure": - return elem.get("href") - return '' - elif tag == "enclosures": - myl = [] - for elem in self._element.findall(self._ns + 'link'): - if elem.get("rel") == "enclosure": - length = elem.get("length") - if length: - length = int(length) / 1048576 - myl.append(ScanFile(elem.get("href"), mimetype=elem.get("type"), size=length, autodetect=False)) - return myl - elif tag == "summary": - text = self._element.findtext(self._ns + 'summary') - if not text: - # NOTE: if we don't have a summary we use the full content instead - elem = self._element.find(self._ns + 'content') - if elem is not None and elem.get('type') == "html": - text = elem.text - return text - - return ElementWrapper.__getattr__(self, tag) - - -class RSSWrapper(ElementWrapper): - def __init__(self, channel, items, ns=""): - self._items = items - ElementWrapper.__init__(self, channel, ns) - - def __iter__(self): - self.idx = 0 - self.len = len(self) - 1 - return self - - def __next__(self): - idx = self.idx - if idx > self.len: - raise StopIteration - self.idx = idx + 1 - return self[idx] - - def __len__(self): - return len(self._items) - - def __getitem__(self, index): - return RSSEntryWrapper(self._items[index], self._ns) - - -class RSS1Wrapper(RSSWrapper): - def __init__(self, feed, ns): - RSSWrapper.__init__(self, feed.find(ns + 'channel'), feed.findall(ns + 'item'), ns) - - def __getattr__(self, tag): - if tag == 'logo': # XXX: afaik not officially part of older rss, but can't hurt - tag = 'image' - return ElementWrapper.__getattr__(self, tag) - - -class RSS2Wrapper(RSSWrapper): - def __init__(self, feed, ns): - channel = feed.find("channel") - RSSWrapper.__init__(self, channel, channel.findall("item")) - - def __getattr__(self, tag): - if tag == 'logo': - tag = 'image' - return ElementWrapper.__getattr__(self, tag) - - -class PEAWrapper(RSSWrapper): - def __init__(self, feed, ns): - ns = feed.tag[:feed.tag.index("}") + 1] - RSSWrapper.__init__(self, feed, feed.findall(ns + 'entry'), ns) - - def __getitem__(self, index): - return PEAEntryWrapper(self._items[index], self._ns) - - def __getattr__(self, tag): - if tag == "description": - tag = "subtitle" - return ElementWrapper.__getattr__(self, tag) - - -class BaseFeed: - """Base-class for all Feeds. Initializes needed Elements.""" - MAX_HISTORY_ELEMENTS = 100 - - def __init__(self, uri, title="", description=""): - # Set URI (used as Identifier) - if not PY3: - uri = uri.encode('utf-8') - title = title.encode('utf-8') - description = description.encode('utf-8') - self.uri = uri - # Initialize - self.title = title or uri - self.description = description - self.logoUrl = '' - self.history = [] - - def __str__(self): - return "<%s, \"%s\", \"%s\", %d items>" % (self.__class__, self.title, self.description, len(self.history)) - - -class UniversalFeed(BaseFeed): - """Feed which can handle rdf, rss and atom feeds utilizing abstraction wrappers.""" - - def __init__(self, uri, autoupdate, sync=False): - BaseFeed.__init__(self, uri) - # Set Autoupdate - self.autoupdate = autoupdate - # Is this a synced feed? - self.sync = sync - # Initialize - self.last_update = None - self.last_ids = set() - self.wrapper = None - self.ns = "" - - def gotWrapper(self, wrapper): - updated = wrapper.updated - if updated and self.last_update == updated: - return [] - idx = 0 - ids = self.last_ids - for item in wrapper: - # Try to read title, continue if none found - title = strip(item.title if PY3 else item.title.encode('utf-8')) - if not title: - continue - # Try to read id, continue if none found (invalid feed or internal error) or to be excluded - id = item.id - if not id or id in ids: - continue - # Link - link = item.link if PY3 else item.link.encode('utf-8') - # Try to read summary, empty if none - summary = strip_readable(item.summary or "") if PY3 else strip_readable(item.summary or "").encode('utf-8') - # Update Lists - self.history.insert(idx, (title, link, summary, item.enclosures)) - ids.add(id) - idx += 1 - # Eventually cut history - del self.history[self.MAX_HISTORY_ELEMENTS:] - return self.history[:idx] - - def gotFeed(self, feed): - if self.wrapper is not None: - wrapper = self.wrapper(feed, self.ns) - else: - if feed.tag == "rss": - self.wrapper = RSS2Wrapper - elif feed.tag.startswith(NS_RDF): - self.ns = NS_RDF - self.wrapper = RSS1Wrapper - elif feed.tag.startswith(NS_RSS_09): - self.ns = NS_RSS_09 - self.wrapper = RSS1Wrapper - elif feed.tag.startswith(NS_RSS_10): - self.ns = NS_RSS_10 - self.wrapper = RSS1Wrapper - elif feed.tag.endswith("feed"): - self.wrapper = PEAWrapper - else: - raise NotImplementedError('Unsupported Feed: %s' % feed.tag) - wrapper = self.wrapper(feed, self.ns) - self.title = strip(wrapper.title) if PY3 else strip(wrapper.title).encode('utf-8') - self.description = strip_readable(wrapper.description or "") if PY3 else strip_readable(wrapper.description or "").encode('utf-8') - self.logoUrl = wrapper.logo - return self.gotWrapper(wrapper) diff --git a/simplerss/src/RSSList.py b/simplerss/src/RSSList.py deleted file mode 100644 index 7367dc2003..0000000000 --- a/simplerss/src/RSSList.py +++ /dev/null @@ -1,67 +0,0 @@ -# ENIGMA IMPORTS -from Components.MenuList import MenuList -from enigma import eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT, RT_WRAP -from skin import parseFont - - -class RSSFeedList(MenuList): - def __init__(self, entries): - MenuList.__init__(self, entries, False, content=eListboxPythonMultiContent) - l = self.l - l.setFont(0, gFont("Regular", 22)) - self.descriptionFont = gFont("Regular", 18) - l.setFont(1, self.descriptionFont) - l.setItemHeight(100) - l.setBuildFunc(self.buildListboxEntry) - - def applySkin(self, desktop, parent): - attribs = [] - if self.skinAttributes is not None: - for (attrib, value) in self.skinAttributes: - if attrib == "font": - self.l.setFont(0, parseFont(value, ((1, 1), (1, 1)))) - elif attrib == "descriptionFont": - self.descriptionFont = parseFont(value, ((1, 1), (1, 1))) - self.l.setFont(1, self.descriptionFont) - elif attrib == "itemHeight": - self.l.setItemHeight(int(value)) - else: - attribs.append((attrib, value)) - self.skinAttributes = attribs - return MenuList.applySkin(self, desktop, parent) - - def connectSelChanged(self, fnc): - if not fnc in self.onSelectionChanged: - self.onSelectionChanged.append(fnc) - - def disconnectSelChanged(self, fnc): - if fnc in self.onSelectionChanged: - self.onSelectionChanged.remove(fnc) - - def invalidate(self): - self.l.invalidate() - - def moveToEntry(self, feed): - if feed is None: - return - idx = 0 - for x in self.list: - if feed.uri == x[0].uri: - self.instance.moveSelectionTo(idx) - break - idx += 1 - - def buildListboxEntry(self, feed): - size = self.l.getItemSize() - width = size.width() - descriptionHeight = self.descriptionFont.pointSize + 2 - titleHeight = size.height() - descriptionHeight - return [ - None, - (eListboxPythonMultiContent.TYPE_TEXT, 0, 0, width, titleHeight, 0, RT_HALIGN_LEFT | RT_WRAP, feed.title), - (eListboxPythonMultiContent.TYPE_TEXT, 0, titleHeight, width, descriptionHeight, 1, RT_HALIGN_LEFT, feed.description) - ] - - def getCurrent(self): - # We know that the list will never be empty... - return self.l.getCurrentSelection()[0] diff --git a/simplerss/src/RSSPoller.py b/simplerss/src/RSSPoller.py deleted file mode 100644 index a96faf222d..0000000000 --- a/simplerss/src/RSSPoller.py +++ /dev/null @@ -1,220 +0,0 @@ -# PYTHON IMPORTS -from requests import get, exceptions -from six import ensure_str, ensure_binary -from sys import stdout -from traceback import print_exc -from xml.etree.cElementTree import fromstring - -# ENIGMA IMPORTS -from enigma import eTimer -from Components.config import config -from Screens.MessageBox import MessageBox -from Tools import Notifications -from Tools.Notifications import AddPopup, AddNotificationWithID, RemovePopup - -# PLUGIN IMPORTS -from . import _ # for localized messages -from .RSSFeed import BaseFeed, UniversalFeed -from .RSSScreens import RSSFeedView -from .RSSTickerView import tickerView - -MODULE_NAME = __name__.split(".")[-1] -NOTIFICATIONID = 'SimpleRSSUpdateNotification' -update_callbacks = [] - - -class RSSPoller: - """Keeps all Feed and takes care of (automatic) updates""" - - def __init__(self, poll=True): - # Timer - self.poll_timer = eTimer() - self.poll_timer.callback.append(self.poll) - self.do_poll = poll - # this indicates we're reloading the list of feeds - self.reloading = False - self.newItemFeed = BaseFeed("", _("New Items"), _("New Items since last Auto-Update"),) - # Generate Feeds - self.feeds = [UniversalFeed(x.uri.value, x.autoupdate.value) for x in config.plugins.simpleRSS.feed] - if poll and self.poll_timer: - self.poll_timer.start(0, 1) - # Initialize Vars - self.current_feed = 0 - - def addCallback(self, callback): - if callback not in update_callbacks: - update_callbacks.append(callback) - - def removeCallback(self, callback): - if callback in update_callbacks: - update_callbacks.remove(callback) - - def doCallback(self, id=None): - for callback in update_callbacks: - try: - callback(id) - except Exception: - pass - - def error(self, error=""): - print("[SimpleRSS] failed to fetch feed:", error) - # Assume its just a temporary failure and jump over to next feed - self.next_feed() - - def _gotPage(self, id=None, callback=False, errorback=None, data=None): - # workaround: exceptions in gotPage-callback were ignored - try: - self.gotPage(data, id) - if callback: - self.doCallback(id) - except NotImplementedError as errmsg: - # Don't show this error when updating in background - if id is not None: - AddPopup(_("Sorry, this type of feed is unsupported:\n%s") % str(errmsg), MessageBox.TYPE_INFO, 5,) - else: - # We don't want to stop updating just because one feed is broken - self.next_feed() - except Exception: - print_exc(file=stdout) - # Errorback given, call it (asumme we don't need do restart timer!) - if errorback is not None: - errorback() - return - # Assume its just a temporary failure and jump over to next feed - self.next_feed() - - def singlePoll(self, feedid, errorback=None): - self.pollXml(self.feeds[feedid].uri, errorback) - - def pollXml(self, feeduri, errorback=None): - headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0", "Accept": "text/xml"} - if feeduri: - response = get - try: - response = get(ensure_binary(feeduri), headers=headers, timeout=(3.05, 6)) - response.raise_for_status() - except exceptions.RequestException as err: - print("[%s] ERROR in module 'pollXml': '%s" % (MODULE_NAME, str(err))) - if errorback: - errorback(str(err)) - try: - xmlData = response.content - if xmlData: - self.gotPage(xmlData) - print("[%s] ERROR in module 'pollXml': server access failed." % MODULE_NAME) - except Exception as err: - print("[%s] ERROR in module 'pollXml': invalid json data from server. %s" % (MODULE_NAME, str(err))) - else: - print("[%s] ERROR in module 'pollXml': missing link." % MODULE_NAME) - - def gotPage(self, data, id=None): - feed = fromstring(ensure_str(data)) - # For Single-Polling - if id is not None: - self.feeds[id].gotFeed(feed) - print("[SimpleRSS] single feed parsed...") - return - new_items = self.feeds[self.current_feed].gotFeed(feed) - print("[SimpleRSS] feed parsed...") - # Append new items to locally bound ones - if new_items is not None: - self.newItemFeed.history.extend(new_items) - # Start Timer so we can either fetch next feed or show new_items - self.next_feed() - - def poll(self): - # Reloading, reschedule - if self.reloading: - print("[SimpleRSS] timer triggered while reloading, rescheduling") - if self.poll_timer: - self.poll_timer.start(10000, 1) - # End of List - elif len(self.feeds) <= self.current_feed: - # New Items - if self.newItemFeed.history: - print("[SimpleRSS] got new items, calling back") - self.doCallback() - # Inform User - update_notification_value = config.plugins.simpleRSS.update_notification.value - if update_notification_value == "preview": - RemovePopup(NOTIFICATIONID) - AddNotificationWithID(NOTIFICATIONID, RSSFeedView, self.newItemFeed, newItems=True) - elif update_notification_value == "notification": - AddPopup(_("Received %d new news item(s).") % (len(self.newItemFeed.history)), MessageBox.TYPE_INFO, 5, NOTIFICATIONID) - elif update_notification_value == "ticker": - if not tickerView: - print("[SimpleRSS] missing ticker instance, something with my code is wrong :-/") - else: - tickerView.display(self.newItemFeed) - # No new Items - else: - print("[SimpleRSS] no new items") - self.current_feed = 0 - if self.poll_timer: - self.poll_timer.startLongTimer(config.plugins.simpleRSS.interval.value * 60) - # It's updating-time - else: - # Assume we're cleaning history if current feed is 0 - clearHistory = self.current_feed == 0 - if config.plugins.simpleRSS.update_notification.value != "none": - if hasattr(Notifications.notifications, 'Notifications.notificationQueue'): - Xnotifications = Notifications.notificationQueue.queue - Xcurrent_notifications = Notifications.notificationQueue.current - handler = lambda note: (note.fnc, note.screen, note.args, note.kwargs, note.id) - handler_current = lambda note: (note[0].id,) - else: - Xnotifications = Notifications.notifications - Xcurrent_notifications = Notifications.current_notifications - handler_current = handler = lambda note: note - for x in Xcurrent_notifications: - if handler_current(x)[0] == NOTIFICATIONID: - print("[SimpleRSS] timer triggered while preview on screen, rescheduling") - if self.poll_timer: - self.poll_timer.start(10000, 1) - if clearHistory: - for x in Xnotifications: - if handler(x)[4] == NOTIFICATIONID: - print("[SimpleRSS] wont wipe history because it was never read") - clearHistory = False - break - if clearHistory: - del self.newItemFeed.history[:] - # Feed supposed to autoupdate - feed = self.feeds[self.current_feed] - if feed.autoupdate: - self.pollXml(feed.uri, self.error) - # Go to next feed - else: - print("[SimpleRSS] passing feed sucessfully") - self.next_feed() - - def next_feed(self): - self.current_feed += 1 - if self.poll_timer: - self.poll_timer.start(1000, 1) - - def shutdown(self): - if self.poll_timer: - self.poll_timer.callback.remove(self.poll) - self.poll_timer = None - self.do_poll = False - - def triggerReload(self): - self.reloading = True - newfeeds = [] - oldfeeds = self.feeds - found = False - for x in config.plugins.simpleRSS.feed: - for feed in oldfeeds: - if x.uri.value == feed.uri: - # Update possibly different autoupdate value - feed.autoupdate = x.autoupdate.value - newfeeds.append(feed) # Append to new Feeds - oldfeeds.remove(feed) # Remove from old Feeds - found = True - break - if not found: - newfeeds.append(UniversalFeed(x.uri.value, x.autoupdate.value)) - found = False - self.feeds = newfeeds - self.reloading = False diff --git a/simplerss/src/RSSScreens.py b/simplerss/src/RSSScreens.py deleted file mode 100644 index 20f6b34e99..0000000000 --- a/simplerss/src/RSSScreens.py +++ /dev/null @@ -1,439 +0,0 @@ -# PYTHON IMPORTS -from __future__ import print_function -from __future__ import absolute_import -from twisted.internet.reactor import callInThread - -# ENIGMA IMPORTS -from enigma import eTimer -from Components.ActionMap import ActionMap -from Components.Scanner import openList -from Components.ScrollLabel import ScrollLabel -from Components.Sources.List import List -from Components.Sources.StaticText import StaticText -from Screens.ChoiceBox import ChoiceBox -from Screens.Screen import Screen -from Screens.MessageBox import MessageBox - -# PLUGIN IMPORTS -from . import _ # for localized messages -from .RSSList import RSSFeedList -from .RSSSetup import RSSSetup - - -class RSSSummary(Screen): - skin = """ - - - - - WithSeconds - - """ - - def __init__(self, session, parent): - Screen.__init__(self, session, parent=parent) - self["entry"] = StaticText("") - parent.onChangedEntry.append(self.selectionChanged) - self.onShow.append(parent.updateInfo) - self.onClose.append(self.removeWatcher) - - def removeWatcher(self): - self.parent.onChangedEntry.remove(self.selectionChanged) - - def selectionChanged(self, text): - self["entry"].text = text - - -class RSSBaseView(Screen): - """Base Screen for all Screens used in SimpleRSS""" - - def __init__(self, session, poller, parent=None): - Screen.__init__(self, session, parent) - self.onChangedEntry = [] - self.rssPoller = poller - self.pollDialog = None - - def createSummary(self): - return RSSSummary - - def errorPolling(self, errmsg=""): - # An error occured while polling - self.session.open(MessageBox, _("Error while parsing Feed, this usually means there is something wrong with it."), type=MessageBox.TYPE_ERROR, timeout=3) - # Don't show "we're updating"-dialog any longer - if self.pollDialog: - self.pollDialog.close() - self.pollDialog = None - - def singleUpdate(self, feedid): - # Don't do anything if we have no poller - if self.rssPoller is None: - return - # Tell Poller to poll - callInThread(self.rssPoller.singlePoll, feedid, errorback=self.errorPolling) - # Open Dialog and save locally - self.pollDialog = self.session.open(MessageBox, _("Update is being done in Background.\nContents will automatically be updated when it's done."), type=MessageBox.TYPE_INFO, timeout=3) - - def selectEnclosure(self, enclosures): - # Empty List - if enclosures is not None and not openList(self.session, enclosures): - self.session.open(MessageBox, _("Found no Enclosure we can display."), type=MessageBox.TYPE_INFO, timeout=3) - - -class RSSEntryView(RSSBaseView): - # Shows a RSS Item - skin = """ - - - - """ - - def __init__(self, session, data, feedTitle="", cur_idx=None, entries=None, parent=None): - RSSBaseView.__init__(self, session, None, parent) - self.data = data - self.feedTitle = feedTitle - self.cur_idx = cur_idx - self.entries = entries - self["info"] = StaticText(_("Entry %s/%s") % (cur_idx + 1, entries)) if cur_idx is not None and entries is not None else StaticText() - self["content"] = ScrollLabel(''.join((data[0], '\n\n', data[2], '\n\n', str(len(data[3])), ' ', _("Enclosures")))) if data else ScrollLabel() - self["actions"] = ActionMap(["OkCancelActions", "ChannelSelectBaseActions", "ColorActions", "DirectionActions"], - { - "cancel": self.close, - "ok": self.selectEnclosure, - "yellow": self.selectEnclosure, - "up": self.up, - "down": self.down, - "right": self.next, - "left": self.previous, - "nextBouquet": self.nextFeed, - "prevBouquet": self.previousFeed, - }) - self.onLayoutFinish.append(self.setConditionalTitle) - - def setConditionalTitle(self): - self.setTitle(_("Simple RSS Reader: %s") % (self.feedTitle)) - - def updateInfo(self): - text = self.data[0] if self.data else _("No such Item.") - for x in self.onChangedEntry: - try: - x(text) - except Exception: - pass - - def up(self): - self["content"].pageUp() - - def down(self): - self["content"].pageDown() - - def next(self): - if self.parent is not None: - (self.data, self.cur_idx, self.entries) = self.parent.nextEntry() - self.setContent() - - def previous(self): - if self.parent is not None: - (self.data, self.cur_idx, self.entries) = self.parent.previousEntry() - self.setContent() - - def nextFeed(self): - # Show next Feed - if self.parent is not None: - result = next(self.parent) - self.feedTitle = result[0] - self.entries = len(result[1]) - if self.entries: - self.cur_idx = 0 - self.data = result[1][0] - else: - self.cur_idx = None - self.data = None - self.setConditionalTitle() - self.setContent() - - def previousFeed(self): - # Show previous Feed - if self.parent is not None: - result = self.parent.previous() - self.feedTitle = result[0] - self.entries = len(result[1]) - if self.entries: - self.cur_idx = 0 - self.data = result[1][0] - else: - self.cur_idx = None - self.data = None - self.setConditionalTitle() - self.setContent() - - def setContent(self): - if self.cur_idx is not None and self.entries is not None: - self["info"].text = _("Entry %s/%s") % (self.cur_idx + 1, self.entries) - else: - self["info"].text = "" - data = self.data - if data: - self["content"].setText(''.join((data[0], '\n\n', data[2], '\n\n', str(len(data[3])), ' ', _("Enclosures")))) - else: - self["content"].setText(_("No such Item.")) - self.updateInfo() - - def selectEnclosure(self, ignore): - if self.data: - RSSBaseView.selectEnclosure(self, self.data[3]) - - -class RSSFeedView(RSSBaseView): - # Shows a RSS-Feed - skin = """ - - - - - {"template": [ - MultiContentEntryText(pos=(0, 3), size=(460, 294), font=0, flags = RT_HALIGN_LEFT|RT_WRAP, text = 0) - ], - "fonts": [gFont("Regular", 22)], - "itemHeight": 50 - } - - - - """ - - def __init__(self, session, feed=None, newItems=False, parent=None, rssPoller=None, id=None): - RSSBaseView.__init__(self, session, rssPoller, parent) - self.feed = feed - self.newItems = newItems - self.id = id - self["content"] = List(feed.history) if feed else List([]) - self["summary"] = StaticText() - self["info"] = StaticText() - if not newItems: - self["actions"] = ActionMap(["OkCancelActions", "ChannelSelectBaseActions", "MenuActions", "ColorActions"], - { - "ok": self.showCurrentEntry, - "cancel": self.close, - "nextBouquet": self.next, - "prevBouquet": self.previous, - "menu": self.menu, - "yellow": self.selectEnclosure, - }) - self.onLayoutFinish.append(self.__show) - self.onClose.append(self.__close) - self.timer = None - else: - self["actions"] = ActionMap(["OkCancelActions"], - { - "cancel": self.close, - }) - self.timer = eTimer() - self.timer.callback.append(self.timerTick) - self.onExecBegin.append(self.startTimer) - self["content"].onSelectionChanged.append(self.updateInfo) - self.onLayoutFinish.extend(( - self.updateInfo, - self.setConditionalTitle - )) - - def startTimer(self): - if self.timer: - self.timer.startLongTimer(5) - - def timerTick(self): - if self.timer: - self.timer.callback.remove(self.timerTick) - self.close() - - def __show(self): - self.rssPoller.addCallback(self.pollCallback) - - def __close(self): - if self.timer is not None: - self.timer.callback.remove(self.timerTick) - self.timer = None - self.rssPoller.removeCallback(self.pollCallback) - - def pollCallback(self, id=None): - print("[SimpleRSS] SimpleRSSFeed called back") - if (id is None or id + 1 == self.id) and self.feed: - self["content"].updateList(self.feed.history) - self.setConditionalTitle() - self.updateInfo() - - def setConditionalTitle(self): - if self.feed: - self.setTitle(_("Simple RSS Reader: %s") % (self.feed.title)) - - def updateInfo(self): - current_entry = self["content"].current - if current_entry: - self["summary"].text = current_entry[2] - cur_idx = self["content"].index - if self.feed: - self["info"].text = _("Entry %s/%s") % (cur_idx + 1, len(self.feed.history)) - summary_text = current_entry[0] - else: - self["summary"].text = _("Feed is empty.") - self["info"].text = "" - summary_text = _("Feed is empty.") - for x in self.onChangedEntry: - try: - x(summary_text) - except Exception: - pass - - def menu(self): - if self.id and self.id > 0: - self.singleUpdate(self.id - 1) - - def nextEntry(self): - self["content"].selectNext() - if self.feed: - return (self["content"].current, self["content"].index, len(self.feed.history)) - - def previousEntry(self): - self["content"].selectPrevious() - if self.feed: - return (self["content"].current, self["content"].index, len(self.feed.history)) - - def next(self): - # Show next Feed - if self.parent is not None: - (self.feed, self.id) = self.parent.nextFeed() - self["content"].list = self.feed.history - self["content"].index = 0 - self.updateInfo() - self.setConditionalTitle() # Update title - return (self.feed.title, self.feed.history, self.id) - if self.feed: - return (self.feed.title, self.feed.history, self.id) - - def previous(self): - # Show previous Feed - if self.parent is not None: - (self.feed, self.id) = self.parent.previousFeed() - self["content"].list = self.feed.history - self["content"].index = 0 - self.updateInfo() - self.setConditionalTitle() # Update title - return (self.feed.title, self.feed.history, self.id) - if self.feed: - return (self.feed.title, self.feed.history, self.id) - - def checkEmpty(self): - if self.id and self.feed and self.id > 0 and not len(self.feed.history): - self.singleUpdate(self.id - 1) - - def showCurrentEntry(self): - current_entry = self["content"].current - if not current_entry: # empty list - return - if self.feed: - self.session.openWithCallback(self.updateInfo, RSSEntryView, current_entry, cur_idx=self["content"].index, entries=len(self.feed.history), feedTitle=self.feed.title, parent=self) - - def selectEnclosure(self, ignore): - current_entry = self["content"].current - if current_entry: - RSSBaseView.selectEnclosure(self, current_entry[3]) - - -class RSSOverview(RSSBaseView): - # Shows an Overview over all RSS-Feeds known to rssPoller""" - skin = """ - - - - - """ - - def __init__(self, session, poller): - RSSBaseView.__init__(self, session, poller) - self["actions"] = ActionMap(["OkCancelActions", "MenuActions", "ColorActions"], - { - "ok": self.showCurrentEntry, - "cancel": self.close, - "menu": self.menu, - "yellow": self.selectEnclosure, - }) - self.fillFeeds() - # We always have at least "New Items"-Feed - self["content"] = RSSFeedList(self.feeds) - self["summary"] = StaticText(' '.join((str(len(self.feeds[0][0].history)), _("Entries")))) - self["info"] = StaticText(_("Feed %s/%s") % (1, len(self.feeds))) - self["content"].connectSelChanged(self.updateInfo) - self.onLayoutFinish.append(self.__show) - self.onClose.append(self.__close) - - def __show(self): - self.rssPoller.addCallback(self.pollCallback) - self.setTitle(_("Simple RSS Reader")) - - def __close(self): - self.rssPoller.removeCallback(self.pollCallback) - - def fillFeeds(self): - # Feedlist contains our virtual Feed and all real ones - self.feeds = [(self.rssPoller.newItemFeed,)] - self.feeds.extend([(feed,) for feed in self.rssPoller.feeds]) - - def pollCallback(self, id=None): - print("[SimpleRSS] SimpleRSS called back") - self.fillFeeds() - self["content"].setList(self.feeds) - self.updateInfo() - self["content"].invalidate() - - def updateInfo(self): - current_entry = self["content"].getCurrent() - self["summary"].text = ' '.join((str(len(current_entry.history)), _("Entries"))) - self["info"].text = _("Feed %s/%s") % (self["content"].getSelectedIndex() + 1, len(self.feeds)) - summary_text = current_entry.title - for x in self.onChangedEntry: - try: - x(summary_text) - except Exception: - pass - - def menu(self): - cur_idx = self["content"].getSelectedIndex() - possible_actions = ((_("Update Feed"), "update"), (_("Setup"), "setup"), (_("Close"), "close")) if cur_idx > 0 else ((_("Setup"), "setup"), (_("Close"), "close")) - self.session.openWithCallback(self.menuChoice, ChoiceBox, _("What to do?"), possible_actions) - - def menuChoice(self, result): - if result: - if result[1] == "update": - cur_idx = self["content"].getSelectedIndex() - if cur_idx > 0: - self.singleUpdate(cur_idx - 1) - elif result[1] == "setup": - self.session.openWithCallback(self.refresh, RSSSetup, rssPoller=self.rssPoller) - elif result[1] == "close": - self.close() - - def refresh(self): - current_entry = self["content"].getCurrent() - self.fillFeeds() - self["content"].setList(self.feeds) - self["content"].moveToEntry(current_entry) - self.updateInfo() - - def nextFeed(self): - self["content"].up() - return (self["content"].getCurrent(), self["content"].getSelectedIndex()) - - def previousFeed(self): - self["content"].down() - return (self["content"].getCurrent(), self["content"].getSelectedIndex()) - - def showCurrentEntry(self): - current_entry = self["content"].getCurrent() - self.session.openWithCallback(self.updateInfo, RSSFeedView, feed=current_entry, parent=self, rssPoller=self.rssPoller, id=self["content"].getSelectedIndex()) - - def selectEnclosure(self, ignore): - # Build a list of all enclosures in this feed - enclosures = [] - for entry in self["content"].getCurrent().history: - enclosures.extend(entry[3]) - if enclosures: - RSSBaseView.selectEnclosure(self, enclosures) diff --git a/simplerss/src/RSSSetup.py b/simplerss/src/RSSSetup.py deleted file mode 100644 index ca4ef490c7..0000000000 --- a/simplerss/src/RSSSetup.py +++ /dev/null @@ -1,193 +0,0 @@ -# PYTHON IMPORTS -from __future__ import print_function, absolute_import - -# ENIGMA IMPORTS -from Components.ActionMap import ActionMap -from Components.config import config, ConfigSubsection, ConfigEnableDisable, ConfigText, getConfigListEntry -from Components.ConfigList import ConfigListScreen -from Components.Pixmap import Pixmap -from Components.Sources.StaticText import StaticText -from Components.Sources.Boolean import Boolean -from Screens.MessageBox import MessageBox -from Screens.Screen import Screen - -# PLUGIN IMPORTS -from . import _ # for localized messages -from . import RSSTickerView - - -class RSSFeedEdit(ConfigListScreen, Screen): - """Edit an RSS-Feed""" - - def __init__(self, session, id): - Screen.__init__(self, session) - self.skinName = ["RSSFeedEdit", "Setup"] - s = config.plugins.simpleRSS.feed[id] - list = [getConfigListEntry(_("Autoupdate"), s.autoupdate), getConfigListEntry(_("Feed URI"), s.uri)] - ConfigListScreen.__init__(self, list, session) - self["key_red"] = StaticText(_("Cancel")) - self["key_green"] = StaticText(_("OK")) - - self["setupActions"] = ActionMap(["SetupActions"], - { - "save": self.save, - "cancel": self.keyCancel - }, -1) - self.id = id - self.onLayoutFinish.append(self.setCustomTitle) - - def setCustomTitle(self): - self.setTitle(_("Simple RSS Reader Setup")) - - def save(self): - config.plugins.simpleRSS.feed[self.id].save() - config.plugins.simpleRSS.feed.save() - self.close() - - -class RSSSetup(ConfigListScreen, Screen): - """Setup for SimpleRSS, quick-edit for Feed-URIs and settings present.""" - skin = """ - - - - - - - - - - - """ - - def __init__(self, session, rssPoller=None): - Screen.__init__(self, session) - self.rssPoller = rssPoller - self.createSetup() - config.plugins.simpleRSS.autostart.addNotifier(self.elementChanged, initial_call=False) - # Initialize ConfigListScreen - ConfigListScreen.__init__(self, self.list, session) - self["HelpWindow"] = Pixmap() - self["HelpWindow"].hide() - self["VKeyIcon"] = Boolean(False) - self["key_red"] = StaticText(_("Cancel")) - self["key_green"] = StaticText(_("OK")) - self["key_yellow"] = StaticText(_("New")) - self["key_blue"] = StaticText(_("Delete")) - self["setupActions"] = ActionMap(["SetupActions", "ColorActions"], - { - "blue": self.delete, - "yellow": self.new, - "save": self.keySave, - "cancel": self.keyCancel, - "ok": self.ok - }, -1) - self.onLayoutFinish.append(self.setCustomTitle) - self.onClose.append(self.abort) - - def setCustomTitle(self): - self.setTitle(_("Simple RSS Reader Setup")) - - def createSetup(self): - simpleRSS = config.plugins.simpleRSS - - # Create List of all Feeds - list = [getConfigListEntry(_("Feed"), x.uri) for x in simpleRSS.feed] - list.append(getConfigListEntry(_("Start automatically with Enigma2"), simpleRSS.autostart)) - # Save keep_running in instance as we want to dynamically add/remove it - self.keep_running = getConfigListEntry(_("Keep running in background"), simpleRSS.keep_running) - if not simpleRSS.autostart.value: - list.append(self.keep_running) - # Append Last two config Elements - list.extend(( - getConfigListEntry(_("Show new Messages as"), simpleRSS.update_notification), - getConfigListEntry(_("Update Interval (min)"), simpleRSS.interval), - )) - self.list = list - - def elementChanged(self, instance): - self.createSetup() - self["config"].setList(self.list) - - def notificationChanged(self, instance): - if instance and instance.value == "ticker": - if RSSTickerView.tickerView is None: - print("[SimpleRSS] Ticker instantiated on startup") - RSSTickerView.tickerView = self.session.instantiateDialog(RSSTickerView.RSSTickerView) - else: - if RSSTickerView.tickerView is not None: - self.session.deleteDialog(RSSTickerView.tickerView) - RSSTickerView.tickerView = None - - def delete(self): - self.session.openWithCallback(self.deleteConfirm, MessageBox, _("Really delete this entry?\nIt cannot be recovered!")) - - def deleteConfirm(self, result): - if result: - try: - id = self["config"].getCurrentIndex() - del config.plugins.simpleRSS.feed[id] - config.plugins.simpleRSS.feedcount.value -= 1 - except Exception: - pass - self.createSetup() - self["config"].setList(self.list) - - def ok(self): - id = self["config"].getCurrentIndex() - if id < len(config.plugins.simpleRSS.feed): - self.session.openWithCallback(self.refresh, RSSFeedEdit, id) - - def refresh(self): - # TODO: anything to be done here? - pass - - def new(self): - l = config.plugins.simpleRSS.feed - s = ConfigSubsection() - s.uri = ConfigText(default="http://", fixed_size=False) - s.autoupdate = ConfigEnableDisable(default=True) - id = len(l) - l.append(s) - self.session.openWithCallback(self.conditionalNew, RSSFeedEdit, id) - - def conditionalNew(self): - id = len(config.plugins.simpleRSS.feed) - 1 - uri = config.plugins.simpleRSS.feed[id].uri - # Check if new feed differs from default - if uri.value == "http://": - del config.plugins.simpleRSS.feed[id] - else: - config.plugins.simpleRSS.feedcount.value = id + 1 - self.createSetup() - self["config"].setList(self.list) - - def keySave(self): - # Tell Poller to recreate List if present - if self.rssPoller is not None: - self.rssPoller.triggerReload() - ConfigListScreen.keySave(self) - - def abort(self): - simpleRSS = config.plugins.simpleRSS - # Remove Notifier - simpleRSS.autostart.removeNotifier(self.elementChanged) - # Handle ticker - self.notificationChanged(simpleRSS.update_notification) - # Keep feedcount sane - simpleRSS.feedcount.value = len(simpleRSS.feed) - simpleRSS.feedcount.save() - - -def addFeed(address, auto=False): - l = config.plugins.simpleRSS.feed - # Create new Item - s = ConfigSubsection() - s.uri = ConfigText(default="http://", fixed_size=False) - s.autoupdate = ConfigEnableDisable(default=True) - # Set values - s.uri.value = address - s.autoupdate.value = auto - # Save - l.append(s) - l.save() diff --git a/simplerss/src/RSSTickerView.py b/simplerss/src/RSSTickerView.py deleted file mode 100644 index 0bb19c0013..0000000000 --- a/simplerss/src/RSSTickerView.py +++ /dev/null @@ -1,101 +0,0 @@ -# PYTHON IMPORTS -from six import PY2 - -# ENIGMA IMPORTS -from enigma import eTimer -from Components.Label import Label -from Screens.Screen import Screen - -# PLUGIN IMPORTS -from . import _ # for localized messages - - -class MovingLabel(Label): - """Simple Label which allows to display badly scrolling text.""" - - def __init__(self, text=""): - self.offset = 0 - self.displayLength = 100 - Label.__init__(self, text) - self.moveTimer = eTimer() - self.moveTimer.callback.append(self.doMove) - - def applySkin(self, desktop, screen): - if self.skinAttributes is not None: - attribs = [] - append = attribs.append - for attrib, value in self.skinAttributes: - if attrib == "displayLength": - self.displayLength = int(value) - else: - append((attrib, value)) - self.skinAttributes = attribs - return Label.applySkin(self, desktop, screen) - - def setText(self, text): - text = (self.displayLength * ' ') + text - self.longText = text - self.offset = 0 - text = text[:self.displayLength] - if PY2: - text = text.encode('utf-8', 'ignore') - Label.setText(self, text) - - def stopMoving(self): - self.moveTimer.stop() - self.offset = 0 - - def startMoving(self): - self.moveTimer.start(125) - - def doMove(self): - offset = self.offset + 1 - text = self.longText[offset:self.displayLength + offset] - self.offset = offset - if not text: - # it appears we're done displaying the full text, so stop now or waste cpu time forever :D - self.stopMoving() - try: - if PY2: - text = text.encode('utf-8', 'ignore') - Label.setText(self, text) - except Exception: - self.stopMoving() - - -class MovingCallbackLabel(MovingLabel): - """Extended MovingLabel that allows to set a callback when done scrolling.""" - - def __init__(self, text="", callback=None): - MovingLabel.__init__(self, text) - self.callback = callback - - def stopMoving(self): - MovingLabel.stopMoving(self) - if self.callback: - self.callback() - - -class RSSTickerView(Screen): # pragma mark RSSTickerView - skin = """ - - - - """ - - def __init__(self, session): - Screen.__init__(self, session) - self["newsLabel"] = MovingCallbackLabel(callback=self.hide) - - def updateText(self, feed): - text = _("New Items") + ': ' + ' +++ '.join((item[0].decode('utf-8') for item in feed.history)) - self["newsLabel"].setText(text) - - def display(self, feed=None): - if feed: - self.updateText(feed) - self.show() - self["newsLabel"].startMoving() - - -tickerView = None diff --git a/simplerss/src/feeds.xml b/simplerss/src/feeds.xml new file mode 100644 index 0000000000..c6b54a05a9 --- /dev/null +++ b/simplerss/src/feeds.xml @@ -0,0 +1,27 @@ + + + + Tagesschau.de + http://www.tagesschau.de/infoservices/alle-meldungen-100~rdf.xml + + + TV Spielfilm.de - TV-Tipps des Tages + https://www.tvspielfilm.de/tv-programm/rss/tipps.xml + + + kicker Teamnews FC Schalke 04 + https://newsfeed.kicker.de/team/fc-schalke-04 + + + Der Westen.de + https://www.derwesten.de/feed + + + SAT: Digitalfernsehen + http://www.digitalfernsehen.de/rss/rss.xml + + + SAT: Satellifax + http://www.satellifax.de/satellifax-rss.xml + + diff --git a/simplerss/src/plugin.py b/simplerss/src/plugin.py index afa461e8f4..eae373c8cd 100644 --- a/simplerss/src/plugin.py +++ b/simplerss/src/plugin.py @@ -1,24 +1,52 @@ # PYTHON IMPORTS -from __future__ import absolute_import +from os import remove +from os.path import join, exists +from requests import get, exceptions +from traceback import print_exc +from twisted.internet.reactor import callInThread +from xml.etree.cElementTree import fromstring # ENIGMA IMPORTS -from Components.config import config, ConfigSubsection, ConfigSubList, ConfigEnableDisable, ConfigNumber, ConfigText, ConfigSelection +from enigma import eTimer, eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT, RT_VALIGN_BOTTOM, RT_WRAP, BT_SCALE, BT_KEEP_ASPECT_RATIO, BT_HALIGN_CENTER, BT_VALIGN_CENTER +from Components.ActionMap import ActionMap +from Components.config import config, getConfigListEntry, ConfigSubsection, ConfigSubList, ConfigEnableDisable, ConfigNumber, ConfigText, ConfigSelection +from Components.ConfigList import ConfigListScreen +from Components.MenuList import MenuList +from Components.Label import Label +from Components.Pixmap import Pixmap from Components.PluginComponent import plugins -from Components.Scanner import Scanner, ScanPath +from Components.ScrollLabel import ScrollLabel +from Components.Sources.Boolean import Boolean +from Components.Sources.List import List +from Components.Sources.StaticText import StaticText +from Plugins.Extensions.PicturePlayer import ui from Plugins.Plugin import PluginDescriptor +from Plugins.SystemPlugins.Toolkit.TagStrip import strip, strip_readable +from Screens.ChoiceBox import ChoiceBox from Screens.MessageBox import MessageBox +from Screens.Screen import Screen +from skin import parseFont +from Tools import Notifications +from Tools.Notifications import AddPopup, RemovePopup, AddNotificationWithID # PLUGIN IMPORTS -from . import RSSTickerView, _ # for localized messages -from .RSSScreens import RSSOverview -from .RSSSetup import RSSSetup, addFeed -from .RSSPoller import RSSPoller -from .RSSPoller import RSSPoller +from . import _ # for localized messages + +# GLOBALS +rssPoller = None +tickerView = None +update_callbacks = [] +TEMPPATH = "/tmp/" +MODULE_NAME = __name__.split(".")[-2] +NOTIFICATIONID = 'SimpleRSSUpdateNotification' +NS_RDF = "{http://www.w3.org/1999/02/22-rdf-syntax-ns#}" +NS_RSS_09 = "{http://my.netscape.com/rdf/simple/0.9/}" +NS_RSS_10 = "{http://purl.org/rss/1.0/}" # Initialize Configuration config.plugins.simpleRSS = ConfigSubsection() simpleRSS = config.plugins.simpleRSS -simpleRSS.update_notification = ConfigSelection(choices=[("notification", _("Notification")), ("preview", _("Preview")), ("ticker", _("Ticker")), ("none", _("none"))], default="preview") +simpleRSS.update_notification = ConfigSelection(choices=[("notification", _("Notification")), ("preview", _("Preview")), ("ticker", _("Ticker")), ("none", _("none"))], default="ticker") simpleRSS.interval = ConfigNumber(default=15) simpleRSS.feedcount = ConfigNumber(default=0) simpleRSS.autostart = ConfigEnableDisable(default=False) @@ -33,105 +61,1163 @@ i += 1 del s del simpleRSS, i -# Global Poller-Object -rssPoller = None -# Main Function - -def main(session, **kwargs): - # Get Global rssPoller-Object - global rssPoller - # Create one if we have none (no autostart) - if rssPoller is None: +def main(session, **kwargs): # Main Function + global rssPoller # Get Global rssPoller-Object + if rssPoller is None: # Create one if we have none (no autostart) rssPoller = RSSPoller() - # Show Overview when we have feeds - if rssPoller.feeds: + if rssPoller.feeds: # Show Overview when we have feeds session.openWithCallback(closed, RSSOverview, rssPoller) - # Show Setup otherwise - else: - session.openWithCallback(closed, RSSSetup, rssPoller) -# Plugin window has been closed + else: # Show Setup otherwise + session.openWithCallback(closed, RSSSetup, rssPoller) # Plugin window has been closed -def closed(): - # If SimpleRSS should not run in Background: shutdown +def closed(): # If SimpleRSS should not run in Background: shutdown if not (config.plugins.simpleRSS.autostart.value or config.plugins.simpleRSS.keep_running.value): - # Get Global rssPoller-Object - global rssPoller + global rssPoller # Get Global rssPoller-Object if rssPoller: rssPoller.shutdown() rssPoller = None -# Autostart - - -def autostart(reason, **kwargs): - global rssPoller - - if "session" in kwargs and config.plugins.simpleRSS.update_notification.value == "ticker": - if RSSTickerView.tickerView is None: - RSSTickerView.tickerView = kwargs["session"].instantiateDialog(RSSTickerView.RSSTickerView) +def autostart(reason, **kwargs): # Autostart + global rssPoller, tickerView + if "session" in kwargs and config.plugins.simpleRSS.update_notification.value == "ticker" and tickerView is None: + tickerView = kwargs["session"].instantiateDialog(RSSTickerView) # Instanciate when enigma2 is launching, autostart active and session present or installed during runtime - if reason == 0 and config.plugins.simpleRSS.autostart.value and \ - (not plugins.firstRun or "session" in kwargs): + if reason == 0 and config.plugins.simpleRSS.autostart.value and (not plugins.firstRun or "session" in kwargs): rssPoller = RSSPoller() elif reason == 1 and rssPoller is not None: rssPoller.shutdown() rssPoller = None -# Filescan - - -def filescan_open(item, session, **kwargs): - # Add earch feed - for each in item: - addFeed(each) - # Display Message - session.open(MessageBox, _("%d Feed(s) were added to configuration.") % (len(item)), type=MessageBox.TYPE_INFO, timeout=5) - # Filescanner - - -def filescan(**kwargs): - # Overwrite checkFile to detect remote files - class RemoteScanner(Scanner): - def checkFile(self, file): - return file.path.startswith(("http://", "https://")) - return [RemoteScanner(mimetypes=("application/rss+xml", "application/atom+xml"), - paths_to_scan=(ScanPath(path="", - with_subdirs=False),), - name="RSS-Reader", - description=_("Subscribe Newsfeed..."), - openfnc=filescan_open,) - ] + +class MovingLabel(Label): # Simple Label which allows to display badly scrolling text. + def __init__(self, text=""): + self.offset = 0 + self.displayLength = 100 + Label.__init__(self, text) + self.moveTimer = eTimer() + self.moveTimer.callback.append(self.doMove) + + def applySkin(self, desktop, screen): + if self.skinAttributes is not None: + attribs = [] + append = attribs.append + for attrib, value in self.skinAttributes: + if attrib == "displayLength": + self.displayLength = int(value) + else: + append((attrib, value)) + self.skinAttributes = attribs + return Label.applySkin(self, desktop, screen) + + def setText(self, text): + text = (self.displayLength * " ") + text + self.longText = text + self.offset = 0 + text = text[:self.displayLength] + Label.setText(self, text) + + def stopMoving(self): + self.moveTimer.stop() + self.offset = 0 + + def startMoving(self): + self.moveTimer.start(125) + + def doMove(self): + offset = self.offset + 1 + text = self.longText[offset:self.displayLength + offset] + self.offset = offset + if not text: + self.stopMoving() # it appears we're done displaying the full text, so stop now or waste cpu time forever :D + try: + Label.setText(self, text) + except Exception: + self.stopMoving() + + +class MovingCallbackLabel(MovingLabel): # Extended MovingLabel that allows to set a callback when done scrolling. + def __init__(self, text="", callback=None): + MovingLabel.__init__(self, text) + self.callback = callback + + def stopMoving(self): + MovingLabel.stopMoving(self) + if self.callback: + self.callback() + + +class RSSTickerView(Screen): # pragma mark RSSTickerView, kinda sucks because of overscan, but gives me "good enough" results + skin = """ + + + """ + + def __init__(self, session): + Screen.__init__(self, session) + self["newsLabel"] = MovingCallbackLabel(callback=self.hide) + + def updateText(self, feed): + text = _("New Items") + ': ' + ' +++ '.join((item[0] for item in feed.history)) + self["newsLabel"].setText(text) + + def display(self, feed=None): + if feed: + self.updateText(feed) + self.show() + self["newsLabel"].startMoving() + + +class RSSFeedEdit(ConfigListScreen, Screen): # Edit an RSS-Feed + def __init__(self, session, ident): + Screen.__init__(self, session) + self.ident = ident + self.skinName = ["RSSFeedEdit", "Setup"] + s = config.plugins.simpleRSS.feed[ident] + clist = [getConfigListEntry(_("Autoupdate"), s.autoupdate), getConfigListEntry(_("Feed URI"), s.uri)] + ConfigListScreen.__init__(self, clist, session) + self["key_red"] = StaticText(_("Cancel")) + self["key_green"] = StaticText(_("OK")) + self["setupActions"] = ActionMap(["SetupActions"], + { + "save": self.save, + "cancel": self.keyCancel + }, -1) + self.onLayoutFinish.append(self.setCustomTitle) + + def setCustomTitle(self): + self.setTitle(_("Simple RSS Reader Setup")) + + def save(self): + config.plugins.simpleRSS.feed[self.ident].save() + config.plugins.simpleRSS.feed.save() + self.close() + + +class RSSSetup(ConfigListScreen, Screen): # Setup for SimpleRSS, quick-edit for Feed-URIs and settings present. + skin = """ + + + + + + + + + + + + + """ + + def __init__(self, session, rssPoller=None): + Screen.__init__(self, session) + self.rssPoller = rssPoller + self.createSetup() + config.plugins.simpleRSS.autostart.addNotifier(self.elementChanged, initial_call=False) + ConfigListScreen.__init__(self, self.list, session) # Initialize ConfigListScreen + self["VKeyIcon"] = Boolean(False) + self["key_red"] = StaticText(_("Cancel")) + self["key_green"] = StaticText(_("OK")) + self["key_yellow"] = StaticText(_("New")) + self["key_blue"] = StaticText(_("Delete")) + self["keymenu"] = StaticText(_("Import from '%sfeeds.xml'") % TEMPPATH) + self["content"] = List([]) + self["setupActions"] = ActionMap(["SetupActions", "ColorActions", "MenuActions"], + { + "blue": self.delete, + "yellow": self.new, + "save": self.keySave, + "menu": self.importFeedlist, + "cancel": self.keyCancel, + "ok": self.ok + }, -1) + self.onLayoutFinish.append(self.setCustomTitle) + self.onClose.append(self.abort) + + def setCustomTitle(self): + self.setTitle(_("Simple RSS Reader Setup")) + + def createSetup(self): + simpleRSS = config.plugins.simpleRSS + flist = [getConfigListEntry(_("Feed"), x.uri) for x in simpleRSS.feed] # Create List of all Feeds + flist.append(getConfigListEntry(_("Start automatically with Enigma2"), simpleRSS.autostart)) + self.keep_running = getConfigListEntry(_("Keep running in background"), simpleRSS.keep_running) # Save keep_running in instance as we want to dynamically add/remove it + if not simpleRSS.autostart.value: + flist.append(self.keep_running) + flist.extend((getConfigListEntry(_("Show new Messages as"), simpleRSS.update_notification), getConfigListEntry(_("Update Interval (min)"), simpleRSS.interval),)) # Append Last two config Elements + self.list = flist + + def elementChanged(self, instance): + self.createSetup() + self["config"].setList(self.list) + + def notificationChanged(self, instance): + global tickerView + if instance and instance.value == "ticker": + if tickerView is None: + print("[%s] Ticker instantiated on startup" % MODULE_NAME) + tickerView = self.session.instantiateDialog(RSSTickerView) + else: + if tickerView is not None: + self.session.deleteDialog(tickerView) + tickerView = None + + def delete(self): + self.session.openWithCallback(self.deleteConfirm, MessageBox, _("Really delete this entry?\nIt cannot be recovered!"), MessageBox.TYPE_YESNO, default=False) + + def deleteConfirm(self, result): + if result: + ident = self["config"].getCurrentIndex() + del config.plugins.simpleRSS.feed[ident] + config.plugins.simpleRSS.feedcount.value -= 1 + config.plugins.simpleRSS.feedcount.save() + self.createSetup() + self["config"].setList(self.list) + + def ok(self): + ident = self["config"].getCurrentIndex() + if ident < len(config.plugins.simpleRSS.feed): + self.session.open(RSSFeedEdit, ident) + + def importFeedlist(self): + feedfile = join(TEMPPATH, "feeds.xml") + if exists(feedfile): + success = 0 + dupes = 0 + try: + simpleRSS = config.plugins.simpleRSS + with open(feedfile, "r") as f: + xmlroot = fromstring(f.read()) + for child in xmlroot: + if child.tag == "feed" and child[1].tag == "url": + uri = child[1].text + if uri in [x.uri.value for x in config.plugins.simpleRSS.feed]: + print("[%s] Found double feed: '%s'" % (MODULE_NAME, uri)) + dupes += 1 + else: + ident = self.addEntry() + print("[%s] Feed was imported: '%s'" % (MODULE_NAME, uri)) + simpleRSS.feed[ident].uri.value = uri + simpleRSS.feed[ident].save() + simpleRSS.feedcount.value += 1 + success += 1 + if success: + simpleRSS.feedcount.save() + simpleRSS.feed.save() + except Exception as err: + print("[%s] ERROR in module 'importFeedlist' - xml-file was corrupt:\n%s" % (MODULE_NAME, str(err))) + self.session.open(MessageBox, _("Xml-file '%s' was corrupt:\n%s" % (feedfile, str(err))), type=MessageBox.TYPE_ERROR, timeout=5) + return + print("[%s] Importing '%s': %s successfully, %s double" % (MODULE_NAME, feedfile, success, dupes)) + self.session.open(MessageBox, _("Importing '%s'\n%s feeds were imported successfully\n%s feeds were double and not imported") % (feedfile, success, dupes), type=MessageBox.TYPE_INFO, timeout=10) + else: + print("[%s] File '%s' was not found, import was aborted!" % (MODULE_NAME, feedfile)) + self.session.open(MessageBox, _("File '%s' was not found, import was aborted!" % feedfile), type=MessageBox.TYPE_ERROR, timeout=5) + + def addEntry(self): # create entry + l = config.plugins.simpleRSS.feed + s = ConfigSubsection() + s.uri = ConfigText(default="http://", fixed_size=False) + s.autoupdate = ConfigEnableDisable(default=True) + ident = len(l) + l.append(s) + return ident + + def new(self): + self.session.openWithCallback(self.conditionalNew, RSSFeedEdit, self.addEntry()) # use default + + def conditionalNew(self): + ident = len(config.plugins.simpleRSS.feed) - 1 + uri = config.plugins.simpleRSS.feed[ident].uri + if uri.value == "http://": # Check if new feed differs from default + del config.plugins.simpleRSS.feed[ident] + else: + config.plugins.simpleRSS.feedcount.value = ident + 1 + self.createSetup() + self["config"].setList(self.list) + + def keySave(self): # Tell Poller to recreate List if present + if self.rssPoller is not None: + self.rssPoller.triggerReload() + ConfigListScreen.keySave(self) + + def abort(self): + simpleRSS = config.plugins.simpleRSS + simpleRSS.autostart.removeNotifier(self.elementChanged) # Remove Notifier + self.notificationChanged(simpleRSS.update_notification) # Handle ticker + simpleRSS.feedcount.value = len(simpleRSS.feed) # Keep feedcount sane + simpleRSS.feedcount.save() + + +class RSSSummary(Screen): + skin = """ + + + + + WithSeconds + + """ + + def __init__(self, session, parent): + Screen.__init__(self, session, parent=parent) + self["entry"] = StaticText("") + parent.onChangedEntry.append(self.selectionChanged) + self.onShow.append(parent.updateInfo) + self.onClose.append(self.removeWatcher) + + def removeWatcher(self): + self.parent.onChangedEntry.remove(self.selectionChanged) + + def selectionChanged(self, text): + self["entry"].text = text + + +class RSSBaseView(Screen): # Base Screen for all Screens used in SimpleRSS + def __init__(self, session, poller, parent=None): + Screen.__init__(self, session, parent) + self.onChangedEntry = [] + self.rssPoller = poller + self.pollDialog = None + + def createSummary(self): + return RSSSummary + + def errorPolling(self, errmsg=""): # An error occured while polling + self.session.open(MessageBox, _("Error while parsing Feed, this usually means there is something wrong with it."), type=MessageBox.TYPE_ERROR, timeout=3) + if self.pollDialog: # Don't show "we're updating"-dialog any longer + self.pollDialog.close() + self.pollDialog = None + + def singleUpdate(self, feedid): # Don't do anything if we have no poller + if self.rssPoller: + callInThread(self.rssPoller.singlePoll, feedid, errorback=self.errorPolling) # Tell Poller to poll + # Open Dialog and save locally + self.pollDialog = self.session.open(MessageBox, _("Update is being done in Background.\nContents will automatically be updated when it's done."), type=MessageBox.TYPE_INFO, timeout=3) + + def selectEnclosure(self, enclosures, show=True): # Empty List + if enclosures: + return self.showEnclosure(enclosures, show) +# else: +# self.session.open(MessageBox, _("Found no Enclosure we can display."), type=MessageBox.TYPE_INFO, timeout=3) + + def showEnclosure(self, enclosures, show=True): + filelist = [] + index = 0 + for enclosure in enclosures: + if enclosure[1] in ["image/jpg", "image/png", "image/gif"]: + filename = enclosure[0][enclosure[0].rfind("/") + 1:].lower() + if self.pollEnclosure(enclosure[0], join(TEMPPATH, filename)): + filelist.append(((join(TEMPPATH, filename), False), None)) + index = len(filelist) - 1 + if filelist: + if show: + self.session.open(ui.Pic_Full_View, filelist, index, TEMPPATH) + return filelist + + def pollEnclosure(self, url, filename): + header = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0", "Accept": "text/xml"} + if url: + response = get + try: + response = get(url.encode(), headers=header, timeout=(3.05, 6)) + response.raise_for_status() + except exceptions.RequestException as err: + print("[%s] ERROR in module 'pollEnclosure': '%s" % (MODULE_NAME, str(err))) + try: + if not exists(filename): + with open(filename, "wb") as f: + f.write(response.content) + return True + except Exception as err: + errmsg = "[%s] ERROR in module 'pollEnclosure': invalid xml data from server. %s" % (MODULE_NAME, str(err)) + print(errmsg) + else: + errmsg = "[%s] ERROR in module 'pollEnclosure': missing link." % MODULE_NAME + print(errmsg) + + +class RSSEntryView(RSSBaseView): # Shows a RSS Item + skin = """ + + + + + """ + + def __init__(self, session, data, feedTitle="", cur_idx=None, entries=None, parent=None): + RSSBaseView.__init__(self, session, None, parent) + self.data = data + self.feedTitle = feedTitle + self.cur_idx = cur_idx + self.entries = entries + self["info"] = StaticText(_("Entry %s/%s") % (cur_idx + 1, entries)) if cur_idx is not None and entries is not None else StaticText() + self["content"] = ScrollLabel(''.join((data[0], '\n\n', data[2], '\n\n', str(len(data[3])), ' ', _("Enclosures")))) if data else ScrollLabel() + self["picture"] = Pixmap() + self["actions"] = ActionMap(["OkCancelActions", "ChannelSelectBaseActions", "ColorActions", "DirectionActions"], + { + "cancel": self.close, + "ok": self.selectEnclosure, + "yellow": self.selectEnclosure, + "up": self.up, + "down": self.down, + "right": self.next, + "left": self.previous, + "nextBouquet": self.nextFeed, + "prevBouquet": self.previousFeed, + }) + self.filelist = self.selectEnclosure(False) + self.onLayoutFinish.append(self.setConditionalTitle) + self.onClose.append(self.removeEnclosures) + + def setConditionalTitle(self): + self["picture"].hide() + self.setTitle(_("Simple RSS Reader: %s") % (self.feedTitle)) + self.setContent() + + def updateInfo(self): + text = self.data[0] if self.data else _("No such Item.") + for x in self.onChangedEntry: + x(text) + + def up(self): + self["content"].pageUp() + + def down(self): + self["content"].pageDown() + + def next(self): + if self.parent is not None: + (self.data, self.cur_idx, self.entries) = self.parent.nextEntry() + self.setContent() + + def previous(self): + if self.parent is not None: + (self.data, self.cur_idx, self.entries) = self.parent.previousEntry() + self.setContent() + + def nextFeed(self): # Show next Feed + if self.parent is not None: + self.showFeed(self.parent.next) + + def previousFeed(self): # Show previous Feed + if self.parent is not None: + self.showFeed(self.parent.previous) + + def showFeed(self, direction): # Show desired Feed + result = direction() + self.feedTitle = result[0] + self.entries = len(result[1]) + if self.entries: + self.cur_idx = 0 + self.data = result[1][0] + else: + self.cur_idx = None + self.data = None + self.setConditionalTitle() + self.setContent() + + def setContent(self): + if self.cur_idx is not None and self.entries is not None: + self["info"].text = _("Entry %s/%s") % (self.cur_idx + 1, self.entries) + else: + self["info"].text = "" + data = self.data + if data: + self["content"].setText(''.join((data[0], '\n\n', data[2], '\n\n', str(len(data[3])), ' ', _("Enclosures")))) + else: + self["content"].setText(_("No such Item.")) + if self.filelist: + picfile = join(TEMPPATH, self.filelist[0][0][0]) + if exists(picfile): + self["picture"].instance.setPixmapScaleFlags(BT_SCALE | BT_KEEP_ASPECT_RATIO | BT_HALIGN_CENTER | BT_VALIGN_CENTER) + self["picture"].instance.setPixmapFromFile(picfile) + self["picture"].show() + self.updateInfo() + + def selectEnclosure(self, show=True): + if self.data: + return RSSBaseView.selectEnclosure(self, self.data[3], show) + + def removeEnclosures(self): + if self.filelist: + for file in self.filelist: + if exists(file[0][0]): + remove(file[0][0]) + + +class RSSFeedView(RSSBaseView): # Shows a RSS-Feed + skin = """ + + + + + {"template": [ + MultiContentEntryText(pos=(0, 3), size=(460, 294), font=0, flags = RT_HALIGN_LEFT|RT_WRAP, text = 0) + ], + "fonts": [gFont("Regular", 22)], + "itemHeight": 50 + } + + + + """ + + def __init__(self, session, feed=None, newItems=False, parent=None, rssPoller=None, ident=None): + RSSBaseView.__init__(self, session, rssPoller, parent) + self.feed = feed + self.newItems = newItems + self.ident = ident + self["content"] = List(feed.history) if feed else List([]) + self["summary"] = StaticText() + self["info"] = StaticText() + if not newItems: + self["actions"] = ActionMap(["OkCancelActions", "ChannelSelectBaseActions", "MenuActions", "ColorActions"], + { + "ok": self.showCurrentEntry, + "cancel": self.close, + "nextBouquet": self.next, + "prevBouquet": self.previous, + "menu": self.menu, + "yellow": self.selectEnclosure, + }) + self.onLayoutFinish.append(self.__show) + self.onClose.append(self.__close) + self.timer = None + else: + self["actions"] = ActionMap(["OkCancelActions"], + { + "cancel": self.close, + }) + self.timer = eTimer() + self.timer.callback.append(self.timerTick) + self.onExecBegin.append(self.startTimer) + self["content"].onSelectionChanged.append(self.updateInfo) + self.onLayoutFinish.extend((self.updateInfo, self.setConditionalTitle)) + + def startTimer(self): + if self.timer: + self.timer.startLongTimer(5) + + def timerTick(self): + if self.timer: + self.timer.callback.remove(self.timerTick) + self.close() + + def __show(self): + self.rssPoller.addCallback(self.pollCallback) + + def __close(self): + if self.timer is not None: + self.timer.callback.remove(self.timerTick) + self.timer = None + self.rssPoller.removeCallback(self.pollCallback) + + def pollCallback(self, ident=None): + print("[%s] SimpleRSSFeed called back" % MODULE_NAME) + if (ident is None or ident + 1 == self.ident) and self.feed: + self["content"].updateList(self.feed.history) + self.setConditionalTitle() + self.updateInfo() + + def setConditionalTitle(self): + if self.feed: + self.setTitle(_("Simple RSS Reader: %s") % (self.feed.title)) + + def updateInfo(self): + current_entry = self["content"].current + if current_entry: + self["summary"].text = current_entry[2] + cur_idx = self["content"].index + if self.feed: + self["info"].text = _("Entry %s/%s") % (cur_idx + 1, len(self.feed.history)) + summary_text = current_entry[0] + else: + self["summary"].text = _("Feed is empty.") + self["info"].text = "" + summary_text = _("Feed is empty.") + for x in self.onChangedEntry: + x(summary_text) + + def menu(self): + if self.ident and self.id > 0: + self.singleUpdate(self.ident - 1) + + def nextEntry(self): + self["content"].selectNext() + if self.feed: + return (self["content"].current, self["content"].index, len(self.feed.history)) + + def previousEntry(self): + self["content"].selectPrevious() + if self.feed: + return (self["content"].current, self["content"].index, len(self.feed.history)) + + def next(self): + if self.parent is not None: # Show next Feed + (self.feed, self.ident) = self.parent.nextFeed() + self["content"].list = self.feed.history + self["content"].index = 0 + self.updateInfo() + self.setConditionalTitle() # Update title + return (self.feed.title, self.feed.history, self.ident) + if self.feed: + return (self.feed.title, self.feed.history, self.ident) + + def previous(self): + if self.parent is not None: # Show previous Feed + (self.feed, self.id) = self.parent.previousFeed() + self["content"].list = self.feed.history + self["content"].index = 0 + self.updateInfo() + self.setConditionalTitle() # Update title + return (self.feed.title, self.feed.history, self.ident) + if self.feed: + return (self.feed.title, self.feed.history, self.ident) + + def checkEmpty(self): + if self.ident and self.feed and self.ident > 0 and not len(self.feed.history): + self.singleUpdate(self.ident - 1) + + def showCurrentEntry(self): + current_entry = self["content"].current + if current_entry and self.feed: + self.session.openWithCallback(self.updateInfo, RSSEntryView, current_entry, cur_idx=self["content"].index, entries=len(self.feed.history), feedTitle=self.feed.title, parent=self) + + def selectEnclosure(self): + current_entry = self["content"].current + if current_entry: + RSSBaseView.selectEnclosure(self, current_entry[3]) + + +class RSSOverview(RSSBaseView): # Shows an Overview over all RSS-Feeds known to rssPoller + skin = """ + + + + + """ + + def __init__(self, session, poller): + RSSBaseView.__init__(self, session, poller) + self["actions"] = ActionMap(["OkCancelActions", "MenuActions", "ColorActions", "ChannelSelectBaseActions"], + { + "ok": self.showCurrentEntry, + "cancel": self.close, + "menu": self.menu, + "yellow": self.selectEnclosure, + "nextBouquet": self.keyPageDown, + "prevBouquet": self.keyPageUp, + }) + self.fillFeeds() + self["content"] = RSSFeedList(self.feeds) # We always have at least "New Items"-Feed + self["summary"] = StaticText(' '.join((str(len(self.feeds[0][0].history)), _("Entries")))) + self["info"] = StaticText(_("Feed %s/%s") % (1, len(self.feeds))) + self["content"].connectSelChanged(self.updateInfo) + self.onLayoutFinish.append(self.__show) + self.onClose.append(self.__close) + + def __show(self): + self.rssPoller.addCallback(self.pollCallback) + self.setTitle(_("Simple RSS Reader")) + + def __close(self): + global tickerView + self.rssPoller.removeCallback(self.pollCallback) + if tickerView is not None: + self.session.deleteDialog(tickerView) + tickerView = None + + def fillFeeds(self): # Feedlist contains our virtual Feed and all real ones + self.feeds = [(self.rssPoller.newItemFeed,)] + self.feeds.extend([(feed,) for feed in self.rssPoller.feeds]) + + def pollCallback(self, ident=None): + print("[%s] SimpleRSS called back" % MODULE_NAME) + self.fillFeeds() + self["content"].setList(self.feeds) + self.updateInfo() + self["content"].invalidate() + + def updateInfo(self): + current_entry = self["content"].getCurrent() + self["summary"].text = ' '.join((str(len(current_entry.history)), _("Entries"))) + self["info"].text = _("Feed %s/%s") % (self["content"].getSelectedIndex() + 1, len(self.feeds)) + summary_text = current_entry.title + for x in self.onChangedEntry: + x(summary_text) + + def menu(self): + cur_idx = self["content"].getSelectedIndex() + possible_actions = ((_("Update Feed"), "update"), (_("Setup"), "setup"), (_("Close"), "close")) if cur_idx > 0 else ((_("Setup"), "setup"), (_("Close"), "close")) + self.session.openWithCallback(self.menuChoice, ChoiceBox, _("What to do?"), possible_actions) + + def menuChoice(self, result): + if result: + if result[1] == "update": + cur_idx = self["content"].getSelectedIndex() + if cur_idx > 0: + self.singleUpdate(cur_idx - 1) + elif result[1] == "setup": + self.session.openWithCallback(self.refresh, RSSSetup, rssPoller=self.rssPoller) + elif result[1] == "close": + self.close() + + def refresh(self): + current_entry = self["content"].getCurrent() + self.fillFeeds() + self["content"].setList(self.feeds) + self["content"].moveToEntry(current_entry) + self.updateInfo() + + def nextFeed(self): + self["content"].up() + return (self["content"].getCurrent(), self["content"].getSelectedIndex()) + + def previousFeed(self): + self["content"].down() + return (self["content"].getCurrent(), self["content"].getSelectedIndex()) + + def keyPageUp(self): + self["content"].pageUp() + + def keyPageDown(self): + self["content"].pageDown() + + def showCurrentEntry(self): + current_entry = self["content"].getCurrent() + if current_entry and self.rssPoller: + self.session.openWithCallback(self.updateInfo, RSSFeedView, feed=current_entry, parent=self, rssPoller=self.rssPoller, ident=self["content"].getSelectedIndex()) + + def selectEnclosure(self): + enclosures = [] # Build a list of all enclosures in this feed + for entry in self["content"].getCurrent().history: + enclosures.extend(entry[3]) + if enclosures: + RSSBaseView.selectEnclosure(self, enclosures) + + +class RSSPoller: # Keeps all Feed and takes care of (automatic) updates + def __init__(self, poll=True): + self.poll_timer = eTimer() # Timer + self.poll_timer.callback.append(self.poll) + self.do_poll = poll + self.reloading = False # this indicates we're reloading the list of feeds + self.newItemFeed = BaseFeed("", _("New Items"), _("New Items since last Auto-Update"),) + self.feeds = [UniversalFeed(x.uri.value, x.autoupdate.value) for x in config.plugins.simpleRSS.feed] # Generate Feeds + if poll and self.poll_timer: + self.poll_timer.start(0, 1) + self.current_feed = 0 # Initialize Vars + + def addCallback(self, callback): + if callback not in update_callbacks: + update_callbacks.append(callback) + + def removeCallback(self, callback): + if callback in update_callbacks: + update_callbacks.remove(callback) + + def doCallback(self, ident=None): + for callback in update_callbacks: + callback(id) + + def error(self, error=""): + print("[%s] failed to fetch feed: %s" % (MODULE_NAME, str(error))) + self.next_feed() # Assume its just a temporary failure and jump over to next feed + + def _gotPage(self, ident=None, callback=False, errorback=None, data=None): + try: # workaround: exceptions in gotPage-callback were ignored + self.gotPage(data, ident) + if callback: + self.doCallback(ident) + except NotImplementedError as errmsg: + if ident is not None: # Don't show this error when updating in background + AddPopup(_("Sorry, this type of feed is unsupported:\n%s") % str(errmsg), MessageBox.TYPE_INFO, 5,) + else: + self.next_feed() # We don't want to stop updating just because one feed is broken + except Exception: + print_exc() + if errorback is not None: # Errorback given, call it (asumme we don't need do restart timer!) + errorback() + return + self.next_feed() # Assume its just a temporary failure and jump over to next feed + + def singlePoll(self, feedid, errorback=None): + self.pollXml(self.feeds[feedid].uri, errorback) + + def pollXml(self, feeduri, errorback=None): + header = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0", "Accept": "text/xml"} + if feeduri: + response = get + try: + response = get(feeduri.encode(), headers=header, timeout=(3.05, 6)) + response.raise_for_status() + except exceptions.RequestException as err: + print("[%s] ERROR in module 'pollXml': '%s" % (MODULE_NAME, str(err))) + if errorback: + errorback(str(err)) + try: + xmlData = response.content + if xmlData: + self.gotPage(xmlData) + else: + print("[%s] ERROR in module 'pollXml': server access failed, no xml-data found." % MODULE_NAME) + except Exception as err: + print("[%s] ERROR in module 'pollXml': invalid xml data from server. %s" % (MODULE_NAME, str(err))) + if errorback: + errorback(str(err)) + else: + print("[%s] ERROR in module 'pollXml': missing link." % MODULE_NAME) + + def gotPage(self, data, ident=None): + feed = fromstring(data.decode()) + if ident is not None: # For Single-Polling + self.feeds[ident].gotFeed(feed) + print("[%s] single feed parsed..." % MODULE_NAME) + return + new_items = self.feeds[self.current_feed].gotFeed(feed) + print("[%s] feed parsed..." % MODULE_NAME) + if new_items is not None: # Append new items to locally bound ones + self.newItemFeed.history.extend(new_items) + self.next_feed() # Start Timer so we can either fetch next feed or show new_items + + def poll(self): + if self.reloading: # Reloading, reschedule + print("[%s] timer triggered while reloading, rescheduling" % MODULE_NAME) + if self.poll_timer: + self.poll_timer.start(10000, 1) + elif len(self.feeds) <= self.current_feed: # End of List + if self.newItemFeed.history: # New Items + print("[%s] got new items, calling back" % MODULE_NAME) + self.doCallback() + update_notification_value = config.plugins.simpleRSS.update_notification.value # Inform User + if update_notification_value == "preview": + RemovePopup(NOTIFICATIONID) +# AddNotificationWithID(NOTIFICATIONID, RSSFeedView, feed=self.newItemFeed, newItems=True) # ToDo: makes trobles when leaving plugin first time. + elif update_notification_value == "notification": + AddPopup(_("Received %d new news item(s).") % (len(self.newItemFeed.history)), MessageBox.TYPE_INFO, 5, NOTIFICATIONID) + elif update_notification_value == "ticker": + if tickerView: + tickerView.display(self.newItemFeed) + else: + print("[%s] missing ticker instance, something is wrong with the code" % MODULE_NAME) + else: # No new Items + print("[%s] no new items" % MODULE_NAME) + self.current_feed = 0 + if self.poll_timer: + self.poll_timer.startLongTimer(config.plugins.simpleRSS.interval.value * 60) + else: # It's updating-time + clearHistory = self.current_feed == 0 # Assume we're cleaning history if current feed is 0 + if config.plugins.simpleRSS.update_notification.value != "none": + if hasattr(Notifications.notifications, 'Notifications.notificationQueue'): + Xnotifications = Notifications.notificationQueue.queue + Xcurrent_notifications = Notifications.notificationQueue.current + handler = lambda note: (note.fnc, note.screen, note.args, note.kwargs, note.id) + handler_current = lambda note: (note[0].id,) + else: + Xnotifications = Notifications.notifications + Xcurrent_notifications = Notifications.current_notifications + handler_current = handler = lambda note: note + for x in Xcurrent_notifications: + if handler_current(x)[0] == NOTIFICATIONID: + print("[%s] timer triggered while preview on screen, rescheduling" % MODULE_NAME) + if self.poll_timer: + self.poll_timer.start(10000, 1) + if clearHistory: + for x in Xnotifications: + if handler(x)[4] == NOTIFICATIONID: + print("[%s] wont wipe history because it was never read" % MODULE_NAME) + clearHistory = False + break + if clearHistory: + del self.newItemFeed.history[:] + feed = self.feeds[self.current_feed] # Feed supposed to autoupdate + if feed.autoupdate: + self.pollXml(feed.uri, self.error) + else: # Go to next feed + print("[%s] passing feed sucessfully" % MODULE_NAME) + self.next_feed() + + def next_feed(self): + self.current_feed += 1 + if self.poll_timer: + self.poll_timer.start(1000, 1) + + def shutdown(self): + if self.poll_timer: + self.poll_timer.callback.remove(self.poll) + self.poll_timer = None + self.do_poll = False + + def triggerReload(self): + self.reloading = True + newfeeds = [] + oldfeeds = self.feeds + found = False + for x in config.plugins.simpleRSS.feed: + for feed in oldfeeds: + if x.uri.value == feed.uri: + feed.autoupdate = x.autoupdate.value # Update possibly different autoupdate value + newfeeds.append(feed) # Append to new Feeds + oldfeeds.remove(feed) # Remove from old Feeds + found = True + break + if not found: + newfeeds.append(UniversalFeed(x.uri.value, x.autoupdate.value)) + found = False + self.feeds = newfeeds + self.reloading = False + self.poll() + + +class RSSFeedList(MenuList): + def __init__(self, entries): + MenuList.__init__(self, entries, False, content=eListboxPythonMultiContent) + l = self.l + l.setFont(0, gFont("Regular", 22)) + self.descriptionFont = gFont("Regular", 20) + l.setFont(1, self.descriptionFont) + l.setItemHeight(115) + l.setBuildFunc(self.buildListboxEntry) + + def applySkin(self, desktop, parent): + attribs = [] + if self.skinAttributes is not None: + for (attrib, value) in self.skinAttributes: + if attrib == "font": + self.l.setFont(0, parseFont(value, ((1, 1), (1, 1)))) + elif attrib == "descriptionFont": + self.descriptionFont = parseFont(value, ((1, 1), (1, 1))) + self.l.setFont(1, self.descriptionFont) + elif attrib == "itemHeight": + self.l.setItemHeight(int(value)) + else: + attribs.append((attrib, value)) + self.skinAttributes = attribs + return MenuList.applySkin(self, desktop, parent) + + def connectSelChanged(self, fnc): + if not fnc in self.onSelectionChanged: + self.onSelectionChanged.append(fnc) + + def disconnectSelChanged(self, fnc): + if fnc in self.onSelectionChanged: + self.onSelectionChanged.remove(fnc) + + def invalidate(self): + self.l.invalidate() + + def moveToEntry(self, feed): + if feed is None: + return + idx = 0 + for x in self.list: + if feed.uri == x[0].uri: + self.instance.moveSelectionTo(idx) + break + idx += 1 + + def buildListboxEntry(self, feed): + size = self.l.getItemSize() + width = size.width() + descriptionHeight = self.descriptionFont.pointSize + 2 + titleHeight = size.height() - descriptionHeight + return [ + None, + (eListboxPythonMultiContent.TYPE_TEXT, 0, 0, width, titleHeight, 0, RT_HALIGN_LEFT | RT_WRAP, feed.title), + (eListboxPythonMultiContent.TYPE_TEXT, 0, int(titleHeight * 0.65), width, int(descriptionHeight * 2.2), 1, RT_HALIGN_LEFT | RT_VALIGN_BOTTOM | RT_WRAP, feed.description) + ] + + def getCurrent(self): + return self.l.getCurrentSelection()[0] # We know that the list will never be empty... + + +class ElementWrapper: # based on http://effbot.org/zone/element-rss-wrapper.htm + def __init__(self, element, ns=""): + self._element = element + self._ns = ns + + def __getattr__(self, tag): + if tag.startswith('__'): + raise AttributeError(tag) + return self._element.findtext(self._ns + tag) + + +class RSSEntryWrapper(ElementWrapper): + def __getattr__(self, tag): + if tag == "enclosures": + myl = [] + for elem in self._element.findall(self._ns + 'enclosure'): + myl.append((elem.get("url"), elem.get("type"), elem.get("length"))) + return myl + elif tag == "id": + return self._element.findtext(self._ns + 'guid', self.title + self.link) + elif tag == "updated": + tag = "lastBuildDate" + elif tag == "summary": + tag = "description" + return ElementWrapper.__getattr__(self, tag) + + +class PEAEntryWrapper(ElementWrapper): + def __getattr__(self, tag): + if tag == "link": + for elem in self._element.findall(self._ns + tag): + if not elem.get("rel") == "enclosure": + return elem.get("href") + return '' + elif tag == "enclosures": + myl = [] + for elem in self._element.findall(self._ns + 'link'): + if elem.get("rel") == "enclosure": + myl.append((elem.get("href"), elem.get("type"), elem.get("length"))) + return myl + elif tag == "summary": + text = self._element.findtext(self._ns + 'summary') + if not text: # if we don't have a summary we use the full content instead + elem = self._element.find(self._ns + 'content') + if elem is not None and elem.get('type') == "html": + text = elem.text + return text + return ElementWrapper.__getattr__(self, tag) + + +class RSSWrapper(ElementWrapper): + def __init__(self, channel, items, ns=""): + self._items = items + ElementWrapper.__init__(self, channel, ns) + + def __iter__(self): + self.idx = 0 + self.len = len(self) - 1 + return self + + def __next__(self): + idx = self.idx + if idx > self.len: + raise StopIteration + self.idx = idx + 1 + return self[idx] + + def __len__(self): + return len(self._items) + + def __getitem__(self, index): + return RSSEntryWrapper(self._items[index], self._ns) + + +class RSS1Wrapper(RSSWrapper): + def __init__(self, feed, ns): + RSSWrapper.__init__(self, feed.find(ns + 'channel'), feed.findall(ns + 'item'), ns) + + def __getattr__(self, tag): + if tag == 'logo': # afaik not officially part of older rss, but can't hurt + tag = 'image' + return ElementWrapper.__getattr__(self, tag) + + +class RSS2Wrapper(RSSWrapper): + def __init__(self, feed, ns): + channel = feed.find("channel") + RSSWrapper.__init__(self, channel, channel.findall("item")) + + def __getattr__(self, tag): + if tag == 'logo': + tag = 'image' + return ElementWrapper.__getattr__(self, tag) + + +class PEAWrapper(RSSWrapper): + def __init__(self, feed, ns): + ns = feed.tag[:feed.tag.index("}") + 1] + RSSWrapper.__init__(self, feed, feed.findall(ns + "entry"), ns) + + def __getitem__(self, index): + return PEAEntryWrapper(self._items[index], self._ns) + + def __getattr__(self, tag): + if tag == "description": + tag = "subtitle" + return ElementWrapper.__getattr__(self, tag) + + +class BaseFeed: # Base-class for all Feeds. Initializes needed Elements. + MAX_HISTORY_ELEMENTS = 100 + + def __init__(self, uri, title="", description=""): + self.uri = uri # Initialize + self.title = title or uri + self.description = description or _("trying to download the feed...") + self.logoUrl = "" + self.history = [] + + def __str__(self): + return "<%s, \"%s\", \"%s\", %d items>" % (self.__class__, self.title, self.description, len(self.history)) + + +class UniversalFeed(BaseFeed): # Feed which can handle rdf, rss and atom feeds utilizing abstraction wrappers. + def __init__(self, uri, autoupdate, sync=False): + BaseFeed.__init__(self, uri) + self.autoupdate = autoupdate # Set Autoupdate + self.sync = sync # Is this a synced feed? + self.last_update = None # Initialize + self.last_ids = set() + self.wrapper = None + self.ns = "" + + def gotWrapper(self, wrapper): + updated = wrapper.updated + if updated and self.last_update == updated: + return [] + idx = 0 + ids = self.last_ids + for item in wrapper: + title = strip(item.title) # Try to read title, continue if none found + if not title: + continue + ident = item.id # Try to read id, continue if none found (invalid feed or internal error) or to be excluded + if not ident or ident in ids: + continue + link = item.link # Link + summary = strip_readable(item.summary or "") # Try to read summary, empty if none + self.history.insert(idx, (title, link, summary, item.enclosures)) # Update Lists + ids.add(ident) + idx += 1 + del self.history[self.MAX_HISTORY_ELEMENTS:] # Eventually cut history + return self.history[:idx] + + def gotFeed(self, feed): + if self.wrapper is not None: + wrapper = self.wrapper(feed, self.ns) + else: + if feed.tag == "rss": + self.wrapper = RSS2Wrapper + elif feed.tag.startswith(NS_RDF): + self.ns = NS_RDF + self.wrapper = RSS1Wrapper + elif feed.tag.startswith(NS_RSS_09): + self.ns = NS_RSS_09 + self.wrapper = RSS1Wrapper + elif feed.tag.startswith(NS_RSS_10): + self.ns = NS_RSS_10 + self.wrapper = RSS1Wrapper + elif feed.tag.endswith("feed"): + self.wrapper = PEAWrapper + else: + raise NotImplementedError('Unsupported Feed: %s' % feed.tag) + wrapper = self.wrapper(feed, self.ns) + self.title = strip(wrapper.title) + self.description = strip_readable(wrapper.description or "") + self.logoUrl = wrapper.logo + return self.gotWrapper(wrapper) def Plugins(**kwargs): - return [ - PluginDescriptor( - name="RSS Reader", - description=_("A simple to use RSS reader"), - icon="plugin.png", - where=PluginDescriptor.WHERE_PLUGINMENU, - fnc=main, - needsRestart=False, - ), - PluginDescriptor( - where=[PluginDescriptor.WHERE_SESSIONSTART, PluginDescriptor.WHERE_AUTOSTART], - fnc=autostart, - needsRestart=False, - ), - PluginDescriptor( - name=_("View RSS..."), - description="Let's you view current RSS entries", - where=PluginDescriptor.WHERE_EXTENSIONSMENU, - fnc=main, - needsRestart=False, - ), - PluginDescriptor( - where=PluginDescriptor.WHERE_FILESCAN, - fnc=filescan, - needsRestart=False, - ) + return [PluginDescriptor(name="RSS Reader", description=_("A simple to use RSS reader"), icon="plugin.png", where=PluginDescriptor.WHERE_PLUGINMENU, fnc=main, needsRestart=False,), + PluginDescriptor(where=[PluginDescriptor.WHERE_SESSIONSTART, PluginDescriptor.WHERE_AUTOSTART], fnc=autostart, needsRestart=False,), + PluginDescriptor(name=_("View RSS..."), description="Let's you view current RSS entries", where=PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=main, needsRestart=False,) ]