diff --git a/Makefile.am b/Makefile.am index d32fd5e9c..a52ad7aea 100644 --- a/Makefile.am +++ b/Makefile.am @@ -10,6 +10,7 @@ SUBDIRS = \ autoresolution \ autotimer \ babelzapper \ + birthdayreminder \ blindscan \ bonjour \ btdevicesmanager \ diff --git a/birthdayreminder/CONTROL/control b/birthdayreminder/CONTROL/control new file mode 100644 index 000000000..2e214798b --- /dev/null +++ b/birthdayreminder/CONTROL/control @@ -0,0 +1,2 @@ +Description: Birthday Reminder: Reminds you of birthdays +Depends: python-textutils diff --git a/birthdayreminder/Makefile.am b/birthdayreminder/Makefile.am new file mode 100644 index 000000000..5afb69089 --- /dev/null +++ b/birthdayreminder/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = src po meta diff --git a/birthdayreminder/meta/Makefile.am b/birthdayreminder/meta/Makefile.am new file mode 100644 index 000000000..efc87b294 --- /dev/null +++ b/birthdayreminder/meta/Makefile.am @@ -0,0 +1,4 @@ +installdir = $(datadir)/meta/ + +dist_install_DATA = plugin_birthdayreminder.xml + diff --git a/birthdayreminder/meta/plugin_birthdayreminder.xml b/birthdayreminder/meta/plugin_birthdayreminder.xml new file mode 100644 index 000000000..17111bd5b --- /dev/null +++ b/birthdayreminder/meta/plugin_birthdayreminder.xml @@ -0,0 +1,16 @@ + + + + + + Shaderman + Birthday Reminder + enigma2-plugin-extensions-birthdayreminder + Reminds you of birthdays + Reminds you of birthdays + + + + + + diff --git a/birthdayreminder/po/BirthdayReminder.pot b/birthdayreminder/po/BirthdayReminder.pot new file mode 100644 index 000000000..357c6b344 --- /dev/null +++ b/birthdayreminder/po/BirthdayReminder.pot @@ -0,0 +1,205 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-01-12 19:10+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#, python-format +msgid "%s will turn %s in %s!" +msgstr "" + +msgid "1 day" +msgstr "" + +msgid "1 week" +msgstr "" + +msgid "3 days" +msgstr "" + +msgid "Add" +msgstr "" + +msgid "Add a birthday" +msgstr "" + +msgid "Add birthday" +msgstr "" + +msgid "Age" +msgstr "" + +msgid "Birthday" +msgstr "" + +msgid "Birthday Reminder" +msgstr "" + +msgid "Birthday Reminder Settings" +msgstr "" + +#, python-format +msgid "Birthday Reminder received %s birthdays from %s." +msgstr "" + +msgid "Birthday filename:" +msgstr "" + +msgid "Birthdays" +msgstr "" + +msgid "CSV import successful!" +msgstr "" + +#, python-format +msgid "Can't find CSV file %s!" +msgstr "" + +#, python-format +msgid "Can't import CSV data from file %s." +msgstr "" + +#, python-format +msgid "Can't write CSV file %s." +msgstr "" + +msgid "Date format:" +msgstr "" + +msgid "Day:" +msgstr "" + +msgid "Disabled" +msgstr "" + +msgid "Distribute birthdays to other Dreamboxes" +msgstr "" + +#, python-format +msgid "Do you really want to delete the entry for %s?" +msgstr "" + +msgid "Edit" +msgstr "" + +msgid "Edit Birthday Settings" +msgstr "" + +msgid "Edit birthday" +msgstr "" + +msgid "Edit birthdays" +msgstr "" + +msgid "Edit the selected entry" +msgstr "" + +#, python-format +msgid "" +"Error reading file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" + +#, python-format +msgid "" +"Error writing file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" + +msgid "Exit the plugin" +msgstr "" + +msgid "Export CSV file" +msgstr "" + +msgid "Extras" +msgstr "" + +msgid "Helps to remind of birthdays" +msgstr "" + +msgid "Import CSV file" +msgstr "" + +msgid "Invalid date!" +msgstr "" + +msgid "Month:" +msgstr "" + +msgid "Name" +msgstr "" + +msgid "Name:" +msgstr "" + +msgid "Networking port (default: 7374):" +msgstr "" + +msgid "Next birthday" +msgstr "" + +msgid "Notification time:" +msgstr "" + +msgid "Open the extras menu" +msgstr "" + +msgid "Path to birthday file:" +msgstr "" + +msgid "Remind before birthday:" +msgstr "" + +msgid "Remove" +msgstr "" + +msgid "Remove the selected entry" +msgstr "" + +msgid "Select a path for the birthday file" +msgstr "" + +msgid "Show plugin in extensions menu:" +msgstr "" + +msgid "Sort birthdays by:" +msgstr "" + +msgid "Sorting next" +msgstr "" + +msgid "Sorting previous" +msgstr "" + +#, python-format +msgid "" +"Today is %s's birthday!\n" +"\n" +"She/he was born on %s and is now %s year(s) old." +msgstr "" + +msgid "What do you want to do?" +msgstr "" + +#, python-format +msgid "Wrote CSV file %s." +msgstr "" + +msgid "Year:" +msgstr "" diff --git a/birthdayreminder/po/Makefile.am b/birthdayreminder/po/Makefile.am new file mode 100644 index 000000000..7f5cf7048 --- /dev/null +++ b/birthdayreminder/po/Makefile.am @@ -0,0 +1,2 @@ +PLUGIN = BirthdayReminder +include $(top_srcdir)/Rules-po.mak diff --git a/birthdayreminder/po/de.po b/birthdayreminder/po/de.po new file mode 100644 index 000000000..9a71dad7f --- /dev/null +++ b/birthdayreminder/po/de.po @@ -0,0 +1,231 @@ +msgid "" +msgstr "" +"Project-Id-Version: BirthdayReminder 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-04-16 19:06+0430\n" +"PO-Revision-Date: \n" +"Last-Translator: Mr.Servo \n" +"Language-Team: \n" +"Language: de_DE\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: Poedit 3.2.2\n" + +#, python-format +msgid "%s will turn %s in %s!" +msgstr "%s wird %s in %s!" + +msgid "1 day" +msgstr "1 Tag" + +msgid "1 week" +msgstr "1 Woche" + +msgid "3 days" +msgstr "3 Tage" + +msgid "Accept changes" +msgstr "Änderungen übernehmen" + +msgid "Add" +msgstr "Hinzufügen" + +msgid "Add a birthday" +msgstr "Geburtstag hinzufügen" + +msgid "Add birthday" +msgstr "Geburtstag hinzufügen" + +msgid "Age" +msgstr "Alter" + +msgid "Birthday" +msgstr "Geburtstag" + +msgid "Birthday Reminder" +msgstr "Birthday Reminder" + +msgid "Birthday Reminder Settings" +msgstr "Birthday Reminder Einstellungen" + +#, python-format +msgid "Birthday Reminder received %s birthdays from %s." +msgstr "Birthday Reminder hat %s Geburtstage von %s empfangen." + +msgid "Birthday filename:" +msgstr "Dateiname:" + +msgid "Birthdays" +msgstr "Geburtstage" + +msgid "CSV import successful!" +msgstr "Die Daten der CSV- Datei wurden erfolgreich importiert!" + +#, python-format +msgid "Can't find CSV file %s!" +msgstr "Die CSV- Datei %s konnte nicht gefunden werden!" + +#, python-format +msgid "Can't import CSV data from file %s." +msgstr "Die Daten der CSV- Datei %s konnten nicht importiert werden." + +#, python-format +msgid "Can't write CSV file %s." +msgstr "Die CSV- Datei %s konnte nicht gespeichert werden." + +msgid "Cancel" +msgstr "Abbrechen" + +msgid "Change path" +msgstr "Pfad ändern" + +msgid "Choose the filename:" +msgstr "Wähle den Dateinamen:" + +msgid "Date format:" +msgstr "Datumsformat:" + +msgid "Day:" +msgstr "Tag:" + +msgid "Disabled" +msgstr "Deaktiviert" + +msgid "Distribute birthdays to other Dreamboxes" +msgstr "Geburtstagsliste an andere Boxen verteilen" + +#, python-format +msgid "Do you really want to delete the entry for %s?" +msgstr "Wollen Sie den Eintrag für %s wirklich löschen?" + +msgid "Edit" +msgstr "Bearbeiten" + +msgid "Edit birthday" +msgstr "Geburtstag bearbeiten" + +msgid "Edit birthdays" +msgstr "Geburtstage bearbeiten" + +msgid "Edit the selected entry" +msgstr "Gewählten Eintrag bearbeiten" + +msgid "Enter the name of the person:" +msgstr "Geben den Namen der Person ein:" + +#, python-format +msgid "" +"Error reading file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" +"Fehler beim Lesen der Datei %s.\n" +"\n" +"Fehler: %s, %s" + +#, python-format +msgid "" +"Error writing file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" +"Fehler beim Schreiben der Datei %s.\n" +"\n" +"Fehler: %s, %s" + +msgid "Exit the plugin" +msgstr "Plugin beenden" + +msgid "Export CSV file" +msgstr "CSV- Datei exportieren" + +msgid "Extras" +msgstr "Extras" + +msgid "Helps to remind of birthdays" +msgstr "Erinnert an Geburtstage" + +msgid "Import CSV file" +msgstr "CSV- Datei importieren" + +msgid "Invalid Location" +msgstr "Fehlerhafter Ort" + +msgid "Invalid date!" +msgstr "Ungültiges Datum!" + +msgid "Month:" +msgstr "Monat:" + +msgid "Name" +msgstr "Name" + +msgid "Name:" +msgstr "Name:" + +msgid "Networking port (default: 7374):" +msgstr "Netzwerk Port (Standard: 7374):" + +msgid "Next birthday" +msgstr "Nächstem Geburtstag" + +msgid "Notification time:" +msgstr "Zeit für Benachrichtigungen:" + +msgid "OK" +msgstr "OK" + +msgid "Open the extras menu" +msgstr "Extras menu öffnen" + +msgid "Path to birthday file:" +msgstr "Pfad zur Geburtstagsdatei:" + +msgid "Remind before birthday:" +msgstr "Vor Geburtstag erinnern:" + +msgid "Remove" +msgstr "Entfernen" + +msgid "Remove the selected entry" +msgstr "Gewählten Eintrag löschen" + +msgid "Save" +msgstr "Speichern" + +msgid "Show plugin in extensions menu:" +msgstr "Zeige Plugin im Erweiterungsmenu:" + +msgid "Sort birthdays by:" +msgstr "Sortiere Geburtstage nach:" + +msgid "Sorting next" +msgstr "Sortierung vor" + +msgid "Sorting previous" +msgstr "Sortierung zurück" + +#, python-format +msgid "" +"Today is %s's birthday!\n" +"\n" +"She/he was born on %s and is now %s year(s) old." +msgstr "" +"Heute ist %s's Geburtstag!\n" +"\n" +"Sie/er wurde am %s geboren und ist jetzt %s Jahr(e) alt." + +msgid "VirtualKeyBoard" +msgstr "VirtualKeyBoard" + +msgid "What do you want to do?" +msgstr "Was wollen Sie tun?" + +#, python-format +msgid "Wrote CSV file %s." +msgstr "Die CSV- Datei %s wurde gespeichert." + +msgid "Year:" +msgstr "Jahr:" diff --git a/birthdayreminder/po/en.po b/birthdayreminder/po/en.po new file mode 100644 index 000000000..5f738af1a --- /dev/null +++ b/birthdayreminder/po/en.po @@ -0,0 +1,236 @@ +# English translations for enigma2-plugins package. +# Copyright (C) 2012 THE enigma2-plugins'S COPYRIGHT HOLDER +# This file is distributed under the same license as the enigma2-plugins package. +# Automatically generated, 2012. +# +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: 2023-03-30 11:44+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.2.2\n" + +#, python-format +msgid "%s will turn %s in %s!" +msgstr "%s will turn %s in %s!" + +msgid "1 day" +msgstr "1 day" + +msgid "1 week" +msgstr "1 week" + +msgid "3 days" +msgstr "3 days" + +msgid "Accept changes" +msgstr "Accept changes" + +msgid "Add" +msgstr "Add" + +msgid "Add a birthday" +msgstr "Add a birthday" + +msgid "Add birthday" +msgstr "Add birthday" + +msgid "Age" +msgstr "Age" + +msgid "Birthday" +msgstr "Birthday" + +msgid "Birthday Reminder" +msgstr "Birthday Reminder" + +msgid "Birthday Reminder Settings" +msgstr "Birthday Reminder Settings" + +#, python-format +msgid "Birthday Reminder received %s birthdays from %s." +msgstr "Birthday Reminder received %s birthdays from %s." + +msgid "Birthday filename:" +msgstr "Birthday filename:" + +msgid "Birthdays" +msgstr "Birthdays" + +msgid "CSV import successful!" +msgstr "CSV import successful!" + +#, python-format +msgid "Can't find CSV file %s!" +msgstr "Can't find CSV file %s!" + +#, python-format +msgid "Can't import CSV data from file %s." +msgstr "Can't import CSV data from file %s." + +#, python-format +msgid "Can't write CSV file %s." +msgstr "Can't write CSV file %s." + +msgid "Cancel" +msgstr "Cancel" + +msgid "Change path" +msgstr "Change path" + +msgid "Choose the filename:" +msgstr "Choose the filename:" + +msgid "Date format:" +msgstr "Date format:" + +msgid "Day:" +msgstr "Day:" + +msgid "Disabled" +msgstr "Disabled" + +msgid "Distribute birthdays to other Dreamboxes" +msgstr "Distribute birthdays to other boxes" + +#, python-format +msgid "Do you really want to delete the entry for %s?" +msgstr "Do you really want to delete the entry for %s?" + +msgid "Edit" +msgstr "Edit" + +msgid "Edit birthday" +msgstr "Edit birthday" + +msgid "Edit birthdays" +msgstr "Edit birthdays" + +msgid "Edit the selected entry" +msgstr "Edit the selected entry" + +msgid "Enter the name of the person:" +msgstr "Enter the name of the person:" + +#, python-format +msgid "" +"Error reading file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" +"Error reading file %s.\n" +"\n" +"Error: %s, %s" + +#, python-format +msgid "" +"Error writing file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" +"Error writing file %s.\n" +"\n" +"Error: %s, %s" + +msgid "Exit the plugin" +msgstr "Exit the plugin" + +msgid "Export CSV file" +msgstr "Export CSV file" + +msgid "Extras" +msgstr "Extras" + +msgid "Helps to remind of birthdays" +msgstr "Helps to remind of birthdays" + +msgid "Import CSV file" +msgstr "Import CSV file" + +msgid "Invalid Location" +msgstr "Invalid Location" + +msgid "Invalid date!" +msgstr "Invalid date!" + +msgid "Month:" +msgstr "Month:" + +msgid "Name" +msgstr "Name" + +msgid "Name:" +msgstr "Name:" + +msgid "Networking port (default: 7374):" +msgstr "Networking port (default: 7374):" + +msgid "Next birthday" +msgstr "Next birthday" + +msgid "Notification time:" +msgstr "Notification time:" + +msgid "OK" +msgstr "OK" + +msgid "Open the extras menu" +msgstr "Open the extras menu" + +msgid "Path to birthday file:" +msgstr "Path to birthday file:" + +msgid "Remind before birthday:" +msgstr "Remind before birthday:" + +msgid "Remove" +msgstr "Remove" + +msgid "Remove the selected entry" +msgstr "Remove the selected entry" + +msgid "Save" +msgstr "Save" + +msgid "Show plugin in extensions menu:" +msgstr "Show plugin in extensions menu:" + +msgid "Sort birthdays by:" +msgstr "Sort birthdays by:" + +msgid "Sorting next" +msgstr "Sorting next" + +msgid "Sorting previous" +msgstr "Sorting previous" + +#, python-format +msgid "" +"Today is %s's birthday!\n" +"\n" +"She/he was born on %s and is now %s year(s) old." +msgstr "" +"Today is %s's birthday!\n" +"\n" +"She/he was born on %s and is now %s year(s) old." + +msgid "VirtualKeyBoard" +msgstr "VirtualKeyBoard" + +msgid "What do you want to do?" +msgstr "What do you want to do?" + +#, python-format +msgid "Wrote CSV file %s." +msgstr "Wrote CSV file %s." + +msgid "Year:" +msgstr "Year:" diff --git a/birthdayreminder/po/en_GB.po b/birthdayreminder/po/en_GB.po new file mode 100644 index 000000000..4df837383 --- /dev/null +++ b/birthdayreminder/po/en_GB.po @@ -0,0 +1,236 @@ +# English translations for enigma2-plugins package. +# Copyright (C) 2012 THE enigma2-plugins'S COPYRIGHT HOLDER +# This file is distributed under the same license as the enigma2-plugins package. +# Automatically generated, 2012. +# +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: 2023-03-30 11:45+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.2.2\n" + +#, python-format +msgid "%s will turn %s in %s!" +msgstr "%s will turn %s in %s!" + +msgid "1 day" +msgstr "1 day" + +msgid "1 week" +msgstr "1 week" + +msgid "3 days" +msgstr "3 days" + +msgid "Accept changes" +msgstr "Accept changes" + +msgid "Add" +msgstr "Add" + +msgid "Add a birthday" +msgstr "Add a birthday" + +msgid "Add birthday" +msgstr "Add birthday" + +msgid "Age" +msgstr "Age" + +msgid "Birthday" +msgstr "Birthday" + +msgid "Birthday Reminder" +msgstr "Birthday Reminder" + +msgid "Birthday Reminder Settings" +msgstr "Birthday Reminder Settings" + +#, python-format +msgid "Birthday Reminder received %s birthdays from %s." +msgstr "Birthday Reminder received %s birthdays from %s." + +msgid "Birthday filename:" +msgstr "Birthday filename:" + +msgid "Birthdays" +msgstr "Birthdays" + +msgid "CSV import successful!" +msgstr "CSV import successful!" + +#, python-format +msgid "Can't find CSV file %s!" +msgstr "Can't find CSV file %s!" + +#, python-format +msgid "Can't import CSV data from file %s." +msgstr "Can't import CSV data from file %s." + +#, python-format +msgid "Can't write CSV file %s." +msgstr "Can't write CSV file %s." + +msgid "Cancel" +msgstr "Cancel" + +msgid "Change path" +msgstr "Change path" + +msgid "Choose the filename:" +msgstr "Choose the filename:" + +msgid "Date format:" +msgstr "Date format:" + +msgid "Day:" +msgstr "Day:" + +msgid "Disabled" +msgstr "Disabled" + +msgid "Distribute birthdays to other Dreamboxes" +msgstr "Distribute birthdays to other boxes" + +#, python-format +msgid "Do you really want to delete the entry for %s?" +msgstr "Do you really want to delete the entry for %s?" + +msgid "Edit" +msgstr "Edit" + +msgid "Edit birthday" +msgstr "Edit birthday" + +msgid "Edit birthdays" +msgstr "Edit birthdays" + +msgid "Edit the selected entry" +msgstr "Edit the selected entry" + +msgid "Enter the name of the person:" +msgstr "Enter the name of the person:" + +#, python-format +msgid "" +"Error reading file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" +"Error reading file %s.\n" +"\n" +"Error: %s, %s" + +#, python-format +msgid "" +"Error writing file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" +"Error writing file %s.\n" +"\n" +"Error: %s, %s" + +msgid "Exit the plugin" +msgstr "Exit the plugin" + +msgid "Export CSV file" +msgstr "Export CSV file" + +msgid "Extras" +msgstr "Extras" + +msgid "Helps to remind of birthdays" +msgstr "Helps to remind of birthdays" + +msgid "Import CSV file" +msgstr "Import CSV file" + +msgid "Invalid Location" +msgstr "Invalid Location" + +msgid "Invalid date!" +msgstr "Invalid date!" + +msgid "Month:" +msgstr "Month:" + +msgid "Name" +msgstr "Name" + +msgid "Name:" +msgstr "Name:" + +msgid "Networking port (default: 7374):" +msgstr "Networking port (default: 7374):" + +msgid "Next birthday" +msgstr "Next birthday" + +msgid "Notification time:" +msgstr "Notification time:" + +msgid "OK" +msgstr "OK" + +msgid "Open the extras menu" +msgstr "Open the extras menu" + +msgid "Path to birthday file:" +msgstr "Path to birthday file:" + +msgid "Remind before birthday:" +msgstr "Remind before birthday:" + +msgid "Remove" +msgstr "Remove" + +msgid "Remove the selected entry" +msgstr "Remove the selected entry" + +msgid "Save" +msgstr "Save" + +msgid "Show plugin in extensions menu:" +msgstr "Show plugin in extensions menu:" + +msgid "Sort birthdays by:" +msgstr "Sort birthdays by:" + +msgid "Sorting next" +msgstr "Sorting next" + +msgid "Sorting previous" +msgstr "Sorting previous" + +#, python-format +msgid "" +"Today is %s's birthday!\n" +"\n" +"She/he was born on %s and is now %s year(s) old." +msgstr "" +"Today is %s's birthday!\n" +"\n" +"She/he was born on %s and is now %s year(s) old." + +msgid "VirtualKeyBoard" +msgstr "VirtualKeyBoard" + +msgid "What do you want to do?" +msgstr "What do you want to do?" + +#, python-format +msgid "Wrote CSV file %s." +msgstr "Wrote CSV file %s." + +msgid "Year:" +msgstr "Year:" diff --git a/birthdayreminder/po/fr.po b/birthdayreminder/po/fr.po new file mode 100644 index 000000000..f9c215ac2 --- /dev/null +++ b/birthdayreminder/po/fr.po @@ -0,0 +1,236 @@ +# English translations for enigma2-plugins package. +# Copyright (C) 2012 THE enigma2-plugins'S COPYRIGHT HOLDER +# This file is distributed under the same license as the enigma2-plugins package. +# Automatically generated, 2012. +# +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: 2023-03-30 11:46+0200\n" +"Last-Translator: Mr.Servo \n" +"Language-Team: french\n" +"Language: fr\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.2.2\n" + +#, python-format +msgid "%s will turn %s in %s!" +msgstr "%s tournera %s dans %s!" + +msgid "1 day" +msgstr "1 jour" + +msgid "1 week" +msgstr "1 semaine" + +msgid "3 days" +msgstr "3 jours" + +msgid "Accept changes" +msgstr "Accepter les changements" + +msgid "Add" +msgstr "Ajouter" + +msgid "Add a birthday" +msgstr "Ajouter un anniversaire" + +msgid "Add birthday" +msgstr "Ajouter anniversaire" + +msgid "Age" +msgstr "Âge" + +msgid "Birthday" +msgstr "Anniversaire" + +msgid "Birthday Reminder" +msgstr "Birthday Reminder" + +msgid "Birthday Reminder Settings" +msgstr "Birthday Reminder Configuration" + +#, python-format +msgid "Birthday Reminder received %s birthdays from %s." +msgstr "Birthday Reminder a reçu %s anniversaire de %s." + +msgid "Birthday filename:" +msgstr "Nom du fichier Anniversaire:" + +msgid "Birthdays" +msgstr "Anniversaires" + +msgid "CSV import successful!" +msgstr "CSV importé avec succès!" + +#, python-format +msgid "Can't find CSV file %s!" +msgstr "Impossible de trouver un fichier CSV %s!" + +#, python-format +msgid "Can't import CSV data from file %s." +msgstr "Impossible d'importer des données du fichier CSV %s." + +#, python-format +msgid "Can't write CSV file %s." +msgstr "Impossible d'écrire un fichier CSV %s." + +msgid "Cancel" +msgstr "Annuler" + +msgid "Change path" +msgstr "Changer le chemin" + +msgid "Choose the filename:" +msgstr "Choisissez le nom du fichier:" + +msgid "Date format:" +msgstr "Format date:" + +msgid "Day:" +msgstr "Jour:" + +msgid "Disabled" +msgstr "Désactivé" + +msgid "Distribute birthdays to other Dreamboxes" +msgstr "Distribuer les anniversaires aux autres récepteurs" + +#, python-format +msgid "Do you really want to delete the entry for %s?" +msgstr "Voulez-vous vraiment effacer l'entrée pour %s?" + +msgid "Edit" +msgstr "Éditer" + +msgid "Edit birthday" +msgstr "Éditer anniversaire" + +msgid "Edit birthdays" +msgstr "Éditer anniversaires" + +msgid "Edit the selected entry" +msgstr "Éditer l'entrée sélectionnée" + +msgid "Enter the name of the person:" +msgstr "Saisissez le nom de la personne:" + +#, python-format +msgid "" +"Error reading file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" +"Erreur en lisant le fichier %s.\n" +"\n" +"Erreur: %s, %s" + +#, python-format +msgid "" +"Error writing file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" +"Erreur en écrivant le fichier %s.\n" +"\n" +"Erreur: %s, %s" + +msgid "Exit the plugin" +msgstr "Quitter le plugin" + +msgid "Export CSV file" +msgstr "Exporter un fichier CSV" + +msgid "Extras" +msgstr "Extras" + +msgid "Helps to remind of birthdays" +msgstr "Aide pour se rappeler les anniversaires" + +msgid "Import CSV file" +msgstr "Importer un fichier CSV" + +msgid "Invalid Location" +msgstr "Localisation non valide" + +msgid "Invalid date!" +msgstr "Date non valide!" + +msgid "Month:" +msgstr "Mois:" + +msgid "Name" +msgstr "Nom" + +msgid "Name:" +msgstr "Nom:" + +msgid "Networking port (default: 7374):" +msgstr "Port réseau (défaut: 7374):" + +msgid "Next birthday" +msgstr "Anniversaire suivant" + +msgid "Notification time:" +msgstr "Heure de notification:" + +msgid "OK" +msgstr "OK" + +msgid "Open the extras menu" +msgstr "Ouvrir le menu extras" + +msgid "Path to birthday file:" +msgstr "Chemin vers le fichier des anniversaires:" + +msgid "Remind before birthday:" +msgstr "Rappeler avant l'anniversaire:" + +msgid "Remove" +msgstr "Enlever" + +msgid "Remove the selected entry" +msgstr "Enlever l'entrée sélectionnée" + +msgid "Save" +msgstr "Sauvegarder" + +msgid "Show plugin in extensions menu:" +msgstr "Afficher plugin dans le menu extensions:" + +msgid "Sort birthdays by:" +msgstr "Afficher les anniversaires par:" + +msgid "Sorting next" +msgstr "Tri suivant" + +msgid "Sorting previous" +msgstr "Tri précédent" + +#, python-format +msgid "" +"Today is %s's birthday!\n" +"\n" +"She/he was born on %s and is now %s year(s) old." +msgstr "" +"Aujourd'hui c'est l'anniversaire de %s!\n" +"\n" +"Il/Elle est né(e) en %s et a donc %s an(s)." + +msgid "VirtualKeyBoard" +msgstr "VirtualKeyBoard" + +msgid "What do you want to do?" +msgstr "Que voulez-vous faire?" + +#, python-format +msgid "Wrote CSV file %s." +msgstr "Écrire un fichier CSV %s." + +msgid "Year:" +msgstr "Année:" diff --git a/birthdayreminder/po/it.po b/birthdayreminder/po/it.po new file mode 100644 index 000000000..44dc1554a --- /dev/null +++ b/birthdayreminder/po/it.po @@ -0,0 +1,235 @@ +msgid "" +msgstr "" +"Project-Id-Version: enigma2 plugin - birthday reminder\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-04-16 19:06+0430\n" +"PO-Revision-Date: 2023-03-30 11:49+0200\n" +"Last-Translator: Mr.Servo \n" +"Language-Team: www.linsat.net \n" +"Language: 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-KeywordsList: _;gettext;gettext_noop\n" +"X-Poedit-Basepath: /media/TREKSTOR/enigma2/BirthdayReminder/BirthdayReminder\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: Poedit 3.2.2\n" +"X-Poedit-SearchPath-0: /media/TREKSTOR/enigma2/BirthdayReminder/BirthdayReminder\n" + +#, python-format +msgid "%s will turn %s in %s!" +msgstr "%s compirà %s anni fra %s!" + +msgid "1 day" +msgstr "1 giorno" + +msgid "1 week" +msgstr "1 settimana" + +msgid "3 days" +msgstr "3 giorni" + +msgid "Accept changes" +msgstr "Conf. modifiche" + +msgid "Add" +msgstr "Agg" + +msgid "Add a birthday" +msgstr "Agg. compleanno" + +msgid "Add birthday" +msgstr "Aggiungere compleanno" + +msgid "Age" +msgstr "Età" + +msgid "Birthday" +msgstr "Compleanno" + +msgid "Birthday Reminder" +msgstr "Birthday Reminder" + +msgid "Birthday Reminder Settings" +msgstr "Configurazione Birthday Reminder" + +#, python-format +msgid "Birthday Reminder received %s birthdays from %s." +msgstr "Birthday Reminder: ricevuti %s compleanni da %s." + +msgid "Birthday filename:" +msgstr "Nome file compleanni:" + +msgid "Birthdays" +msgstr "Compleanni" + +msgid "CSV import successful!" +msgstr "Importazione CVS corretta!" + +#, python-format +msgid "Can't find CSV file %s!" +msgstr "Impossibile trovare file CVS %s!" + +#, python-format +msgid "Can't import CSV data from file %s." +msgstr "Impossible importare dati dal file %s." + +#, python-format +msgid "Can't write CSV file %s." +msgstr "Impossibile scrivere file CVS %s." + +msgid "Cancel" +msgstr "Annullare" + +msgid "Change path" +msgstr "Mod. percorso" + +msgid "Choose the filename:" +msgstr "Scegliere il nome del file:" + +msgid "Date format:" +msgstr "Formato data:" + +msgid "Day:" +msgstr "Giorno:" + +msgid "Disabled" +msgstr "Disabilitato" + +msgid "Distribute birthdays to other Dreamboxes" +msgstr "Distribuire compleanni ad altri box" + +#, python-format +msgid "Do you really want to delete the entry for %s?" +msgstr "%s: RIMUOVERE la voce?" + +msgid "Edit" +msgstr "Mod" + +msgid "Edit birthday" +msgstr "Modificare compleanno" + +msgid "Edit birthdays" +msgstr "Mod. compleanni" + +msgid "Edit the selected entry" +msgstr "Mod. voce selezionata" + +msgid "Enter the name of the person:" +msgstr "Inserire il nome della persona:" + +#, python-format +msgid "" +"Error reading file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" +"%s: errore in lettura file.\n" +"\n" +"Errore: %s, %s" + +#, python-format +msgid "" +"Error writing file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" +"%s: errore in scrittura file.\n" +"\n" +"Errore: %s, %s" + +msgid "Exit the plugin" +msgstr "Uscire" + +msgid "Export CSV file" +msgstr "Esportare come CVS" + +msgid "Extras" +msgstr "Extra" + +msgid "Helps to remind of birthdays" +msgstr "Un aiuto per ricordare i compleanni" + +msgid "Import CSV file" +msgstr "Importare CVS" + +msgid "Invalid Location" +msgstr "Estinazione non valida" + +msgid "Invalid date!" +msgstr "Data non valida!" + +msgid "Month:" +msgstr "Mese:" + +msgid "Name" +msgstr "Nome" + +msgid "Name:" +msgstr "Nome:" + +msgid "Networking port (default: 7374):" +msgstr "Porta (predefinita: 7374):" + +msgid "Next birthday" +msgstr "Prossimo compleanno" + +msgid "Notification time:" +msgstr "Ora notifica:" + +msgid "OK" +msgstr "Ok" + +msgid "Open the extras menu" +msgstr "Aprire menu extra" + +msgid "Path to birthday file:" +msgstr "Percorso file compleanni:" + +msgid "Remind before birthday:" +msgstr "Avvisare con un anticipo di:" + +msgid "Remove" +msgstr "Rimuov" + +msgid "Remove the selected entry" +msgstr "Rimuov. voce selezionata" + +msgid "Save" +msgstr "Salvare" + +msgid "Show plugin in extensions menu:" +msgstr "Mostrare nel menu estensioni:" + +msgid "Sort birthdays by:" +msgstr "Ordinare per:" + +msgid "Sorting next" +msgstr "Crescente" + +msgid "Sorting previous" +msgstr "Decrescente" + +#, python-format +msgid "" +"Today is %s's birthday!\n" +"\n" +"She/he was born on %s and is now %s year(s) old." +msgstr "" +"Oggi è il compleanno di %s!\n" +"\n" +"Data di nascita: %s - Età: %s." + +msgid "VirtualKeyBoard" +msgstr "Tastiera virtuale" + +msgid "What do you want to do?" +msgstr "Cosa si desidera fare?" + +#, python-format +msgid "Wrote CSV file %s." +msgstr "Scritto file CVS %s." + +msgid "Year:" +msgstr "Anno:" diff --git a/birthdayreminder/po/lt.po b/birthdayreminder/po/lt.po new file mode 100644 index 000000000..7590ce1e0 --- /dev/null +++ b/birthdayreminder/po/lt.po @@ -0,0 +1,236 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR ORGANIZATION +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-04-16 19:06+0430\n" +"PO-Revision-Date: 2023-03-30 11:49+0200\n" +"Last-Translator: Mr.Servo \n" +"Language-Team: \n" +"Language: lt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\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" +"Generated-By: pygettext.py 1.5\n" +"X-Generator: Poedit 3.2.2\n" + +#, python-format +msgid "%s will turn %s in %s!" +msgstr "%s įjungs %s po %s!" + +msgid "1 day" +msgstr "1 dieną" + +msgid "1 week" +msgstr "1 savaitę" + +msgid "3 days" +msgstr "3 dienas" + +msgid "Accept changes" +msgstr "Priimti pakeitimus" + +msgid "Add" +msgstr "Pridėti" + +msgid "Add a birthday" +msgstr "Pridėti gimtadienį" + +msgid "Add birthday" +msgstr "Pridėti gimtadienį" + +msgid "Age" +msgstr "Amžius" + +msgid "Birthday" +msgstr "Gimtadienis" + +msgid "Birthday Reminder" +msgstr "Gimtadienių priminimas" + +msgid "Birthday Reminder Settings" +msgstr "Gimtadienių priminimo nustatymai" + +#, python-format +msgid "Birthday Reminder received %s birthdays from %s." +msgstr "Gimtadienių priminimo parsiųsti %s gimtadieniai iš %s." + +msgid "Birthday filename:" +msgstr "Gimtadienių failo pavadinimas:" + +msgid "Birthdays" +msgstr "Gimtadieniai" + +msgid "CSV import successful!" +msgstr "CSV importas pavyko!" + +#, python-format +msgid "Can't find CSV file %s!" +msgstr "Surasti CSV failo %s nepavyko!" + +#, python-format +msgid "Can't import CSV data from file %s." +msgstr "Importuoti CSV duomenų iš failo %s negalima." + +#, python-format +msgid "Can't write CSV file %s." +msgstr "Įrašyti CSV failo %s nepavyko." + +msgid "Cancel" +msgstr "Atšaukti" + +msgid "Change path" +msgstr "Keisti kelią" + +msgid "Choose the filename:" +msgstr "Pasirinkite failo pavadinimą:" + +msgid "Date format:" +msgstr "Datos formatas:" + +msgid "Day:" +msgstr "Diena:" + +msgid "Disabled" +msgstr "Išjungta" + +msgid "Distribute birthdays to other Dreamboxes" +msgstr "Platinti gimtadienius į kitus aparatus" + +#, python-format +msgid "Do you really want to delete the entry for %s?" +msgstr "Ar tikrai norite trinti įrašą %s?" + +msgid "Edit" +msgstr "Redaguoti" + +msgid "Edit birthday" +msgstr "Redaguoti gimtadienį" + +msgid "Edit birthdays" +msgstr "Redaguoti gimtadienius" + +msgid "Edit the selected entry" +msgstr "Redaguoti pasirinktą įrašą" + +msgid "Enter the name of the person:" +msgstr "Įveskite asmens vardą ir pavardę:" + +#, python-format +msgid "" +"Error reading file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" +"Klaida skaitant failą %s.\n" +"\n" +"Klaida: %s, %s" + +#, python-format +msgid "" +"Error writing file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" +"Klaida rašant failą %s.\n" +"\n" +"Klaida: %s, %s" + +msgid "Exit the plugin" +msgstr "Užverti įskiepį" + +msgid "Export CSV file" +msgstr "Eksportuoti CSV failą" + +msgid "Extras" +msgstr "Priedai" + +msgid "Helps to remind of birthdays" +msgstr "Padeda prisiminti apie gimtadienius" + +msgid "Import CSV file" +msgstr "Importuoti CSV failą" + +msgid "Invalid Location" +msgstr "Neteisinga vieta" + +msgid "Invalid date!" +msgstr "Neleistina data!" + +msgid "Month:" +msgstr "Mėnuo:" + +msgid "Name" +msgstr "Vardas" + +msgid "Name:" +msgstr "Vardas:" + +msgid "Networking port (default: 7374):" +msgstr "Tinklo prievadas (numatytasis: 7374):" + +msgid "Next birthday" +msgstr "Kitas gimtadienis" + +msgid "Notification time:" +msgstr "Pranešimo laikas:" + +msgid "OK" +msgstr "Gerai" + +msgid "Open the extras menu" +msgstr "Atidaryti priedų meniu" + +msgid "Path to birthday file:" +msgstr "Kelias į gimtadienių failą:" + +msgid "Remind before birthday:" +msgstr "Priminti prieš gimtadienį:" + +msgid "Remove" +msgstr "Pašalinti" + +msgid "Remove the selected entry" +msgstr "Pašalinti pasirinktą įrašą" + +msgid "Save" +msgstr "Išsaugoti" + +msgid "Show plugin in extensions menu:" +msgstr "Rodyti tarp plėtinių meniu:" + +msgid "Sort birthdays by:" +msgstr "Rūšiuoti gimtadienius pagal:" + +msgid "Sorting next" +msgstr "Kitas rūšiavimas" + +msgid "Sorting previous" +msgstr "Ankstesnis rūšiavimas" + +#, python-format +msgid "" +"Today is %s's birthday!\n" +"\n" +"She/he was born on %s and is now %s year(s) old." +msgstr "" +"Šiandien %s gimtadienis!\n" +"\n" +"Gimė %s ir dabar yra %s metų amžiaus." + +msgid "VirtualKeyBoard" +msgstr "VirtualKeyBoard" + +msgid "What do you want to do?" +msgstr "Ką norite daryti?" + +#, python-format +msgid "Wrote CSV file %s." +msgstr "Įrašytas CSV failas %s." + +msgid "Year:" +msgstr "Metai:" diff --git a/birthdayreminder/po/nl.po b/birthdayreminder/po/nl.po new file mode 100644 index 000000000..adb553a58 --- /dev/null +++ b/birthdayreminder/po/nl.po @@ -0,0 +1,236 @@ +# Dutch translations for enigma2-plugins package. +# Copyright (C) 2012 THE enigma2-plugins'S COPYRIGHT HOLDER +# This file is distributed under the same license as the enigma2-plugins package. +# Automatically generated, 2012. +# +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: 2023-03-30 11:41+0200\n" +"Last-Translator: Mr.Servo \n" +"Language-Team: Andy Blackburn/Rob van der Does\n" +"Language: nl\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.2.2\n" + +#, python-format +msgid "%s will turn %s in %s!" +msgstr "%s zal worden gewijzigd %s in %s!" + +msgid "1 day" +msgstr "1 dag" + +msgid "1 week" +msgstr "1 week" + +msgid "3 days" +msgstr "3 dagen" + +msgid "Accept changes" +msgstr "Accepteer veranderingen" + +msgid "Add" +msgstr "Voeg toe" + +msgid "Add a birthday" +msgstr "Voeg een verjaardag toe" + +msgid "Add birthday" +msgstr "Voeg verjaardag toe" + +msgid "Age" +msgstr "Leeftijd" + +msgid "Birthday" +msgstr "Verjaardag" + +msgid "Birthday Reminder" +msgstr "Verjaardagsherinnering" + +msgid "Birthday Reminder Settings" +msgstr "Verjaardagsherinnering instellingen" + +#, python-format +msgid "Birthday Reminder received %s birthdays from %s." +msgstr "Verjaardagsherinnering ontvangen %s verjaardagen van %s." + +msgid "Birthday filename:" +msgstr "Verjaardagen bestandsnaam:" + +msgid "Birthdays" +msgstr "Verjaardagen" + +msgid "CSV import successful!" +msgstr "CSV import geslaagd!" + +#, python-format +msgid "Can't find CSV file %s!" +msgstr "Kan CSV bestand %s niet vinden!" + +#, python-format +msgid "Can't import CSV data from file %s." +msgstr "Kan CSV data van bestand %s niet importeren." + +#, python-format +msgid "Can't write CSV file %s." +msgstr "Kan CSV bestand %s niet schrijven." + +msgid "Cancel" +msgstr "Annuleer" + +msgid "Change path" +msgstr "Verander pad" + +msgid "Choose the filename:" +msgstr "Kies de bestandsnaam:" + +msgid "Date format:" +msgstr "Datum formaat:" + +msgid "Day:" +msgstr "Dag:" + +msgid "Disabled" +msgstr "Uitgeschakeld" + +msgid "Distribute birthdays to other Dreamboxes" +msgstr "Geef verjaardagen door aan andere ontvangers" + +#, python-format +msgid "Do you really want to delete the entry for %s?" +msgstr "Wilt u echt het bestand voor %s verwijderen?" + +msgid "Edit" +msgstr "Bewerk" + +msgid "Edit birthday" +msgstr "Bewerk verjaardag" + +msgid "Edit birthdays" +msgstr "Bewerk verjaardagen" + +msgid "Edit the selected entry" +msgstr "Bewerk de geselecteerde waarde" + +msgid "Enter the name of the person:" +msgstr "Geef de naam van de persoon:" + +#, python-format +msgid "" +"Error reading file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" +"Fout in lezen bestand %s.\n" +"\n" +"Fout: %s, %s" + +#, python-format +msgid "" +"Error writing file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" +"Fout in schrijven bestand %s.\n" +"\n" +"Fout: %s, %s" + +msgid "Exit the plugin" +msgstr "Verlaat de plugin" + +msgid "Export CSV file" +msgstr "Exporteer CSV bestand" + +msgid "Extras" +msgstr "Extras" + +msgid "Helps to remind of birthdays" +msgstr "Helpt te herinneren aan verjaardagen" + +msgid "Import CSV file" +msgstr "Importeer CSV bestand" + +msgid "Invalid Location" +msgstr "Ongeldige lokatie" + +msgid "Invalid date!" +msgstr "Ongeldige datum!" + +msgid "Month:" +msgstr "Maand:" + +msgid "Name" +msgstr "Naam" + +msgid "Name:" +msgstr "Naam:" + +msgid "Networking port (default: 7374):" +msgstr "Netwerk poort (default: 7374):" + +msgid "Next birthday" +msgstr "Volgende verjaardag" + +msgid "Notification time:" +msgstr "Waarschuwingstijd:" + +msgid "OK" +msgstr "OK" + +msgid "Open the extras menu" +msgstr "Open het extras menu" + +msgid "Path to birthday file:" +msgstr "Pad naar verjaardagen bestand:" + +msgid "Remind before birthday:" +msgstr "Herinner voor de verjaardag:" + +msgid "Remove" +msgstr "Verwijder" + +msgid "Remove the selected entry" +msgstr "Verwijder de geselecteerde waarde" + +msgid "Save" +msgstr "Sla op" + +msgid "Show plugin in extensions menu:" +msgstr "Toon plugin in extensies:" + +msgid "Sort birthdays by:" +msgstr "Sorteer verjaardagen volgens:" + +msgid "Sorting next" +msgstr "Volgende sortering" + +msgid "Sorting previous" +msgstr "Vorige sortering" + +#, python-format +msgid "" +"Today is %s's birthday!\n" +"\n" +"She/he was born on %s and is now %s year(s) old." +msgstr "" +"Vandaag is %s's verjaardag!\n" +"\n" +"Hij/Zij is geboren op %s en is nu %s jaar oud." + +msgid "VirtualKeyBoard" +msgstr "VirtualKeyBoard" + +msgid "What do you want to do?" +msgstr "Wat wilt u doen?" + +#, python-format +msgid "Wrote CSV file %s." +msgstr "CSV bestand %s geschreven." + +msgid "Year:" +msgstr "Jaar:" diff --git a/birthdayreminder/po/pl.po b/birthdayreminder/po/pl.po new file mode 100644 index 000000000..7183d8e33 --- /dev/null +++ b/birthdayreminder/po/pl.po @@ -0,0 +1,196 @@ +msgid "" +msgstr "" +"Project-Id-Version: Birthday Reminder\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2023-03-30 09:32+0200\n" +"Last-Translator: paps\n" +"Language-Team: paps\n" +"Language: pl_PL\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" +"X-Generator: Poedit 3.2.2\n" + +msgid "%s will turn %s in %s!" +msgstr "%s będzie miał/a %s urodziny za %s!" + +msgid "1 day" +msgstr "1 dzień" + +msgid "1 week" +msgstr "tydzień" + +msgid "3 days" +msgstr "3 dni" + +msgid "Add" +msgstr "Dodaj" + +msgid "Add a birthday" +msgstr "Dodaj urodziny" + +msgid "Add birthday" +msgstr "Dodaj urodziny" + +msgid "Age" +msgstr "Wiek" + +msgid "Birthday" +msgstr "Urodziny" + +msgid "Birthday Reminder" +msgstr "Przypomnienie o urodzinach" + +msgid "Birthday Reminder Settings" +msgstr "Ustawienia Birthday Reminder" + +msgid "Birthday Reminder received %s birthdays from %s." +msgstr "Birthday Remainder odebrał %s wpisów urodzin od %s." + +msgid "Birthday filename:" +msgstr "Nazwa pliku z urodzinami:" + +msgid "Birthdays" +msgstr "Lista urodzin" + +msgid "CSV import successful!" +msgstr "Pomyślnie zaimportowano plik CSV!" + +msgid "Can't find CSV file %s!" +msgstr "Nie można znaleźć pliku CSV: %s!" + +msgid "Can't import CSV data from file %s." +msgstr "Nie można zaimportować danych z pliku CSV: %s." + +msgid "Can't write CSV file %s." +msgstr "Nie można zapisać pliku CSV: %s." + +msgid "Date format:" +msgstr "Format daty:" + +msgid "Day:" +msgstr "Dzień:" + +msgid "Disabled" +msgstr "Wyłączone" + +msgid "Distribute birthdays to other Dreamboxes" +msgstr "Wysyłanie pliku z urodzinami do innych STB" + +msgid "Do you really want to delete the entry for %s?" +msgstr "Czy na pewno chcesz usunąć wpis '%s'?" + +msgid "Edit" +msgstr "Edycja" + +msgid "Edit birthday" +msgstr "Edycja urodzin" + +msgid "Edit birthdays" +msgstr "Edycja urodzin" + +msgid "Edit the selected entry" +msgstr "Edycja zaznaczonego wpisu" + +msgid "" +"Error reading file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" +"Błąd odczytu pliku: %s.\n" +"\n" +"Błąd: %s, %s" + +msgid "" +"Error writing file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" +"Błąd zapisu pliku: %s.\n" +"\n" +"Błąd: %s, %s" + +msgid "Exit the plugin" +msgstr "Wyjście" + +msgid "Export CSV file" +msgstr "Eksport pliku CSV" + +msgid "Extras" +msgstr "Dodatki" + +msgid "Helps to remind of birthdays" +msgstr "Przypomienie o urodzinach" + +msgid "Import CSV file" +msgstr "Import pliku CSV" + +msgid "Invalid date!" +msgstr "Niepoprawna data!" + +msgid "Month:" +msgstr "Miesiąc:" + +msgid "Name" +msgstr "Nazwisko" + +msgid "Name:" +msgstr "Nazwisko:" + +msgid "Networking port (default: 7374):" +msgstr "Port sieciowy (domyślnie: 7374)" + +msgid "Next birthday" +msgstr "Następne urodziny" + +msgid "Notification time:" +msgstr "Godzina przypomnienia:" + +msgid "Open the extras menu" +msgstr "Otwórz dodatkowe menu" + +msgid "Path to birthday file:" +msgstr "Ścieżka do pliku z urodzinami:" + +msgid "Remind before birthday:" +msgstr "Przypomnij przed urodzinami:" + +msgid "Remove" +msgstr "Usuń" + +msgid "Remove the selected entry" +msgstr "Usuń zaznaczony wpis" + +msgid "Show plugin in extensions menu:" +msgstr "Pokaż wtyczkę w rozszerzonym menu:" + +msgid "Sort birthdays by:" +msgstr "" +"Sortowanie listy \n" +"urodzin:" + +msgid "Sorting next" +msgstr "Następne" + +msgid "Sorting previous" +msgstr "Poprzednie" + +msgid "" +"Today is %s's birthday!\n" +"\n" +"She/he was born on %s and is now %s year(s) old." +msgstr "" +"Dzisiaj %s ma urodziny!\n" +"\n" +"Urodził/a się w %s i ma %s lat/a." + +msgid "What do you want to do?" +msgstr "Co chcesz zrobić?" + +msgid "Wrote CSV file %s." +msgstr "Zapisano plik CSV: %s." + +msgid "Year:" +msgstr "Rok:" diff --git a/birthdayreminder/po/pt.po b/birthdayreminder/po/pt.po new file mode 100644 index 000000000..32c72f423 --- /dev/null +++ b/birthdayreminder/po/pt.po @@ -0,0 +1,215 @@ +# Portuguese translations for enigma2-plugins package. +# Copyright (C) 2012 THE enigma2-plugins'S COPYRIGHT HOLDER +# This file is distributed under the same license as the enigma2-plugins package. +# Automatically generated, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-01-12 19:10+0100\n" +"PO-Revision-Date: 2023-03-30 21:37+0100\n" +"Last-Translator: NUNIGAIA \n" +"Language-Team: \n" +"Language: pt\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.2.2\n" + +#, python-format +msgid "%s will turn %s in %s!" +msgstr "%s vai-se %s transformar em %s!" + +msgid "1 day" +msgstr "1 dia" + +msgid "1 week" +msgstr "1 semana" + +msgid "3 days" +msgstr "3 dias" + +msgid "Add" +msgstr "Adicionar" + +msgid "Add a birthday" +msgstr "Adicionar um aniversário" + +msgid "Add birthday" +msgstr "Adicionar aniversário" + +msgid "Age" +msgstr "Idade" + +msgid "Birthday" +msgstr "Aniversário" + +msgid "Birthday Reminder" +msgstr "Lembrete de aniversário" + +msgid "Birthday Reminder Settings" +msgstr "Definições do lembrete de aniversário" + +#, python-format +msgid "Birthday Reminder received %s birthdays from %s." +msgstr "Lembrete de aniversário recebido %s aniversários de %s." + +msgid "Birthday filename:" +msgstr "Nome do arquivo de aniversário:" + +msgid "Birthdays" +msgstr "Aniversários" + +msgid "CSV import successful!" +msgstr "Importação de CSV bem-sucedida!" + +#, python-format +msgid "Can't find CSV file %s!" +msgstr "Não é possível encontrar o arquivo CSV %s!" + +#, python-format +msgid "Can't import CSV data from file %s." +msgstr "Não é possível importar dados CSV do arquivo %s." + +#, python-format +msgid "Can't write CSV file %s." +msgstr "Não é possível gravar o arquivo CSV %s." + +msgid "Date format:" +msgstr "Formato da Data:" + +msgid "Day:" +msgstr "Dia:" + +msgid "Disabled" +msgstr "Inativo" + +msgid "Distribute birthdays to other Dreamboxes" +msgstr "Distribuir aniversários para outros receptores" + +#, python-format +msgid "Do you really want to delete the entry for %s?" +msgstr "Você realmente deseja excluir a entrada para %s?" + +msgid "Edit" +msgstr "Editar" + +msgid "Edit Birthday Settings" +msgstr "Editar configurações de aniversário" + +msgid "Edit birthday" +msgstr "Editar aniversário" + +msgid "Edit birthdays" +msgstr "Editar aniversários" + +msgid "Edit the selected entry" +msgstr "Editar a entrada selecionada" + +#, python-format +msgid "" +"Error reading file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" +"Erro ao ler %s do arquivo.\n" +"\n" +"Erro: %s, %s" + +#, python-format +msgid "" +"Error writing file %s.\n" +"\n" +"Error: %s, %s" +msgstr "" +"Erro ao gravar %s de arquivo.\n" +"\n" +"Erro: %s, %s" + +msgid "Exit the plugin" +msgstr "Sair do plugin" + +msgid "Export CSV file" +msgstr "Exportar arquivo CSV" + +msgid "Extras" +msgstr "Extras" + +msgid "Helps to remind of birthdays" +msgstr "Ajuda a lembrar de aniversários" + +msgid "Import CSV file" +msgstr "Importar arquivo CSV" + +msgid "Invalid date!" +msgstr "Data inválida!" + +msgid "Month:" +msgstr "Mês:" + +msgid "Name" +msgstr "Nome" + +msgid "Name:" +msgstr "Nome:" + +msgid "Networking port (default: 7374):" +msgstr "Porta de rede (padrão: 7374):" + +msgid "Next birthday" +msgstr "Próximo aniversário" + +msgid "Notification time:" +msgstr "Hora da notificação:" + +msgid "Open the extras menu" +msgstr "Abrir o menu de extras" + +msgid "Path to birthday file:" +msgstr "Caminho para o arquivo de aniversário:" + +msgid "Remind before birthday:" +msgstr "Lembrar antes do aniversário:" + +msgid "Remove" +msgstr "Remover" + +msgid "Remove the selected entry" +msgstr "Remover a entrada selecionada" + +msgid "Select a path for the birthday file" +msgstr "Selecione um caminho para o arquivo de aniversário" + +msgid "Show plugin in extensions menu:" +msgstr "Mostrar plugin no menu de extensões:" + +msgid "Sort birthdays by:" +msgstr "Ordenar aniversários por:" + +msgid "Sorting next" +msgstr "Ordenação seguinte" + +msgid "Sorting previous" +msgstr "Ordenação anterior" + +#, python-format +msgid "" +"Today is %s's birthday!\n" +"\n" +"She/he was born on %s and is now %s year(s) old." +msgstr "" +"Hoje é aniversário de %s!\n" +"\n" +"Ele / ela nasceu em %s e agora tem %s ano (s) de idade." + +msgid "What do you want to do?" +msgstr "O que pretende fazer?" + +#, python-format +msgid "Wrote CSV file %s." +msgstr "Escreveu o arquivo CSV %s." + +msgid "Year:" +msgstr "Ano:" diff --git a/birthdayreminder/src/BirthdayNetworking.py b/birthdayreminder/src/BirthdayNetworking.py new file mode 100644 index 000000000..7de345c55 --- /dev/null +++ b/birthdayreminder/src/BirthdayNetworking.py @@ -0,0 +1,138 @@ +# PYTHON IMPORTS +from pickle import loads as pickle_loads +from six import ensure_binary +from socket import SOL_SOCKET, SO_BROADCAST +from twisted.internet.error import ConnectionDone +from twisted.internet.protocol import DatagramProtocol, ServerFactory, ClientFactory, Protocol + +# ENIGMA IMPORTS +from Components.config import config + +# for localized messages +from . import _ + + +class BroadcastProtocol(DatagramProtocol): # this class handles UDP broadcasts (send/receive) + def __init__(self, parent): + self.parent = parent + self.port = config.plugins.birthdayreminder.broadcastPort.value + self.uuid = self.getNodeHack() # sent with broadcasts to identify ourselves when receiving our own broascast :o + + def startProtocol(self): + if self.transport: + self.transport.socket.setsockopt(SOL_SOCKET, SO_BROADCAST, True) + + def sendBroadcast(self, message): + if self.transport: + newMessage = ensure_binary(''.join([self.uuid, " ", message])) + self.transport.write(newMessage, ("255.255.255.255", self.port)) + + def datagramReceived(self, data, addr): + parts = data.split() # filter unknown data. we expect two parts, a uuid and a "command" + if len(parts) != 2: + return + if parts[0] == self.uuid: # ignore our own package + return + elif parts[1] == "offeringList": # a box is offering to send a list + print("[Birthday Reminder] received a list offer from %s" % addr[0]) + self.parent.requestBirthdayList(addr) + elif parts[1] == "ping": # are we there? + print("[Birthday Reminder] received ping from %s" % addr[0]) + self.parent.sendPingResponse(addr) + + def getNodeHack(self): + from os import urandom + return str(urandom(16)) + + +class TransferServerProtocol(Protocol): # the server classes are used to send and receive birthday lists + def __init__(self, parent): + self.parent = parent + + def connectionMade(self): + if self.transport: + print("[Birthday Reminder] client %s connected" % self.transport.getPeer().host) + + def dataReceived(self, data): + peer = self.transport.getPeer().host if self.transport else None + if data == "requestingList": + print("[Birthday Reminder] sending birthday list to client %s" % peer) + data = self.parent.readRawFile() + if data and self.transport: + self.transport.write(data) + else: # should be a pickled birthday list... + receivedList = None + try: # let's see if it's pickled data + receivedList = pickle_loads(data) + print("[Birthday Reminder] received birthday list from %s" % peer) + except Exception as err: + print("[Birthday Reminder] received unknown package from %s" % peer) + if receivedList is None: + return + self.parent.writeRawFile(data) + self.parent.load() + self.parent.addAllTimers() + self.parent.showReceivedMessage(len(receivedList), peer) + if self.transport: + self.transport.loseConnection() + + def connectionLost(self, reason): + if self.transport: + if reason.type == ConnectionDone: + print("[Birthday Reminder] closed connection to client %s" % self.transport.getPeer().host) + else: + print("[Birthday Reminder] lost connection to client %s. Reason: %s" % (self.transport.getPeer().host, str(reason.value))) + + +class TransferServerFactory(ServerFactory): + def __init__(self, parent): + self.parent = parent + + def buildProtocol(self, addr): + return TransferServerProtocol(self.parent) + + +class TransferClientProtocol(Protocol): # the client classes are used to request and receive birthday lists + def __init__(self, parent, data): + self.parent = parent + self.data = data + + def dataReceived(self, data): + peer = self.transport.getPeer().host if self.transport else None + receivedList = None + try: + receivedList = pickle_loads(data) + print("[Birthday Reminder] received birthday list from %s" % peer) + except Exception as err: + print("[Birthday Reminder] received unknown package from %s" % peer) + if receivedList is None: + return + self.parent.save(receivedList) # save and load the received list + self.parent.load() + self.parent.addAllTimers() + self.parent.showReceivedMessage(len(receivedList), peer) + + def connectionMade(self): + if self.transport: + self.transport.write(self.data) + + +class TransferClientFactory(ClientFactory): + def __init__(self, parent, data): + self.parent = parent + self.data = data + + def buildProtocol(self, addr): + return TransferClientProtocol(self.parent, self.data) + + def startedConnecting(self, connector): + dest = ''.join([connector.getDestination().host, ":", str(connector.getDestination().port)]) + + def clientConnectionFailed(self, connector, reason): + print("[Birthday Reminder] connection to server %s failed. Reason: %s" % (connector.getDestination().host, str(reason.value))) + + def clientConnectionLost(self, connector, reason): + if reason.type == ConnectionDone: + print("[Birthday Reminder] disconnected from server %s" % connector.getDestination().host) + else: + print("[Birthday Reminder] lost connection to server %s. Reason: %s" % (connector.getDestination().host, str(reason.value))) diff --git a/birthdayreminder/src/BirthdayReminder.py b/birthdayreminder/src/BirthdayReminder.py new file mode 100644 index 000000000..b098ae6c0 --- /dev/null +++ b/birthdayreminder/src/BirthdayReminder.py @@ -0,0 +1,497 @@ +# PYTHON IMPORTS +from copy import copy +from csv import writer as csv_writer, reader as csv_reader +from datetime import datetime, date +from os.path import isfile, join, split +from pickle import dump, load +from time import mktime, strptime +from functools import cmp_to_key + +# ENIGMA IMPORTS +from Components.ActionMap import HelpableActionMap +from Components.config import config, NoSave, ConfigText, ConfigInteger, ConfigDirectory +from Components.Label import Label +from Components.Sources.List import List +from Components.Sources.StaticText import StaticText +from Screens.ChoiceBox import ChoiceBox +from Screens.HelpMenu import HelpableScreen +from Screens.MessageBox import MessageBox +from Screens.Screen import Screen +from skin import parseColor +from Tools import Notifications +from Screens.LocationBox import defaultInhibitDirs, LocationBox +from Screens.Setup import Setup + +# for localized messages +from . import _ + +CSVFILE = "/tmp/birthdayreminder.csv" +MODULE_NAME = __name__.split(".")[-1] + + +class BirthdayStore: + def __init__(self): + self.loadStore() + + def readRawFile(self): + data = None + fileName = config.plugins.birthdayreminder.file.value + if isfile(fileName): + try: + with open(fileName, "r") as f: + data = f.read() + except IOError as err: + (error_no, error_str) = err.args + print("[%s] ERROR reading from file %s. Error: %s, %s" % (MODULE_NAME, fileName, error_no, error_str)) + text = _("Error reading file %s.\n\nError: %s, %s") % (fileName, error_no, error_str) + Notifications.AddNotification(MessageBox, text, type=MessageBox.TYPE_ERROR, timeout=3) + return data + + def writeRawFile(self, data): + fileName = config.plugins.birthdayreminder.file.value + try: + with open(fileName, "w") as f: + f.write(data) + except IOError as err: + (error_no, error_str) = err.args + print("[%s] ERROR writing to file %s. Error: %s, %s" % (MODULE_NAME, fileName, error_no, error_str)) + text = _("Error writing file %s.\n\nError: %s, %s") % (fileName, error_no, error_str) + Notifications.AddNotification(MessageBox, text, type=MessageBox.TYPE_ERROR, timeout=3) + + def loadStore(self): # read the birthday information from file + fileName = config.plugins.birthdayreminder.file.value + print("[%s] reading from file %s" % (MODULE_NAME, fileName)) + tmpList = [] + if isfile(fileName): + try: + with open(fileName, "rb") as f: + tmpList = load(f) + except IOError as err: + (error_no, error_str) = err.args + print("[%s] ERROR reading from file %s. Error: %s, %s" % (MODULE_NAME, fileName, error_no, error_str)) + text = _("Error reading file %s.\n\nError: %s, %s") % (fileName, error_no, error_str) + Notifications.AddNotification(MessageBox, text, type=MessageBox.TYPE_ERROR, timeout=3) + print("[%s] read %s birthdays" % (MODULE_NAME, len(tmpList))) + else: + print("[%s] File %s not found." % (MODULE_NAME, fileName)) + self.bDayList = tmpList + + def saveStore(self, data=None): # write the birthday information to file + fileName = config.plugins.birthdayreminder.file.value + print("[%s] writing to file %s" % (MODULE_NAME, fileName)) + try: + with open(fileName, "wb") as f: + dump(data if data else self.getBirthdayList(), f) + print("[%s] wrote %s birthdays to %s" % (MODULE_NAME, self.getSize(), fileName)) + except IOError as err: + (error_no, error_str) = err.args + print("[%s] ERROR writing to file %s. Error: %s, %s" % (MODULE_NAME, fileName, error_no, error_str)) + text = _("Error writing file %s.\n\nError: %s, %s") % (MODULE_NAME, fileName, error_no, error_str) + Notifications.AddNotification(MessageBox, text, type=MessageBox.TYPE_ERROR, timeout=3) + + def getSize(self): # return the number of birthdays in list + return len(self.bDayList) + + def getBirthdayList(self): # return the list of birthdays + return self.bDayList + + def addEntry(self, entry): # add a new entry to the list + self.bDayList.append(entry) + self.saveStore() + + def removeEntry(self, idx): # remove an entry from the list + self.bDayList.pop(idx) + self.saveStore() + + def updateEntry(self, oldEntry, newEntry): # update a list entry + idx = self.bDayList.index(oldEntry) + self.bDayList[idx] = newEntry + self.saveStore() + + def getEntry(self, idx): # get a list entry + return self.bDayList[idx] + + +class BirthdayReminder(Screen, HelpableScreen): + skin = """ + + + + + + + + + + + + + + + {"template": [ + MultiContentEntryText(pos = (0, 0), size = (295, 25), font=0, flags = RT_HALIGN_LEFT, text = 0), + MultiContentEntryText(pos = (300, 0), size = (165, 25), font=0, flags = RT_HALIGN_CENTER, text = 1), + MultiContentEntryText(pos = (470, 0), size = (50, 25), font=0, flags = RT_HALIGN_RIGHT, text = 2), + ], + "fonts": [gFont("Regular", 22)], + "itemHeight": 25 + } + + + """ % _("Birthday Reminder") + + def __init__(self, session, birthdaytimer): + self.session = session + self.birthdaytimer = birthdaytimer + Screen.__init__(self, session) + self["key_red"] = StaticText(_("Add")) + self["key_green"] = StaticText("") + self["key_yellow"] = StaticText("") + self["key_blue"] = StaticText(_("Extras")) + self["name"] = Label(_("Name")) + self["birthday"] = Label(_("Birthday")) + self["age"] = Label(_("Age")) + self["list"] = BirthdayList(self.birthdaytimer.getBirthdayList()) + HelpableScreen.__init__(self) + self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", + { + "cancel": (self.exit, _("Exit the plugin")), + }, -1) + self["BaseActions"] = HelpableActionMap(self, "ColorActions", + { + "red": (self.addBirthday, _("Add a birthday")), + "blue": (self.openExtras, _("Open the extras menu")), + }, -1) + # this ActionMap can be enabled/disabled depending on the number of list entries + self["EditActions"] = HelpableActionMap(self, "ColorActions", + { + "green": (self.editBirthday, _("Edit the selected entry")), + "yellow": (self.removeBirthday, _("Remove the selected entry")), + }, -1) + self["ChannelSelectBaseActions"] = HelpableActionMap(self, "ChannelSelectBaseActions", + { + "prevBouquet": (self.changeSortingUp, _("Sorting next")), + "nextBouquet": (self.changeSortingDown, _("Sorting previous")), + }, -1) + self.setButtonState() + self.onLayoutFinish.append(self.cbOnLayoutFinished) + + def cbOnLayoutFinished(self): + self.setListSorted() + + def exit(self): # exit the plugin + self.close() + + def addBirthday(self): # add a birthday + self.session.openWithCallback(self.cbAddBirthday, EditBirthdaySetting) + + def editBirthday(self): # edit a birthday + selected = self["list"].getCurrent() + t = strptime(selected[1], "%m/%d/%Y") if config.plugins.birthdayreminder.dateFormat.value == "mmddyyyy" else strptime(selected[1], "%d.%m.%Y") + newDate = date(*t[:3]) + self.bDayBeforeChange = (selected[0], newDate) + self.session.openWithCallback(self.cbEditBirthday, EditBirthdaySetting, self.bDayBeforeChange) + + def removeBirthday(self): # remove a birthday? + selected = self["list"].getCurrent() + self.session.openWithCallback(self.cbDeleteBirthday, MessageBox, _("Do you really want to delete the entry for %s?") % selected[0], MessageBox.TYPE_YESNO) + + def setButtonState(self): # set the state of the buttons depending on the list size + if not self.birthdaytimer.getSize(): # no entries in list + self["EditActions"].setEnabled(False) + self["key_green"].setText("") + self["key_yellow"].setText("") + else: + self["EditActions"].setEnabled(True) + self["key_green"].setText(_("Edit")) + self["key_yellow"].setText(_("Remove")) + + def openExtras(self): # open extras menu + choiceList = [(_("Export CSV file"), "csvexport"), (_("Import CSV file"), "csvimport"), (_("Distribute birthdays to other Dreamboxes"), "sendListOffer")] + self.session.openWithCallback(self.cbOpenExtras, ChoiceBox, title=_("What do you want to do?"), list=choiceList) + + def cbOpenExtras(self, result): + if result is None: + return + elif result[1] == "csvexport": + self.saveCSV() + elif result[1] == "csvimport": + self.loadCSV() + elif result[1] == "sendListOffer": + self.sendListOffer() + + def cbAddBirthday(self, name, birthday): # this callback is called when a birthday was added + if name is None and birthday is None: + return + entry = (name, birthday) + self.birthdaytimer.addEntry(entry) + self["list"].setList(self.birthdaytimer.getBirthdayList()) + self.setButtonState() + self.birthdaytimer.addTimer(entry) + if config.plugins.birthdayreminder.preremind.value != "-1": + self.birthdaytimer.addTimer(entry, preremind=True) + self.setListSorted(newEntry=entry) + + def cbEditBirthday(self, name, birthday): # this callback is called when a birthday was edited + (oldName, oldBirthday) = self.bDayBeforeChange + if (name == oldName and birthday == oldBirthday) or (name is None and birthday is None): + return + newEntry = (name, birthday) + self.birthdaytimer.updateEntry(self.bDayBeforeChange, newEntry) + self.birthdaytimer.updateTimer(self.bDayBeforeChange, newEntry) + self["list"].updateList(self.birthdaytimer.getBirthdayList()) + self.setListSorted(newEntry=newEntry) + + def cbDeleteBirthday(self, result): # really delete the selected birthday entry? + if not result: + return + selected = self["list"].getCurrent() + t = strptime(selected[1], "%m/%d/%Y") if config.plugins.birthdayreminder.dateFormat.value == "mmddyyyy" else strptime(selected[1], "%d.%m.%Y") + newDate = date(*t[:3]) + entry = (selected[0], newDate) + self.birthdaytimer.removeTimersForEntry(entry) + idx = self["list"].getIndex() + self.birthdaytimer.removeEntry(idx) + self["list"].setList(self.birthdaytimer.getBirthdayList()) + size = self.birthdaytimer.getSize() # set selection + if size > 1 and idx < size: + self["list"].setIndex(idx) + elif size > 1 and idx >= size: + self["list"].setIndex(size - 1) + self.setButtonState() + + def changeSortingUp(self): # change direction of sorting upwards + if config.plugins.birthdayreminder.sortby.value == "1": + config.plugins.birthdayreminder.sortby.value = "3" + else: + val = int(config.plugins.birthdayreminder.sortby.value) - 1 + config.plugins.birthdayreminder.sortby.value = str(val) + config.plugins.birthdayreminder.sortby.save() + self.setListSorted() + + def changeSortingDown(self): # change direction of sorting downwards + if config.plugins.birthdayreminder.sortby.value == "3": + config.plugins.birthdayreminder.sortby.value = "1" + else: + val = int(config.plugins.birthdayreminder.sortby.value) + 1 + config.plugins.birthdayreminder.sortby.value = str(val) + config.plugins.birthdayreminder.sortby.save() + self.setListSorted() + + def setListSorted(self, newEntry=None): # birthday list sorting + if not self.birthdaytimer.getSize(): + return + if config.plugins.birthdayreminder.sortby.value == "1": # sort by name + self["name"].instance.setForegroundColor(parseColor("yellow")) + self["birthday"].instance.setForegroundColor(parseColor("white")) + self["age"].instance.setForegroundColor(parseColor("white")) + self.birthdaytimer.bDayList.sort(key=lambda t: tuple(t[0].lower())) + elif config.plugins.birthdayreminder.sortby.value == "2": # sort by upcoming birthday + self["name"].instance.setForegroundColor(parseColor("white")) + self["birthday"].instance.setForegroundColor(parseColor("yellow")) + self["age"].instance.setForegroundColor(parseColor("white")) + self.birthdaytimer.bDayList.sort(key=cmp_to_key(self.compareDates)) + else: # sort by age + self["name"].instance.setForegroundColor(parseColor("white")) + self["birthday"].instance.setForegroundColor(parseColor("white")) + self["age"].instance.setForegroundColor(parseColor("yellow")) + self.birthdaytimer.bDayList.sort(key=cmp_to_key(self.compareAges)) + self["list"].setList(self.birthdaytimer.getBirthdayList()) + if newEntry: + newIdx = self["list"].getIndexForEntry(newEntry) + self["list"].setIndex(newIdx) + + def compareDates(self, x, y): + x = x[1] + y = y[1] + today = date.today() + try: + bDay1 = x.replace(year=today.year) + except ValueError: # raised on feb 29th + bDay1 = x.replace(year=today.year, day=x.day - 1) + if bDay1 < today: # next birthday in next year + try: + bDay1 = x.replace(year=today.year + 1) + except ValueError: # raised on feb 29th + bDay1 = x.replace(year=today.year + 1, day=x.day - 1) + ts1 = int(mktime(bDay1.timetuple())) + try: + bDay2 = y.replace(year=today.year) + except ValueError: # raised on feb 29th + bDay2 = y.replace(year=today.year, day=y.day - 1) + if bDay2 < today: # next birthday in next year + try: + bDay2 = y.replace(year=today.year + 1) + except ValueError: # raised on feb 29th + bDay2 = y.replace(year=today.year + 1, day=y.day - 1) + ts2 = int(mktime(bDay2.timetuple())) + return ts1 - ts2 + + def compareAges(self, x, y): + x = x[1] + y = y[1] + ageX = getAge(x) + ageY = getAge(y) + if ageX == ageY: # ages are the same, sort by birthday + tX = int(mktime(x.timetuple())) + tY = int(mktime(y.timetuple())) + return tX - tY + else: + return ageX - ageY + + def saveCSV(self): + print("[%s] exporting CSV file %s" % (MODULE_NAME, CSVFILE)) + try: + with open(CSVFILE, "w") as csvFile: + writer = csv_writer(csvFile) + writer.writerows(self.birthdaytimer.getBirthdayList()) + self.session.open(MessageBox, _("Wrote CSV file %s.") % CSVFILE, MessageBox.TYPE_INFO, timeout=3) + except Exception as err: + self.session.open(MessageBox, _("Can't write CSV file '%s'. Error: %s") % (CSVFILE, str(err)), MessageBox.TYPE_ERROR, timeout=3) + + def loadCSV(self): + print("[%s] importing CSV file %s" % (MODULE_NAME, CSVFILE)) + if not isfile(CSVFILE): + text = _("Can't find CSV file %s!") % CSVFILE + self.session.open(MessageBox, text, MessageBox.TYPE_ERROR, timeout=3) + return + csvList = [] + try: + with open(CSVFILE, "r") as csvFile: + reader = csv_reader(csvFile) + for row in reader: + name = row[0] + bDay = row[1] + if bDay[:4].isdigit() and int(bDay[:4]) < 1910: # avoid crashes due to E2-problem with mktime() and dates < 1901-12-15' + bDay = "1910%s" % bDay[4:] + newDate = date.fromtimestamp(mktime(strptime(bDay, "%Y-%m-%d"))) + entry = (name, newDate) + csvList.append(entry) + except IOError as err: + (error_no, error_str) = err.args + text = _("Error reading file %s.\n\nError: %s, %s") % (CSVFILE, error_no, error_str) + self.session.open(MessageBox, text, MessageBox.TYPE_ERROR, timeout=3) + return + self.birthdaytimer.bDayList = copy(csvList) # the critical part is done, now update the lists and timers + self.birthdaytimer.saveStore() + self["list"].setList(self.birthdaytimer.getBirthdayList()) + self.setListSorted() + self.setButtonState() + self.birthdaytimer.timer_list = [] + self.birthdaytimer.start() + self.session.open(MessageBox, _("CSV import successful!"), MessageBox.TYPE_INFO, timeout=3) + + def sendListOffer(self): + print("[%s] broadcasting list offer" % MODULE_NAME) + self.birthdaytimer.broadcastProtocol.sendBroadcast("offeringList") + + +class BirthdayList(List): + def __init__(self, list=None): + List.__init__(self, list=[]) + self.__list = list + + def setList(self, list): + self.__list = list + self.changed((self.CHANGED_ALL,)) + + def getList(self): # some kind of buildFunc replacement :) + dformat = "%m/%d/%Y" if config.plugins.birthdayreminder.dateFormat.value == "mmddyyyy" else "%d.%m.%Y" + l = [] + if self.__list: + for entry in self.__list: + name = entry[0] + birthday = entry[1].strftime(dformat) + age = str(getAge(entry[1])) + l.append((name, birthday, age)) + return l + list = property(getList, setList) + + def getIndexForEntry(self, entry): + if self.__list: + return self.__list.index(entry) if self.master is not None else None + + +class EditBirthdaySetting(Setup): + def __init__(self, session, entry=None): + (name, birthday) = entry if entry is not None else ("", date(*strptime("1.1.1900", "%d.%m.%Y")[:3])) + config.plugins.birthdayreminder.name = NoSave(ConfigText(default=name, fixed_size=False, visible_width=40)) + config.plugins.birthdayreminder.day = NoSave(ConfigInteger(default=birthday.day, limits=(1, 31))) + config.plugins.birthdayreminder.month = NoSave(ConfigInteger(default=birthday.month, limits=(1, 12))) + config.plugins.birthdayreminder.year = NoSave(ConfigInteger(default=birthday.year, limits=(1900, 2050))) + Setup.__init__(self, session, "EditBirthdaySetting", plugin="Extensions/BirthdayReminder", PluginLanguageDomain="BirthdayReminder") + self.setTitle(_("Add birthday") if entry is None else _("Edit birthday")) + + def keyCancel(self): + self.close(None, None) + + def keySave(self): + try: + birthdayDt = datetime(config.plugins.birthdayreminder.year.value, config.plugins.birthdayreminder.month.value, config.plugins.birthdayreminder.day.value) + birthday = datetime.date(birthdayDt) + self.close(config.plugins.birthdayreminder.name.value, birthday) + except ValueError: + self["footnote"].setText(_("Invalid date!")) + + +class BirthdayReminderSettings(Setup): + def __init__(self, session, birthdaytimer): + self.birthdaytimer = birthdaytimer + path, filename = split(config.plugins.birthdayreminder.file.value) + self.path = NoSave(ConfigDirectory(default=path)) + self.filename = NoSave(ConfigText(default=filename, visible_width=50, fixed_size=False)) + self.preremind = config.plugins.birthdayreminder.preremind.value + self.notificationTime = copy(config.plugins.birthdayreminder.notificationTime.value) + Setup.__init__(self, session, "BirthdayReminderSettings", plugin="Extensions/BirthdayReminder", PluginLanguageDomain="BirthdayReminder") + self.setTitle(_("Birthday Reminder Settings")) + self["key_blue"] = StaticText(_("Birthdays")) + self["blueActions"] = HelpableActionMap(self, ["ColorActions"], { + "blue": (self.editBirthdays, _("Edit birthdays")) + }, prio=0) + + def keySelect(self): + if self.getCurrentItem() == self.path: + self.session.openWithCallback(self.keySelectCallback, BirthdayReminderLocationBox, initDir=self.path.value) + return + Setup.keySelect(self) + + def keySelectCallback(self, path): + if path is not None: + path = join(path, "") + self.path.value = path + self["config"].invalidateCurrent() + self.changedEntry() + + def keySave(self): + config.plugins.birthdayreminder.file.value = join(self.path.value, self.filename.value) + config.plugins.birthdayreminder.file.save() + config.plugins.birthdayreminder.file.changed() + if config.plugins.birthdayreminder.preremind.value != self.preremind: + if self.preremind == "-1": + config.plugins.birthdayreminder.preremindChanged.setValue(True) # there are no preremind timers, add new timers + else: + config.plugins.birthdayreminder.preremindChanged.setValue(False) # change existing preremind timers + if config.plugins.birthdayreminder.notificationTime.value != self.notificationTime: + config.plugins.birthdayreminder.notificationTimeChanged.setValue(True) + Setup.keySave(self) + + def editBirthdays(self): + self.session.open(BirthdayReminder, self.birthdaytimer) + + +class BirthdayReminderLocationBox(LocationBox): + def __init__(self, session, initDir): + inhibit = defaultInhibitDirs + inhibit.remove("/etc") + LocationBox.__init__(self, session, text=_("Select a path for the birthday file"), currDir=join(initDir, ""), inhibitDirs=inhibit,) + self.skinName = ["WeatherSettingsLocationBox", "LocationBox"] + + +def getAge(birthday): + today = date.today() + try: + bDay = birthday.replace(year=today.year) # take care of feb 29th, use feb 28th if necessary + except ValueError: # raised on feb 29th + bDay = birthday.replace(year=today.year, day=birthday.day - 1) + age = today.year - birthday.year + return age - 1 if bDay > today else age diff --git a/birthdayreminder/src/BirthdayTimer.py b/birthdayreminder/src/BirthdayTimer.py new file mode 100644 index 000000000..01fed03b9 --- /dev/null +++ b/birthdayreminder/src/BirthdayTimer.py @@ -0,0 +1,252 @@ +# OWN IMPORTS +from .BirthdayNetworking import BroadcastProtocol, TransferServerFactory, TransferClientFactory +from .BirthdayReminder import BirthdayStore, getAge + +# PYTHON IMPORTS +from datetime import datetime, date, timedelta, time as dt_time +from time import mktime, time, strftime, strptime +from timer import Timer, TimerEntry +from twisted.internet import reactor + +# ENIGMA IMPORTS +from Components.config import config +from enigma import eDVBLocalTimeHandler +from Screens.MessageBox import MessageBox +from Tools import Notifications + +# for localized messages +from . import _ + + +class BirthdayTimerEntry(TimerEntry): + def __init__(self, begin, end, preremind): + TimerEntry.__init__(self, int(begin), int(end)) + self.preremind = preremind + self.state = self.StatePrepared + + def getNextActivation(self): + return self.begin + + def activate(self): + if self.preremind: + when = config.plugins.birthdayreminder.preremind.getText() + print("[Birthday Reminder] %s will turn %s in %s!" % (self.bDay[0], getAge(self.bDay[1]) + 1, when)) + text = _("%s will turn %s in %s!") % (self.bDay[0], getAge(self.bDay[1]) + 1, when) + else: + print("[Birthday Reminder] It's %s's birthday today!" % self.bDay[0]) + + if config.plugins.birthdayreminder.dateFormat.value == "mmddyyyy": + format = "%m/%d/%Y" + else: + format = "%d.%m.%Y" + birthday = self.bDay[1].strftime(format) + + text = _("Today is %s's birthday!\n\nShe/he was born on %s and is now %s year(s) old.") % (self.bDay[0], birthday, getAge(self.bDay[1])) + + Notifications.AddNotification(MessageBox, text, type=MessageBox.TYPE_INFO) + + # activate the timer for next year + now = date.today() + bDay = self.bDay[1] + + # set timer to feb 28th for birthdays on feb 29th + try: + bDayNextYear = date(now.year + 1, bDay.month, bDay.day) + except ValueError: # raised on feb 29th + bDayNextYear = date(now.year + 1, bDay.month, bDay.day - 1) + + self.begin = int(mktime(bDayNextYear.timetuple())) + self.end = self.begin - 1 + self.state = self.StatePrepared + + return True + + def shouldSkip(self): + return False + + def timeChanged(self): + self.state = self.StatePrepared + + +class BirthdayTimer(Timer, BirthdayStore): + def __init__(self): + BirthdayStore.__init__(self) + Timer.__init__(self) + + # this is used to detect settings changes, because we only want to change preremind timers if a different value was saved by the user + config.plugins.birthdayreminder.preremindChanged.addNotifier(self.cbPreremindChanged, initial_call=False) + config.plugins.birthdayreminder.notificationTimeChanged.addNotifier(self.cbNotificationTimeChanged, initial_call=False) + + # let's wait for the system time being up to date before starting the timers. needed when the box was powered off + if not eDVBLocalTimeHandler.getInstance().ready(): + eDVBLocalTimeHandler.getInstance().m_timeUpdated.get().append(self.startTimer) + else: + self.start() + self.startNetworking() + self.broadcastPort = None + self.transferServerPort = None + + def startTimer(self): + eDVBLocalTimeHandler.getInstance().m_timeUpdated.get().remove(self.startTimer) + self.start() + self.startNetworking() + + def start(self): + if not self.getSize(): + print("[Birthday Reminder] Got no birthdays, no timers to add.") + return + + self.addAllTimers() + + def stop(self): + self.stopNetworking() + + print("[Birthday Reminder] stopping timer...") + + self.timer.stop() + self.timer_list = [] + self.timer.callback.remove(self.calcNextActivation) + self.timer = None + + config.plugins.birthdayreminder.preremindChanged.notifiers.remove(self.cbPreremindChanged) + config.plugins.birthdayreminder.notificationTimeChanged.notifiers.remove(self.cbNotificationTimeChanged) + + def startNetworking(self): + print("[Birthday Reminder] starting network communication...") + + port = config.plugins.birthdayreminder.broadcastPort.value + self.transferServerProtocol = TransferServerFactory(self) + self.broadcastProtocol = BroadcastProtocol(self) + try: + self.transferServerPort = reactor.listenTCP(port, self.transferServerProtocol) + self.broadcastPort = reactor.listenUDP(port, self.broadcastProtocol) + except: + print("[Birthday Reminder] can't listen on port %s" % port) + + def stopNetworking(self): + print("[Birthday Reminder] stopping network communication...") + self.broadcastPort and self.broadcastPort.stopListening() + self.transferServerPort and self.transferServerPort.stopListening() + + def requestBirthdayList(self, addr): + print("[Birthday Reminder] requesting birthday list from %s" % addr[0]) + reactor.connectTCP(addr[0], 7374, TransferClientFactory(self, "requestingList")) + + def sendPingResponse(self, addr): + print("[Birthday Reminder] sending ping response to %s" % addr[0]) + reactor.connectTCP(addr[0], 7374, TransferClientFactory(self, "pong")) + + def updateTimer(self, oldBirthday, newBirthday): + print("[Birthday Reminder] updating timer for %s" % oldBirthday[0]) + + self.removeTimersForEntry(oldBirthday) + self.addTimer(newBirthday) + + # add a preremind timer also? + if config.plugins.birthdayreminder.preremind.getValue() != "-1": + self.addTimer(newBirthday, preremind=True) + + def addTimer(self, entry, preremind=False): + if preremind: + print("[Birthday Reminder] Adding preremind timer for %s" % entry[0]) + else: + print("[Birthday Reminder] Adding birthday timer for %s" % entry[0]) + + timeList = config.plugins.birthdayreminder.notificationTime.value + notifyTime = dt_time(timeList[0], timeList[1]) + now = date.today() + bDay = entry[1] + + if preremind: + numDays = int(config.plugins.birthdayreminder.preremind.getValue()) + # set timer to feb 28th for birthdays on feb 29th + try: + dateThisYear = date(now.year, bDay.month, bDay.day) - timedelta(numDays) + except ValueError: # raised on feb 29th + dateThisYear = date(now.year, bDay.month, bDay.day - 1) - timedelta(numDays) + else: + # set timer to feb 28th for birthdays on feb 29th + try: + dateThisYear = date(now.year, bDay.month, bDay.day) + except ValueError: # raised on feb 29th + dateThisYear = date(now.year, bDay.month, bDay.day - 1) + + dateTimeThisYear = datetime.combine(dateThisYear, notifyTime) + + if dateThisYear >= now: # check if the birthday is in this year + begin = int(mktime(dateTimeThisYear.timetuple())) + else: # birthday is in the past, we need a timer for the next year + # set timer to feb 28th for birthdays on feb 29th + try: + bDayNextYear = dateTimeThisYear.replace(year=dateThisYear.year + 1) + except ValueError: # raised on feb 29th + bDayNextYear = dateTimeThisYear.replace(year=dateThisYear.year + 1, day=dateThisYear.day - 1) + + begin = int(mktime(bDayNextYear.timetuple())) + + end = begin - 1 + timerEntry = BirthdayTimerEntry(begin, end, preremind) + timerEntry.bDay = entry + self.addTimerEntry(timerEntry) + + def removeTimersForEntry(self, entry): + for timer in self.timer_list[:]: + if timer.bDay == entry: + if timer.preremind: + print("[Birthday Reminder] Removing preremind timer for %s" % entry[0]) + else: + print("[Birthday Reminder] Removing birthday timer for %s" % entry[0]) + self.timer_list.remove(timer) + + self.calcNextActivation() + + def removePreremindTimers(self): + print("[Birthday Reminder] Removing all preremind timers...") + for timer in self.timer_list[:]: + if timer.preremind: + self.timer_list.remove(timer) + + self.calcNextActivation() + + def addAllTimers(self): + print("[Birthday Reminder] Adding timers for all birthdays...") + bDayList = self.getBirthdayList() + for entry in bDayList: + self.addTimer(entry) + + # add a preremind timer also? + if config.plugins.birthdayreminder.preremind.getValue() != "-1": + self.addTimer(entry, preremind=True) + + def showReceivedMessage(self, numReceived, peer): + text = _("Birthday Reminder received %s birthdays from %s.") % (numReceived, peer) + Notifications.AddNotification(MessageBox, text, type=MessageBox.TYPE_INFO) + + def cbPreremindChanged(self, configElement=None): + if config.plugins.birthdayreminder.preremind.value == "-1": # remove all preremind timers + self.removePreremindTimers() + else: # we need to add or change timers + if config.plugins.birthdayreminder.preremindChanged.value: # there are no preremind timers, add new timers + print("[Birthday Reminder] Adding new preremind timers...") + for timer in self.timer_list[:]: + self.addTimer(timer.bDay, preremind=True) + else: # change existing preremind timers + print("[Birthday Reminder] Changing date of preremind timers...") + self.removePreremindTimers() + + for timer in self.timer_list[:]: + self.addTimer(timer.bDay, preremind=True) + + def cbNotificationTimeChanged(self, configElement=None): + print("[Birthday Reminder] Changing timer times...") + + timeList = config.plugins.birthdayreminder.notificationTime.value + notifyTime = dt_time(timeList[0], timeList[1]) + + for timer in self.timer_list: + day = date.fromtimestamp(timer.begin) + newDateTime = datetime.combine(day, notifyTime) + timer.begin = int(mktime(newDateTime.timetuple())) + timer.end = timer.begin - 1 + + self.calcNextActivation() diff --git a/birthdayreminder/src/LICENSE b/birthdayreminder/src/LICENSE new file mode 100644 index 000000000..8038f9570 --- /dev/null +++ b/birthdayreminder/src/LICENSE @@ -0,0 +1,14 @@ +All Files of this Software are licensed under the Creative Commons +Attribution-NonCommercial-ShareAlike 3.0 Unported +License if not stated otherwise in a Files Head. To view a copy of this license, visit +http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative +Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. + +Additionally, this plugin may only be distributed and executed on hardware which +is licensed by Dream Multimedia GmbH. + +This plugin is NOT free software. It is open source, you are allowed to +modify it (if you keep the license), but it may not be commercially +distributed other than under the conditions noted above. +This applies to the source code as a whole as well as to parts of it, unless +explicitely stated otherwise. diff --git a/birthdayreminder/src/Makefile.am b/birthdayreminder/src/Makefile.am new file mode 100644 index 000000000..222c7486f --- /dev/null +++ b/birthdayreminder/src/Makefile.am @@ -0,0 +1,6 @@ +installdir = $(libdir)/enigma2/python/Plugins/Extensions/BirthdayReminder + +install_PYTHON = *.py + +install_DATA = maintainer.info LICENSE plugin.png setup.xml + diff --git a/birthdayreminder/src/__init__.py b/birthdayreminder/src/__init__.py new file mode 100644 index 000000000..f4a5cd707 --- /dev/null +++ b/birthdayreminder/src/__init__.py @@ -0,0 +1,22 @@ +from Components.Language import language +from Tools.Directories import resolveFilename, SCOPE_PLUGINS +import gettext + +PluginLanguageDomain = "BirthdayReminder" +PluginLanguagePath = "Extensions/BirthdayReminder/locale" + + +def localeInit(): + gettext.bindtextdomain(PluginLanguageDomain, resolveFilename(SCOPE_PLUGINS, PluginLanguagePath)) + + +def _(txt): + if gettext.dgettext(PluginLanguageDomain, txt): + return gettext.dgettext(PluginLanguageDomain, txt) + else: + print("[%s] fallback to default translation for %s" % (PluginLanguageDomain, txt)) + return gettext.gettext(txt) + + +localeInit() +language.addCallback(localeInit) diff --git a/birthdayreminder/src/maintainer.info b/birthdayreminder/src/maintainer.info new file mode 100644 index 000000000..4ecc4cf8b --- /dev/null +++ b/birthdayreminder/src/maintainer.info @@ -0,0 +1,2 @@ +shaderman@dreambox-tools.info +BirthdayReminder diff --git a/birthdayreminder/src/plugin.png b/birthdayreminder/src/plugin.png new file mode 100644 index 000000000..9ea49ff69 Binary files /dev/null and b/birthdayreminder/src/plugin.png differ diff --git a/birthdayreminder/src/plugin.py b/birthdayreminder/src/plugin.py new file mode 100644 index 000000000..b0f39e779 --- /dev/null +++ b/birthdayreminder/src/plugin.py @@ -0,0 +1,78 @@ +# +# Birthday Reminder E2 Plugin +# +# $Id: plugin.py,v 1.0 2011-08-29 00:00:00 Shaderman Exp $ +# +# Coded by Shaderman (c) 2011 +# plugin.png by Sakartvelo with images from BazaarDesigns.com +# Support: www.dreambox-tools.info +# +# This plugin is licensed under the Creative Commons +# Attribution-NonCommercial-ShareAlike 3.0 Unported +# License. To view a copy of this license, visit +# http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative +# Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. +# +# Alternatively, this plugin may be distributed and executed on hardware which +# is licensed by Dream Multimedia GmbH. + +# This plugin is NOT free software. It is open source, you are allowed to +# modify it (if you keep the license), but it may not be commercially +# distributed other than under the conditions noted above. +# + +# Python 3 port and cleanup by jbleyel (c) 2022 + +# OWN IMPORTS +from .BirthdayReminder import BirthdayReminder, BirthdayReminderSettings +from .BirthdayTimer import BirthdayTimer + +# ENIGMA IMPORTS +from Components.config import config, ConfigSubsection, ConfigText, ConfigSelection, ConfigYesNo, NoSave, ConfigClock, ConfigInteger +from Plugins.Plugin import PluginDescriptor + +# for localized messages +from . import _ + + +config.plugins.birthdayreminder = ConfigSubsection() +config.plugins.birthdayreminder.file = ConfigText(default="/etc/enigma2/birthdayreminder") +config.plugins.birthdayreminder.dateFormat = ConfigSelection(default="ddmmyyyy", choices=[("ddmmyyyy", "DD.MM.YYYY"), ("mmddyyyy", "MM/DD/YYYY")]) +config.plugins.birthdayreminder.broadcasts = ConfigYesNo(default=True) +config.plugins.birthdayreminder.preremind = ConfigSelection(default="7", choices=[("-1", _("Disabled")), ("1", _("1 day")), ("3", _("3 days")), ("7", _("1 week"))]) +config.plugins.birthdayreminder.preremindChanged = NoSave(ConfigYesNo(default=False)) +config.plugins.birthdayreminder.notificationTime = ConfigClock(default=64800) # 19:00 +config.plugins.birthdayreminder.notificationTimeChanged = NoSave(ConfigYesNo(default=False)) +config.plugins.birthdayreminder.sortby = ConfigSelection(default="1", choices=[ + ("1", _("Name")), + ("2", _("Next birthday")), + ("3", _("Age")) + ]) +config.plugins.birthdayreminder.showInExtensions = ConfigYesNo(default=False) +config.plugins.birthdayreminder.broadcastPort = ConfigInteger(default=7374, limits=(1024, 49151)) + + +birthdaytimer = BirthdayTimer() + + +def settings(session, **kwargs): + session.open(BirthdayReminderSettings, birthdaytimer) + + +def autostart(reason, **kwargs): + if reason == 1: + birthdaytimer.stop() + + +def main(session, **kwargs): + session.open(BirthdayReminder, birthdaytimer) + + +def Plugins(**kwargs): + pluginList = [ + PluginDescriptor(where=[PluginDescriptor.WHERE_AUTOSTART, PluginDescriptor.WHERE_SESSIONSTART], fnc=autostart), + PluginDescriptor(name="Birthday Reminder", description=_("Helps to remind of birthdays"), where=PluginDescriptor.WHERE_PLUGINMENU, icon="plugin.png", fnc=settings) + ] + if config.plugins.birthdayreminder.showInExtensions.value: + pluginList.append(PluginDescriptor(name="Birthday Reminder", description=_("Helps to remind of birthdays"), where=[PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_EVENTINFO], fnc=main)) + return pluginList diff --git a/birthdayreminder/src/setup.xml b/birthdayreminder/src/setup.xml new file mode 100644 index 000000000..7741ea934 --- /dev/null +++ b/birthdayreminder/src/setup.xml @@ -0,0 +1,23 @@ + + + self.path + self.filename + config.plugins.birthdayreminder.dateFormat + config.plugins.birthdayreminder.preremind + config.plugins.birthdayreminder.notificationTime + config.plugins.birthdayreminder.sortby + config.plugins.birthdayreminder.showInExtensions + config.plugins.birthdayreminder.broadcastPort + + + config.plugins.birthdayreminder.name + + config.plugins.birthdayreminder.month + config.plugins.birthdayreminder.day + + config.plugins.birthdayreminder.day + config.plugins.birthdayreminder.month + + config.plugins.birthdayreminder.year + + \ No newline at end of file diff --git a/configure.ac b/configure.ac index e019859bc..a54be40b9 100644 --- a/configure.ac +++ b/configure.ac @@ -87,6 +87,11 @@ babelzapper/etc/Makefile babelzapper/meta/Makefile babelzapper/src/Makefile +birthdayreminder/Makefile +birthdayreminder/meta/Makefile +birthdayreminder/po/Makefile +birthdayreminder/src/Makefile + blindscan/src/Makefile blindscan/po/Makefile blindscan/Makefile