Updated kodi settings on Lenovo
BIN
Kodi/Lenovo/addons/script.metadata.editor/resources/fanart.jpg
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
Kodi/Lenovo/addons/script.metadata.editor/resources/icon.png
Normal file
|
After Width: | Height: | Size: 210 KiB |
@@ -0,0 +1,328 @@
|
||||
# Metadata Editor language file
|
||||
# Addon Name: Metadata Editor
|
||||
# Addon id: script.metadata.editor
|
||||
# Addon Provider: sualfred
|
||||
# Translators:
|
||||
# sualfred <su4lfred@gmail.com>, 2020
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Metadata Editor\n"
|
||||
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"PO-Revision-Date: 2019-11-07 08:05+0000\n"
|
||||
"Last-Translator: sualfred <su4lfred@gmail.com>, 2020\n"
|
||||
"Language-Team: German (Germany) (https://www.transifex.com/sualfred/teams/80018/de_DE/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: de_DE\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32000"
|
||||
msgid "Metadata Editor"
|
||||
msgstr "Metadata Editor"
|
||||
|
||||
#: /resources/lib/dialog.py
|
||||
msgctxt "#32001"
|
||||
msgid "User rating"
|
||||
msgstr "Eigene Bewertung"
|
||||
|
||||
#: /resources/lib/dialog_videogenres.py
|
||||
msgctxt "#32002"
|
||||
msgid "Available entries"
|
||||
msgstr "Verfügbare Einträge"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32003"
|
||||
msgid "Add/remove available tags"
|
||||
msgstr "Verfügbare Tags hinzufügen/entfernen"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32004"
|
||||
msgid "Add/remove available genres"
|
||||
msgstr "Verfügbare Genre hinzufügen/entfernen"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32005"
|
||||
msgid "Add new item"
|
||||
msgstr "Neuen Eintrag hinzufügen"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32006"
|
||||
msgid "Edit current list as string"
|
||||
msgstr "Bearbeite aktuelle Liste als String"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32007"
|
||||
msgid "Select from available items"
|
||||
msgstr "Aus verfügbaren Elementen wählen"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32008"
|
||||
msgid "Remove watchlist tag"
|
||||
msgstr "Entferne Watchlist Tag"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32009"
|
||||
msgid "Add watchlist tag"
|
||||
msgstr "Setze Watchlist Tag"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32010"
|
||||
msgid "Open editor"
|
||||
msgstr "Öffne Editor"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32011"
|
||||
msgid "Enter floating number"
|
||||
msgstr "Gebe Kommazahl ein"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32012"
|
||||
msgid "Select source"
|
||||
msgstr "Wähle Quelle"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32013"
|
||||
msgid "Available sources"
|
||||
msgstr "Verfügbare Quellen"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32014"
|
||||
msgid "Default source"
|
||||
msgstr "Standard-Quelle"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32015"
|
||||
msgid "Select default source"
|
||||
msgstr "Wähle Standard-Quelle"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32016"
|
||||
msgid "Edit ratings and votes"
|
||||
msgstr "Bearbeite Bewertungen und Abstimmungen"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32017"
|
||||
msgid "Add source"
|
||||
msgstr "Füge Quelle hinzu"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32018"
|
||||
msgid "Only values between 1.0 and 10.0 are allowed."
|
||||
msgstr "Nur Werte zwischen 1.0 und 10.0 sind erlaubt."
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32019"
|
||||
msgid "Attention"
|
||||
msgstr "Achtung"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32020"
|
||||
msgid "Set as default?"
|
||||
msgstr "Als Standard setzen?"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32021"
|
||||
msgid "Enable .nfo updating for movies, TV shows and music videos"
|
||||
msgstr "Aktiviere .nfo Aktualisierung für Filme, Serien und Musikvideos"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32022"
|
||||
msgid "value unkown (missing Kodi feature)"
|
||||
msgstr "Wert unbekannt (Kodi Feature fehlt)"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32023"
|
||||
msgid "Record label"
|
||||
msgstr "Record Label"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32025"
|
||||
msgid "Preferred language"
|
||||
msgstr "Bevorzugte Sprachregion"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32026"
|
||||
msgid "Scraper settings"
|
||||
msgstr "Scraper Einstellungen"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32024"
|
||||
msgid "Heavy server load. Please wait."
|
||||
msgstr "Hohe Serverlast. Bitte warten."
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32027"
|
||||
msgid "TV show library is based on informations of"
|
||||
msgstr "Serien-Datenbank basiert auf Informationen von"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32029"
|
||||
msgid "Enable JSON logging"
|
||||
msgstr "Aktiviere JSON Logging"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32030"
|
||||
msgid "Rating updater"
|
||||
msgstr "Bewertungs-Updater"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32028"
|
||||
msgid "Run updating process in the background"
|
||||
msgstr "Führe die Aktualisierung im Hintergrund aus"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32031"
|
||||
msgid "Your personal OMDb API key (www.omdbapi.com)"
|
||||
msgstr "Dein persönlicher OMDb API Schlüssel (www.omdbapi.com)"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32032"
|
||||
msgid "Search by title/year if IMDb ID is missing (not recommended)"
|
||||
msgstr "Suche anhand Titel/Jahr falls IMDb ID fehlt (nicht empfohlen)"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32035"
|
||||
msgid ""
|
||||
"No OMDb API key is configured, which is required to update IMDb, Rotten "
|
||||
"Tomatoes and Metacritic ratings. Please visit www.omdbapi.com and create "
|
||||
"your own API key.[CR][CR]Note: The free key is limited to 1000 calls a day. "
|
||||
"Please suggest to become a patreon of OMDb to increase the limit to "
|
||||
"100.000.[CR][CR]Do you want to proceed updating The Movie DB ratings? This "
|
||||
"only works if you have a TMDb ID stored."
|
||||
msgstr ""
|
||||
"Kein OMDb API Schlüssel ist konfiguriert, welcher benötigt wird um IMDb, "
|
||||
"Rotten Tomatoes und Metacritic Bewertungen zu aktualisieren. Bitte besuche "
|
||||
"www.omdbapi.com und erstelle einen eigenen API Schlüssel.[CR][CR]Hinweis: "
|
||||
"Der kostenfreie Schlüssel ist auf 1000 Anfragen pro Tag limitiert. Bitte "
|
||||
"ziehe in Betracht ein Patreon von OMDb zu werden, um das tägliche Limit auf "
|
||||
"100.000 zu erhöhen.[CR][CR]Willst du fortfahren und nur The Movie DB "
|
||||
"Bewertungen aktualisieren? Dies funktioniert nur, falls eine TMDb ID in der "
|
||||
"Datenbank vorhanden ist."
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32036"
|
||||
msgid "Update TV show ratings"
|
||||
msgstr "Aktualisiere Serienbewertungen"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32033"
|
||||
msgid ""
|
||||
"OMDB API limit reached. Please consider to become a Patreon to increase your"
|
||||
" daily call limitation. Proceed by only using The Movie DB?"
|
||||
msgstr ""
|
||||
"OMDb API Limit erreicht. Bitte erwäge ein Patreon zu werden um das tägliche "
|
||||
"Limit zu erhöhen. Nur mit TMDb fortfahren?"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32034"
|
||||
msgid "Create .nfo file if missing"
|
||||
msgstr "Erstelle .nfo Datei, falls diese fehlt"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32037"
|
||||
msgid "Update movie ratings"
|
||||
msgstr "Aktualisiere Filmbewertungen"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32038"
|
||||
msgid "Update all ratings"
|
||||
msgstr "Aktualisiere alle Bewertungen"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32039"
|
||||
msgid "Update ratings"
|
||||
msgstr "Aktualisiere Bewertungen"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32040"
|
||||
msgid "Edit data for"
|
||||
msgstr "Bearbeite Daten für"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32042"
|
||||
msgid "Canceled"
|
||||
msgstr "Abgebrochen"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32043"
|
||||
msgid "MPAA region"
|
||||
msgstr "MPAA Region"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32041"
|
||||
msgid "Update premiered/year if database value is different"
|
||||
msgstr "Aktualisiere Premiere/Jahr, falls Datenbankwert nicht korrekt ist"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32044"
|
||||
msgid "Skip updating of MPAA"
|
||||
msgstr "MPAA nicht aktualisieren"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32045"
|
||||
msgid "Update episode ratings"
|
||||
msgstr "Aktualisiere Episodenbewertungen"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32047"
|
||||
msgid "No default source defined"
|
||||
msgstr "Keine Standard-Quelle definiert"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32048"
|
||||
msgid "No items found"
|
||||
msgstr "Keine Einträge gefunden"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32046"
|
||||
msgid "Update .nfo"
|
||||
msgstr "Aktualisiere .nfo"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32049"
|
||||
msgid "Incomplete arguments or content type not supported"
|
||||
msgstr "Unvollständiger Aufruf oder Inhaltstyp werden nicht unterstützt"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32050"
|
||||
msgid "Do you want to cancel the update?"
|
||||
msgstr "Update abbrechen?"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32051"
|
||||
msgid "Content"
|
||||
msgstr "Inhalt"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32052"
|
||||
msgid "Fallback to US MPAA if configured country has no certification stored"
|
||||
msgstr ""
|
||||
"Nutze US MPAA als Fallback, falls keine Zertifizierung der konfigurierten "
|
||||
"Region gefunden wird"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32053"
|
||||
msgid "Don't store \"NR\" (Not rated) MPAA rating"
|
||||
msgstr "\"NR\" (nicht bewertet) MPAA-Bewertung nicht speichern"
|
||||
|
||||
#: /service.py
|
||||
msgctxt "#32054"
|
||||
msgid "Do you want to rate the following item?"
|
||||
msgstr "Möchtest du das folgende Video bewerten?"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32055"
|
||||
msgid "Automatically update changed watched states to .nfo"
|
||||
msgstr "Geänderten Watched Status automatisch in .nfo aktualisieren"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32056"
|
||||
msgid "Rate your media if playback has ended"
|
||||
msgstr "Bewerte Medien nach vollständiger Wiedergabe"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32057"
|
||||
msgid "Write watched flag and playcount to .nfo"
|
||||
msgstr "Schreibe Watched Status und Abspielzähler in .nfo"
|
||||
@@ -0,0 +1,305 @@
|
||||
# Metadata Editor language file
|
||||
# Addon Name: Metadata Editor
|
||||
# Addon id: script.metadata.editor
|
||||
# Addon Provider: sualfred
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Metadata Editor\n"
|
||||
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: en_GB\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32000"
|
||||
msgid "Metadata Editor"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/dialog.py
|
||||
msgctxt "#32001"
|
||||
msgid "User rating"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/dialog_videogenres.py
|
||||
msgctxt "#32002"
|
||||
msgid "Available entries"
|
||||
msgstr ""
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32003"
|
||||
msgid "Add/remove available tags"
|
||||
msgstr ""
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32004"
|
||||
msgid "Add/remove available genres"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32005"
|
||||
msgid "Add new item"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32006"
|
||||
msgid "Edit current list as string"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32007"
|
||||
msgid "Select from available items"
|
||||
msgstr ""
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32008"
|
||||
msgid "Remove watchlist tag"
|
||||
msgstr ""
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32009"
|
||||
msgid "Add watchlist tag"
|
||||
msgstr ""
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32010"
|
||||
msgid "Open editor"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32011"
|
||||
msgid "Enter floating number"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32012"
|
||||
msgid "Select source"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32013"
|
||||
msgid "Available sources"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32014"
|
||||
msgid "Default source"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32015"
|
||||
msgid "Select default source"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32016"
|
||||
msgid "Edit ratings and votes"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32017"
|
||||
msgid "Add source"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32018"
|
||||
msgid "Only values between 1.0 and 10.0 are allowed."
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32019"
|
||||
msgid "Attention"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32020"
|
||||
msgid "Set as default?"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32021"
|
||||
msgid "Enable .nfo updating for movies, TV shows and music videos"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32022"
|
||||
msgid "value unkown (missing Kodi feature)"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32023"
|
||||
msgid "Record label"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32025"
|
||||
msgid "Preferred language"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32026"
|
||||
msgid "Scraper settings"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32024"
|
||||
msgid "Heavy server load. Please wait."
|
||||
msgstr ""
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32027"
|
||||
msgid "TV show library is based on informations of"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32029"
|
||||
msgid "Enable JSON logging"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32030"
|
||||
msgid "Rating updater"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32028"
|
||||
msgid "Run updating process in the background"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32031"
|
||||
msgid "Your personal OMDb API key (www.omdbapi.com)"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32032"
|
||||
msgid "Search by title/year if IMDb ID is missing (not recommended)"
|
||||
msgstr ""
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32035"
|
||||
msgid "No OMDb API key is configured, which is required to update IMDb, Rotten Tomatoes and Metacritic ratings. Please visit www.omdbapi.com and create your own API key.[CR][CR]Note: The free key is limited to 1000 calls a day. Please suggest to become a patreon of OMDb to increase the limit to 100.000.[CR][CR]Do you want to proceed updating The Movie DB ratings? This only works if you have a TMDb ID stored."
|
||||
msgstr ""
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32036"
|
||||
msgid "Update TV show ratings"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32033"
|
||||
msgid "OMDB API limit reached. Please consider to become a Patreon to increase your daily call limitation. Proceed by only using The Movie DB?"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32034"
|
||||
msgid "Create .nfo file if missing"
|
||||
msgstr ""
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32037"
|
||||
msgid "Update movie ratings"
|
||||
msgstr ""
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32038"
|
||||
msgid "Update all ratings"
|
||||
msgstr ""
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32039"
|
||||
msgid "Update ratings"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32040"
|
||||
msgid "Edit data for"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32042"
|
||||
msgid "Canceled"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32043"
|
||||
msgid "MPAA region"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32041"
|
||||
msgid "Update premiered/year if database value is different"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32044"
|
||||
msgid "Skip updating of MPAA"
|
||||
msgstr ""
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32045"
|
||||
msgid "Update episode ratings"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32047"
|
||||
msgid "No default source defined"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32048"
|
||||
msgid "No items found"
|
||||
msgstr ""
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32046"
|
||||
msgid "Update .nfo"
|
||||
msgstr ""
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32049"
|
||||
msgid "Incomplete arguments or content type not supported"
|
||||
msgstr ""
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32050"
|
||||
msgid "Do you want to cancel the update?"
|
||||
msgstr ""
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32051"
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32052"
|
||||
msgid "Fallback to US MPAA if configured country has no certification stored"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32053"
|
||||
msgid "Don't store \"NR\" (Not rated) MPAA rating"
|
||||
msgstr ""
|
||||
|
||||
#: /service.py
|
||||
msgctxt "#32054"
|
||||
msgid "Do you want to rate the following item?"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32055"
|
||||
msgid "Automatically update changed watched states to .nfo"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32056"
|
||||
msgid "Rate your media if playback has ended"
|
||||
msgstr ""
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32057"
|
||||
msgid "Write watched flag and playcount to .nfo"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,331 @@
|
||||
# Metadata Editor language file
|
||||
# Addon Name: Metadata Editor
|
||||
# Addon id: script.metadata.editor
|
||||
# Addon Provider: sualfred
|
||||
# Translators:
|
||||
# Bartolome Soriano <bsoriano@gmail.com>, 2019
|
||||
# Rafa Oliveros <roliverosc@gmail.com>, 2020
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Metadata Editor\n"
|
||||
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"PO-Revision-Date: 2019-11-07 08:05+0000\n"
|
||||
"Last-Translator: Rafa Oliveros <roliverosc@gmail.com>, 2020\n"
|
||||
"Language-Team: Spanish (Spain) (https://www.transifex.com/sualfred/teams/80018/es_ES/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: es_ES\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32000"
|
||||
msgid "Metadata Editor"
|
||||
msgstr "Editor de Metadatos"
|
||||
|
||||
#: /resources/lib/dialog.py
|
||||
msgctxt "#32001"
|
||||
msgid "User rating"
|
||||
msgstr "Valoración de usuario"
|
||||
|
||||
#: /resources/lib/dialog_videogenres.py
|
||||
msgctxt "#32002"
|
||||
msgid "Available entries"
|
||||
msgstr "Entradas disponibles"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32003"
|
||||
msgid "Add/remove available tags"
|
||||
msgstr "Añadir/Eliminar etiquetas disponibles"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32004"
|
||||
msgid "Add/remove available genres"
|
||||
msgstr "Añadir/Eliminar géneros disponibles"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32005"
|
||||
msgid "Add new item"
|
||||
msgstr "Añadir nuevo elemento"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32006"
|
||||
msgid "Edit current list as string"
|
||||
msgstr "Editar lista actual como cadena"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32007"
|
||||
msgid "Select from available items"
|
||||
msgstr "Seleccionar de elementos disponibles"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32008"
|
||||
msgid "Remove watchlist tag"
|
||||
msgstr "Eliminar de lista de seguimiento"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32009"
|
||||
msgid "Add watchlist tag"
|
||||
msgstr "Añadir a lista de seguimiento"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32010"
|
||||
msgid "Open editor"
|
||||
msgstr "Abrir editor"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32011"
|
||||
msgid "Enter floating number"
|
||||
msgstr "Introduzca número de coma flotante"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32012"
|
||||
msgid "Select source"
|
||||
msgstr "Seleccionar fuente"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32013"
|
||||
msgid "Available sources"
|
||||
msgstr "Fuentes disponibles"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32014"
|
||||
msgid "Default source"
|
||||
msgstr "Fuente predeterminada"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32015"
|
||||
msgid "Select default source"
|
||||
msgstr "Seleccionar fuente predeterminada"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32016"
|
||||
msgid "Edit ratings and votes"
|
||||
msgstr "Editar valoración y votos"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32017"
|
||||
msgid "Add source"
|
||||
msgstr "Añadir fuente"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32018"
|
||||
msgid "Only values between 1.0 and 10.0 are allowed."
|
||||
msgstr "Solo se permiten valores entre 1.0 y 10.0."
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32019"
|
||||
msgid "Attention"
|
||||
msgstr "Atención"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32020"
|
||||
msgid "Set as default?"
|
||||
msgstr "¿Establecer como predeterminado?"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32021"
|
||||
msgid "Enable .nfo updating for movies, TV shows and music videos"
|
||||
msgstr "Activar actualización de .nfo para películas, series TV y videoclips"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32022"
|
||||
msgid "value unkown (missing Kodi feature)"
|
||||
msgstr "valor desconocido (falta la función de Kodi)"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32023"
|
||||
msgid "Record label"
|
||||
msgstr "Estudio de grabación"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32025"
|
||||
msgid "Preferred language"
|
||||
msgstr "Idioma preferido"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32026"
|
||||
msgid "Scraper settings"
|
||||
msgstr "Ajustes scraper"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32024"
|
||||
msgid "Heavy server load. Please wait."
|
||||
msgstr "Carga de servidor intensa. Por favor espere."
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32027"
|
||||
msgid "TV show library is based on informations of"
|
||||
msgstr "La biblioteca de serie TV se basa en información de"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32029"
|
||||
msgid "Enable JSON logging"
|
||||
msgstr "Activar registro JSON"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32030"
|
||||
msgid "Rating updater"
|
||||
msgstr "Actualizador de valoraciones"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32028"
|
||||
msgid "Run updating process in the background"
|
||||
msgstr "Ejecutar el proceso de actualización en segundo plano"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32031"
|
||||
msgid "Your personal OMDb API key (www.omdbapi.com)"
|
||||
msgstr "Su clave API personal en OMDb (www.omdbapi.com)"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32032"
|
||||
msgid "Search by title/year if IMDb ID is missing (not recommended)"
|
||||
msgstr "Buscar por título/año si falta la ID IMDb (no recomendado)"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32035"
|
||||
msgid ""
|
||||
"No OMDb API key is configured, which is required to update IMDb, Rotten "
|
||||
"Tomatoes and Metacritic ratings. Please visit www.omdbapi.com and create "
|
||||
"your own API key.[CR][CR]Note: The free key is limited to 1000 calls a day. "
|
||||
"Please suggest to become a patreon of OMDb to increase the limit to "
|
||||
"100.000.[CR][CR]Do you want to proceed updating The Movie DB ratings? This "
|
||||
"only works if you have a TMDb ID stored."
|
||||
msgstr ""
|
||||
"No ha configurado la clave API de OMDb, esta es requerida para actualizar "
|
||||
"valoraciones desde IMDb, Rotten Tomatoes y Metacritic. Por favor visite "
|
||||
"www.omdbapi.com y cree su propia clave API.[CR][CR]Nota: La clave API "
|
||||
"gratuita está limitada a 1000 solicitudes diarias. Considere convertirse en "
|
||||
"donante de OMDb para aumentar este límite a 100.000.[CR][CR]¿Quiere proceder"
|
||||
" a actualizar las valoraciones desde The Movie DB? Esto solo funcionara si "
|
||||
"tiene una ID de TMDb almacenada."
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32036"
|
||||
msgid "Update TV show ratings"
|
||||
msgstr "Actualizar valoraciones de Series TV"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32033"
|
||||
msgid ""
|
||||
"OMDB API limit reached. Please consider to become a Patreon to increase your"
|
||||
" daily call limitation. Proceed by only using The Movie DB?"
|
||||
msgstr ""
|
||||
"Limite de API OMDB alcanzado. Por favor, considere convertirse en donante "
|
||||
"para aumentar su limite de solicitudes diarias. ¿Proceder usando solo The "
|
||||
"Movie DB?"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32034"
|
||||
msgid "Create .nfo file if missing"
|
||||
msgstr "Crear archivo .nfo si está pendiente"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32037"
|
||||
msgid "Update movie ratings"
|
||||
msgstr "Actualizar valoraciones de películas"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32038"
|
||||
msgid "Update all ratings"
|
||||
msgstr "Actualizar todas las valoraciones"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32039"
|
||||
msgid "Update ratings"
|
||||
msgstr "Actualizar valoraciones"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32040"
|
||||
msgid "Edit data for"
|
||||
msgstr "Editar datos para"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32042"
|
||||
msgid "Canceled"
|
||||
msgstr "Cancelado"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32043"
|
||||
msgid "MPAA region"
|
||||
msgstr "Región MPAA"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32041"
|
||||
msgid "Update premiered/year if database value is different"
|
||||
msgstr ""
|
||||
"Actualizar premiered/año si los valores de la base de datos son diferentes."
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32044"
|
||||
msgid "Skip updating of MPAA"
|
||||
msgstr "Omitir actualización de MPAA"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32045"
|
||||
msgid "Update episode ratings"
|
||||
msgstr "Actualizar valoraciones de episodios"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32047"
|
||||
msgid "No default source defined"
|
||||
msgstr "No hay una fuente predeterminada definida"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32048"
|
||||
msgid "No items found"
|
||||
msgstr "No se encontraron elementos"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32046"
|
||||
msgid "Update .nfo"
|
||||
msgstr "Actualizar .nfo"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32049"
|
||||
msgid "Incomplete arguments or content type not supported"
|
||||
msgstr "Argumentos incompletos o tipo de contenido no soportado"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32050"
|
||||
msgid "Do you want to cancel the update?"
|
||||
msgstr "¿Desea cancelar la actualización?"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32051"
|
||||
msgid "Content"
|
||||
msgstr "Contenido"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32052"
|
||||
msgid "Fallback to US MPAA if configured country has no certification stored"
|
||||
msgstr ""
|
||||
"Recurrir a MPAA de EE. UU. Si el país configurado no tiene ninguna "
|
||||
"certificación almacenada"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32053"
|
||||
msgid "Don't store \"NR\" (Not rated) MPAA rating"
|
||||
msgstr "No almacenar \"NR\" (Not rated) valoración MPAA"
|
||||
|
||||
#: /service.py
|
||||
msgctxt "#32054"
|
||||
msgid "Do you want to rate the following item?"
|
||||
msgstr "¿Quiere valorar el siguiente elemento?"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32055"
|
||||
msgid "Automatically update changed watched states to .nfo"
|
||||
msgstr "Actualizar automáticamente los estados de vistos modificados a .nfo"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32056"
|
||||
msgid "Rate your media if playback has ended"
|
||||
msgstr "Calificar sus medios si la reproducción ha finalizado"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32057"
|
||||
msgid "Write watched flag and playcount to .nfo"
|
||||
msgstr "Escribir etiqueta de visto y recuento de reproducciones en .nfo"
|
||||
@@ -0,0 +1,274 @@
|
||||
# Metadata Editor language file
|
||||
# Addon Name: Metadata Editor
|
||||
# Addon id: script.metadata.editor
|
||||
# Addon Provider: sualfred
|
||||
# Translators:
|
||||
# Andrea Matesi <andreamatesi@gmail.com>, 2019
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Metadata Editor\n"
|
||||
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"PO-Revision-Date: 2019-11-07 08:05+0000\n"
|
||||
"Last-Translator: Andrea Matesi <andreamatesi@gmail.com>, 2019\n"
|
||||
"Language-Team: Italian (Italy) (https://www.transifex.com/sualfred/teams/80018/it_IT/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: it_IT\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32000"
|
||||
msgid "Metadata Editor"
|
||||
msgstr "Editor Metadati"
|
||||
|
||||
#: /resources/lib/dialog.py
|
||||
msgctxt "#32001"
|
||||
msgid "User rating"
|
||||
msgstr "Valutazione utente"
|
||||
|
||||
#: /resources/lib/dialog_videogenres.py
|
||||
msgctxt "#32002"
|
||||
msgid "Available entries"
|
||||
msgstr "Voci disponibili"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32003"
|
||||
msgid "Add/remove available tags"
|
||||
msgstr "Aggiungi/rimuovi tag disponibili"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32004"
|
||||
msgid "Add/remove available genres"
|
||||
msgstr "Aggiungi/rimuovi generi disponibili"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32005"
|
||||
msgid "Add new item"
|
||||
msgstr "Aggiungi nuovo oggetto"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32006"
|
||||
msgid "Edit current list as string"
|
||||
msgstr "Modifica lista attuale come stringa"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32007"
|
||||
msgid "Select from available items"
|
||||
msgstr "Seleziona dagli oggetti disponibili"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32008"
|
||||
msgid "Remove watchlist tag"
|
||||
msgstr "Rimuovi tag da vedere"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32009"
|
||||
msgid "Add watchlist tag"
|
||||
msgstr "Aggiungi tag da vedere"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32010"
|
||||
msgid "Open editor"
|
||||
msgstr "Apri editor"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32011"
|
||||
msgid "Enter floating number"
|
||||
msgstr "Inserisci numero decimale"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32012"
|
||||
msgid "Select source"
|
||||
msgstr "Seleziona sorgente"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32013"
|
||||
msgid "Available sources"
|
||||
msgstr "Sorgenti disponibili"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32014"
|
||||
msgid "Default source"
|
||||
msgstr "Sorgente predefinita"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32015"
|
||||
msgid "Select default source"
|
||||
msgstr "Seleziona sorgente predefinita"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32016"
|
||||
msgid "Edit ratings and votes"
|
||||
msgstr "Modifica voti e valutazioni"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32017"
|
||||
msgid "Add source"
|
||||
msgstr "Aggiungi sorgente"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32018"
|
||||
msgid "Only values between 1.0 and 10.0 are allowed."
|
||||
msgstr "Solo i valori compresi tra 1.0 e 10.0 sono consentiti"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32019"
|
||||
msgid "Attention"
|
||||
msgstr "Attenzione"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32020"
|
||||
msgid "Set as default?"
|
||||
msgstr "Imposta come predefinito?"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32021"
|
||||
msgid "Enable .nfo updating for movies, TV shows and music videos"
|
||||
msgstr "Attiva aggiornamento .nfo per film, serie TV e video musicali"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32022"
|
||||
msgid "value unkown (missing Kodi feature)"
|
||||
msgstr "valore sconosciuto (funzionalità Kodi mancante)"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32023"
|
||||
msgid "Record label"
|
||||
msgstr "Casa discografica"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32024"
|
||||
msgid "Please use the context menu on a library item to run this script."
|
||||
msgstr ""
|
||||
"Si prega di usare il menu contestuale su un oggetto libreria per eseguire "
|
||||
"questo script"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32025"
|
||||
msgid "Preferred TMDb language"
|
||||
msgstr "Lingua TMDb preferita"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32026"
|
||||
msgid "TV show scraper related settings"
|
||||
msgstr "Impostazioni relative a scraper Serie TV "
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32027"
|
||||
msgid "Library is based on informations of"
|
||||
msgstr "Libreria basata su informazioni relative a "
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32029"
|
||||
msgid "Enable JSON logging"
|
||||
msgstr "Attiva logging JSON"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32030"
|
||||
msgid "Rating updater"
|
||||
msgstr "Updater valutazioni"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32028"
|
||||
msgid "Run updating process in the background"
|
||||
msgstr "Esegui processo di aggiornamento nel sottofondo"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32031"
|
||||
msgid "Your personal OMDb API key (www.omdbapi.com)"
|
||||
msgstr "Chiave personale OMDb API (www.obdbapi.com)"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32032"
|
||||
msgid "Search OMDb with title/year if IMDb is missing"
|
||||
msgstr "Ricerca OMDB in base al titolo/anno se IMDb non esiste"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32033"
|
||||
msgid "Updating movie ratings"
|
||||
msgstr "Aggiornamento valutazioni film"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32034"
|
||||
msgid "Updating TV show ratings"
|
||||
msgstr "Aggiornamento valutazioni Serie TV"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32035"
|
||||
msgid ""
|
||||
"No OMDb API key is configured, which is required to update IMDb, Rotten "
|
||||
"Tomatoes and Metacritic ratings. Please visit www.omdbapi.com and create "
|
||||
"your own API key.[CR][CR]Note: The free key is limited to 1000 calls a day. "
|
||||
"Please suggest to become a patreon of OMDb to increase the limit to "
|
||||
"100.000.[CR][CR]Do you want to proceed updating The Movie DB ratings? This "
|
||||
"only works if you have a TMDb ID stored."
|
||||
msgstr ""
|
||||
"Nessuna chiave OMDb API configurata, ciò è richiesto per aggiornare "
|
||||
"valutazioni IMDb, Rotten Tomatoes e Metacritic. Si prega di visitare "
|
||||
"www.omdbapi.com per generare la propria chiave API.[CR][CR]Nota: chiave "
|
||||
"gratuita limitata a 1000 aggiornamenti al giorno. Al fine di incrementare il"
|
||||
" limite a 100,000, si raccomanda diventare patreon di OMDB.[CR][CR] Desideri"
|
||||
" procedere con l'aggiornamento delle valutazioni The Movie DB? Funzione "
|
||||
"disponibile solo se hai un ID TMDb salvato."
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32036"
|
||||
msgid "Update TV show ratings"
|
||||
msgstr "Aggiorna valutazioni Serie TV"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32037"
|
||||
msgid "Update movie ratings"
|
||||
msgstr "Aggiorna valutazioni film"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32038"
|
||||
msgid "Update all ratings"
|
||||
msgstr "Aggiorna tutte le valutazioni"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32039"
|
||||
msgid "Update ratings"
|
||||
msgstr "Aggiorna valutazioni"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32040"
|
||||
msgid "Edit data for"
|
||||
msgstr "Modifica dati per"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32041"
|
||||
msgid "Cancel updating"
|
||||
msgstr "Annulla aggiornamento"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32042"
|
||||
msgid "Canceled"
|
||||
msgstr "Annullato"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32043"
|
||||
msgid "MPAA region"
|
||||
msgstr "Regione MPAA"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32044"
|
||||
msgid "Skip updating of MPAA"
|
||||
msgstr "Salta aggiornamento MPAA"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32045"
|
||||
msgid "Update episode ratings"
|
||||
msgstr "Aggiorna valutazione episodi"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32046"
|
||||
msgid "Updating episode ratings"
|
||||
msgstr "Aggiornamento valutazione episodi"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32047"
|
||||
msgid "No default source defined"
|
||||
msgstr "Nessuna sorgente definita"
|
||||
@@ -0,0 +1,328 @@
|
||||
# Metadata Editor language file
|
||||
# Addon Name: Metadata Editor
|
||||
# Addon id: script.metadata.editor
|
||||
# Addon Provider: sualfred
|
||||
# Translators:
|
||||
# David Claes <d3claes@gmail.com>, 2020
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Metadata Editor\n"
|
||||
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"PO-Revision-Date: 2019-11-07 08:05+0000\n"
|
||||
"Last-Translator: David Claes <d3claes@gmail.com>, 2020\n"
|
||||
"Language-Team: Dutch (Netherlands) (https://www.transifex.com/sualfred/teams/80018/nl_NL/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: nl_NL\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32000"
|
||||
msgid "Metadata Editor"
|
||||
msgstr "Metadata Editor"
|
||||
|
||||
#: /resources/lib/dialog.py
|
||||
msgctxt "#32001"
|
||||
msgid "User rating"
|
||||
msgstr "Gebruikersbeoordeling"
|
||||
|
||||
#: /resources/lib/dialog_videogenres.py
|
||||
msgctxt "#32002"
|
||||
msgid "Available entries"
|
||||
msgstr "Beschikbare vermeldingen"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32003"
|
||||
msgid "Add/remove available tags"
|
||||
msgstr "Beschikbare labels toevoegen/verwijderen"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32004"
|
||||
msgid "Add/remove available genres"
|
||||
msgstr "Beschikbare genres toevoegen/verwijderen"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32005"
|
||||
msgid "Add new item"
|
||||
msgstr "Nieuw item toevoegen"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32006"
|
||||
msgid "Edit current list as string"
|
||||
msgstr "Huidige lijst als string bewerken"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32007"
|
||||
msgid "Select from available items"
|
||||
msgstr "Kiezen uit beschikbare items"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32008"
|
||||
msgid "Remove watchlist tag"
|
||||
msgstr "Kijklijst label verwijderen"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32009"
|
||||
msgid "Add watchlist tag"
|
||||
msgstr "Kijklijst label toevoegen"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32010"
|
||||
msgid "Open editor"
|
||||
msgstr "Editor openen"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32011"
|
||||
msgid "Enter floating number"
|
||||
msgstr "Kommagetal invoeren"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32012"
|
||||
msgid "Select source"
|
||||
msgstr "Bron kiezen"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32013"
|
||||
msgid "Available sources"
|
||||
msgstr "Beschikbare bronnen"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32014"
|
||||
msgid "Default source"
|
||||
msgstr "Standaardbron"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32015"
|
||||
msgid "Select default source"
|
||||
msgstr "Standaardbron kiezen"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32016"
|
||||
msgid "Edit ratings and votes"
|
||||
msgstr "Beoordelingen en stemmen bewerken"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32017"
|
||||
msgid "Add source"
|
||||
msgstr "Bron toevoegen"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32018"
|
||||
msgid "Only values between 1.0 and 10.0 are allowed."
|
||||
msgstr "Enkel waarden tussen 1.0 en 10.0 zijn toegelaten."
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32019"
|
||||
msgid "Attention"
|
||||
msgstr "Opgelet"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32020"
|
||||
msgid "Set as default?"
|
||||
msgstr "Als standaard instellen?"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32021"
|
||||
msgid "Enable .nfo updating for movies, TV shows and music videos"
|
||||
msgstr ".nfo-updates voor films, tv-shows en muziekvideo's inschakelen"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32022"
|
||||
msgid "value unkown (missing Kodi feature)"
|
||||
msgstr "onbekende waarde (ontbrekende Kodi-functie)"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32023"
|
||||
msgid "Record label"
|
||||
msgstr "Opnamelabel"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32025"
|
||||
msgid "Preferred language"
|
||||
msgstr "Voorkeurstaal"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32026"
|
||||
msgid "Scraper settings"
|
||||
msgstr "Schraperinstellingen"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32024"
|
||||
msgid "Heavy server load. Please wait."
|
||||
msgstr "Zware serverbelasting. Even geduld a.u.b."
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32027"
|
||||
msgid "TV show library is based on informations of"
|
||||
msgstr "Bibliotheek TV-series is gebaseerd op informatie van"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32029"
|
||||
msgid "Enable JSON logging"
|
||||
msgstr "JSON-logboekregistratie inschakelen"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32030"
|
||||
msgid "Rating updater"
|
||||
msgstr "Beoordelingsupdater"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32028"
|
||||
msgid "Run updating process in the background"
|
||||
msgstr "Het updateproces op de achtergrond uitvoeren"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32031"
|
||||
msgid "Your personal OMDb API key (www.omdbapi.com)"
|
||||
msgstr "Uw persoonlijke OMDb API key (www.omdbapi.com)"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32032"
|
||||
msgid "Search by title/year if IMDb ID is missing (not recommended)"
|
||||
msgstr "Zoeken op titel/jaar als IMDb ID ontbreekt (niet aanbevolen)"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32035"
|
||||
msgid ""
|
||||
"No OMDb API key is configured, which is required to update IMDb, Rotten "
|
||||
"Tomatoes and Metacritic ratings. Please visit www.omdbapi.com and create "
|
||||
"your own API key.[CR][CR]Note: The free key is limited to 1000 calls a day. "
|
||||
"Please suggest to become a patreon of OMDb to increase the limit to "
|
||||
"100.000.[CR][CR]Do you want to proceed updating The Movie DB ratings? This "
|
||||
"only works if you have a TMDb ID stored."
|
||||
msgstr ""
|
||||
"Er is geen OMDb API-sleutel geconfigureerd, die nodig is om IMDb, Rotten "
|
||||
"Tomatoes en Metacritic-beoordelingen bij te werken. Ga naar www.omdbapi.com "
|
||||
"en maak uw eigen API-sleutel aan.[CR][CR]Opmerking: de gratis sleutel is "
|
||||
"beperkt tot 1000 oproepen per dag. Overweeg om een patreon van OMDb te "
|
||||
"worden om de limiet naar 100.000 te verhogen.[CR][CR] Wilt u doorgaan met "
|
||||
"het bijwerken van The Movie DB-beoordelingen? Dit werkt alleen als u een "
|
||||
"TMDb-ID hebt opgeslagen."
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32036"
|
||||
msgid "Update TV show ratings"
|
||||
msgstr "Beoordelingen van TV-series bijwerken"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32033"
|
||||
msgid ""
|
||||
"OMDB API limit reached. Please consider to become a Patreon to increase your"
|
||||
" daily call limitation. Proceed by only using The Movie DB?"
|
||||
msgstr ""
|
||||
"OMDB API-limiet bereikt. Overweeg a.u.b. om een Patreon te worden om uw "
|
||||
"dagelijkse aanroepbeperking te verhogen. Enkel verdergaan met The Movie DB?"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32034"
|
||||
msgid "Create .nfo file if missing"
|
||||
msgstr ".nfo bestand aanmaken als het ontbreekt"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32037"
|
||||
msgid "Update movie ratings"
|
||||
msgstr "Beoordelingen van films bijwerken"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32038"
|
||||
msgid "Update all ratings"
|
||||
msgstr "Alle beoordelingen bijwerken"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32039"
|
||||
msgid "Update ratings"
|
||||
msgstr "Beoordelingen bijwerken"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32040"
|
||||
msgid "Edit data for"
|
||||
msgstr "Data bewerken voor"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32042"
|
||||
msgid "Canceled"
|
||||
msgstr "Geannuleerd"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32043"
|
||||
msgid "MPAA region"
|
||||
msgstr "MPAA regio"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32041"
|
||||
msgid "Update premiered/year if database value is different"
|
||||
msgstr "Première/jaar bijwerken als de databasewaarde anders is"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32044"
|
||||
msgid "Skip updating of MPAA"
|
||||
msgstr "Bijwerken van MPAA overslaan"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32045"
|
||||
msgid "Update episode ratings"
|
||||
msgstr "Beoordelingen van afleveringen bijwerken"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32047"
|
||||
msgid "No default source defined"
|
||||
msgstr "Geen standaardbron gedefinieerd"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32048"
|
||||
msgid "No items found"
|
||||
msgstr "Geen items gevonden"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32046"
|
||||
msgid "Update .nfo"
|
||||
msgstr ".nfo bijwerken"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32049"
|
||||
msgid "Incomplete arguments or content type not supported"
|
||||
msgstr "Onvolledige argumenten of inhoudstype niet ondersteund"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32050"
|
||||
msgid "Do you want to cancel the update?"
|
||||
msgstr "Wilt u de bijwerking annuleren?"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32051"
|
||||
msgid "Content"
|
||||
msgstr "Inhoud"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32052"
|
||||
msgid "Fallback to US MPAA if configured country has no certification stored"
|
||||
msgstr ""
|
||||
"Terugvallen op US MPAA als ingesteld land geen certificering heeft "
|
||||
"opgeslagen"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32053"
|
||||
msgid "Don't store \"NR\" (Not rated) MPAA rating"
|
||||
msgstr "MPAA NR-beoordeling niet opslaan (NR = No rating = geen beoordeling)"
|
||||
|
||||
#: /service.py
|
||||
msgctxt "#32054"
|
||||
msgid "Do you want to rate the following item?"
|
||||
msgstr "Wilt u het volgende item beoordelen?"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32055"
|
||||
msgid "Automatically update changed watched states to .nfo"
|
||||
msgstr "Automatische bijwerking wijzigde kijkstatus naar .nfo"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32056"
|
||||
msgid "Rate your media if playback has ended"
|
||||
msgstr "Beoordeel uw media als het afspelen beëindigd is"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32057"
|
||||
msgid "Write watched flag and playcount to .nfo"
|
||||
msgstr "Kijkstatus (bekeken) en kijkteller wegschrijven naar .nfo"
|
||||
@@ -0,0 +1,146 @@
|
||||
# Metadata Editor language file
|
||||
# Addon Name: Metadata Editor
|
||||
# Addon id: script.metadata.editor
|
||||
# Addon Provider: sualfred
|
||||
# Translators:
|
||||
# Edjalmo Bf <edjalmo.bf@hotmail.com>, 2019
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Metadata Editor\n"
|
||||
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"PO-Revision-Date: 2019-11-07 08:05+0000\n"
|
||||
"Last-Translator: Edjalmo Bf <edjalmo.bf@hotmail.com>, 2019\n"
|
||||
"Language-Team: Portuguese (Brazil) (https://www.transifex.com/sualfred/teams/80018/pt_BR/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: pt_BR\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32000"
|
||||
msgid "Metadata Editor"
|
||||
msgstr "Editor de Metadados"
|
||||
|
||||
#: /resources/lib/dialog.py
|
||||
msgctxt "#32001"
|
||||
msgid "User rating"
|
||||
msgstr "Avaliação do usuário"
|
||||
|
||||
#: /resources/lib/dialog_videogenres.py
|
||||
msgctxt "#32002"
|
||||
msgid "Available entries"
|
||||
msgstr "Entradas disponíveis"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32003"
|
||||
msgid "Add/remove available tags"
|
||||
msgstr "Add/remover tags disponíveis"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32004"
|
||||
msgid "Add/remove available genres"
|
||||
msgstr "Add/remover gêneros disponíveis"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32005"
|
||||
msgid "Add new item"
|
||||
msgstr "Add novo item"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32006"
|
||||
msgid "Modify current list"
|
||||
msgstr "Modificar lista atual"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32007"
|
||||
msgid "Select from available items"
|
||||
msgstr "Selecionar de itens disponíveis"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32008"
|
||||
msgid "Remove favourite tag"
|
||||
msgstr "Remover tag favorita"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32009"
|
||||
msgid "Add favourite tag"
|
||||
msgstr "Add tag favorita"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32010"
|
||||
msgid "Open editor"
|
||||
msgstr "Editor livre"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32011"
|
||||
msgid "Enter floating number"
|
||||
msgstr "Digite um número real"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32012"
|
||||
msgid "Select source"
|
||||
msgstr "Selecionar caminho"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32013"
|
||||
msgid "Available sources"
|
||||
msgstr "Caminhos disponíveis"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32014"
|
||||
msgid "Default source"
|
||||
msgstr "Caminho padrão"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32015"
|
||||
msgid "Select default source"
|
||||
msgstr "Selecionar caminho padrão"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32016"
|
||||
msgid "Edit ratings and votes"
|
||||
msgstr "Editar notas e votos"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32017"
|
||||
msgid "Add source"
|
||||
msgstr "Add caminho"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32018"
|
||||
msgid "Only values between 1.0 and 10.0 are allowed."
|
||||
msgstr "Somente valores entre 1.0 e 10.0 são permitidos."
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32019"
|
||||
msgid "Attention"
|
||||
msgstr "Atenção"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32020"
|
||||
msgid "Set as default?"
|
||||
msgstr "Definir como padrão?"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32021"
|
||||
msgid "Enable .nfo updating for movies, TV shows and music videos"
|
||||
msgstr "Ativar atualização de .nfo para filmes, seriados e videoclipes"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32022"
|
||||
msgid "value unkown (missing Kodi feature)"
|
||||
msgstr "valor desconhecidos (faltando recurso do Kodi)"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32023"
|
||||
msgid "Record label"
|
||||
msgstr "Gravadora"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32024"
|
||||
msgid "Please use the context menu on a library item to run this script."
|
||||
msgstr ""
|
||||
"Por favor, use o menu de contexto em um item da biblioteca para executar "
|
||||
"este script."
|
||||
@@ -0,0 +1,274 @@
|
||||
# Metadata Editor language file
|
||||
# Addon Name: Metadata Editor
|
||||
# Addon id: script.metadata.editor
|
||||
# Addon Provider: sualfred
|
||||
# Translators:
|
||||
# Эдуард Приутеса <eduardpriutesa@gmail.com>, 2019
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Metadata Editor\n"
|
||||
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"PO-Revision-Date: 2019-11-07 08:05+0000\n"
|
||||
"Last-Translator: Эдуард Приутеса <eduardpriutesa@gmail.com>, 2019\n"
|
||||
"Language-Team: Russian (Russia) (https://www.transifex.com/sualfred/teams/80018/ru_RU/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ru_RU\n"
|
||||
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32000"
|
||||
msgid "Metadata Editor"
|
||||
msgstr "Редактор метаданных"
|
||||
|
||||
#: /resources/lib/dialog.py
|
||||
msgctxt "#32001"
|
||||
msgid "User rating"
|
||||
msgstr "Рейтинг пользователей"
|
||||
|
||||
#: /resources/lib/dialog_videogenres.py
|
||||
msgctxt "#32002"
|
||||
msgid "Available entries"
|
||||
msgstr "Доступные записи"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32003"
|
||||
msgid "Add/remove available tags"
|
||||
msgstr "Добавить / удалить доступные теги"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32004"
|
||||
msgid "Add/remove available genres"
|
||||
msgstr "Добавить / удалить доступные жанры"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32005"
|
||||
msgid "Add new item"
|
||||
msgstr "Добавление нового элемента"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32006"
|
||||
msgid "Edit current list as string"
|
||||
msgstr "Изменить текущий список как строку"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32007"
|
||||
msgid "Select from available items"
|
||||
msgstr "Выберите из доступных предметов"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32008"
|
||||
msgid "Remove watchlist tag"
|
||||
msgstr "Удалить тег списка наблюдения"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32009"
|
||||
msgid "Add watchlist tag"
|
||||
msgstr "Добавить тег наблюдения"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32010"
|
||||
msgid "Open editor"
|
||||
msgstr "Открыть редактор"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32011"
|
||||
msgid "Enter floating number"
|
||||
msgstr "Введите плавающее число"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32012"
|
||||
msgid "Select source"
|
||||
msgstr "Выберите источник"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32013"
|
||||
msgid "Available sources"
|
||||
msgstr "Доступные источники"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32014"
|
||||
msgid "Default source"
|
||||
msgstr "Источник по умолчанию"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32015"
|
||||
msgid "Select default source"
|
||||
msgstr "Выберите источник по умолчанию"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32016"
|
||||
msgid "Edit ratings and votes"
|
||||
msgstr "Редактировать рейтинги и голоса"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32017"
|
||||
msgid "Add source"
|
||||
msgstr "Добавить источник"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32018"
|
||||
msgid "Only values between 1.0 and 10.0 are allowed."
|
||||
msgstr "Допустимы только значения от 1,0 до 10,0."
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32019"
|
||||
msgid "Attention"
|
||||
msgstr "Внимание!"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32020"
|
||||
msgid "Set as default?"
|
||||
msgstr "Установить по умолчанию?"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32021"
|
||||
msgid "Enable .nfo updating for movies, TV shows and music videos"
|
||||
msgstr "Включить обновление .nfo для фильмов, сериалов и музыкальных клипов"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32022"
|
||||
msgid "value unkown (missing Kodi feature)"
|
||||
msgstr "Значение неизвестно (отсутствует функция Kodi)"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32023"
|
||||
msgid "Record label"
|
||||
msgstr "Запись метки"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32024"
|
||||
msgid "Please use the context menu on a library item to run this script."
|
||||
msgstr ""
|
||||
"Пожалуйста, используйте контекстное меню элемента библиотеки, чтобы "
|
||||
"запустить этот скрипт."
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32025"
|
||||
msgid "Preferred TMDb language"
|
||||
msgstr "Предпочитаемый язык TMDb"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32026"
|
||||
msgid "TV show scraper related settings"
|
||||
msgstr "Настройки скрепера для сериалов"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32027"
|
||||
msgid "Library is based on informations of"
|
||||
msgstr "Библиотека основана на информации"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32029"
|
||||
msgid "Enable JSON logging"
|
||||
msgstr "Включить ведение журнала JSON"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32030"
|
||||
msgid "Rating updater"
|
||||
msgstr "Обновление рейтинга"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32028"
|
||||
msgid "Run updating process in the background"
|
||||
msgstr "Запустите процесс обновления в фоновом режиме"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32031"
|
||||
msgid "Your personal OMDb API key (www.omdbapi.com)"
|
||||
msgstr "Ваш личный ключ API OMDb (www.omdbapi.com)"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32032"
|
||||
msgid "Search OMDb with title/year if IMDb is missing"
|
||||
msgstr "Поиск OMDb с названием / годом, если IMDb отсутствует"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32033"
|
||||
msgid "Updating movie ratings"
|
||||
msgstr "Обновление рейтингов фильмов"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32034"
|
||||
msgid "Updating TV show ratings"
|
||||
msgstr "Обновление рейтингов сериалов"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32035"
|
||||
msgid ""
|
||||
"No OMDb API key is configured, which is required to update IMDb, Rotten "
|
||||
"Tomatoes and Metacritic ratings. Please visit www.omdbapi.com and create "
|
||||
"your own API key.[CR][CR]Note: The free key is limited to 1000 calls a day. "
|
||||
"Please suggest to become a patreon of OMDb to increase the limit to "
|
||||
"100.000.[CR][CR]Do you want to proceed updating The Movie DB ratings? This "
|
||||
"only works if you have a TMDb ID stored."
|
||||
msgstr ""
|
||||
"Не настроен ключ API OMDb, который необходим для обновления рейтингов IMDb, "
|
||||
"Rotten Tomatoes и Metacritic . Пожалуйста, посетите www.omdbapi.com и "
|
||||
"создайте свой собственный ключ API. [CR] [CR] Примечание: бесплатный ключ "
|
||||
"ограничен 1000 звонками в день. Пожалуйста, предложите стать партнёром OMDb,"
|
||||
" чтобы увеличить лимит до 100.000. [CR] [CR] Хотите продолжить обновление "
|
||||
"рейтинга The Movie DB? Это работает, только если у вас есть идентификатор "
|
||||
"TMDb."
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32036"
|
||||
msgid "Update TV show ratings"
|
||||
msgstr "Обновление рейтингов сериалов"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32037"
|
||||
msgid "Update movie ratings"
|
||||
msgstr "Обновить рейтинги фильмов"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32038"
|
||||
msgid "Update all ratings"
|
||||
msgstr "Обновить все рейтинги"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32039"
|
||||
msgid "Update ratings"
|
||||
msgstr "Обновить рейтинги"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32040"
|
||||
msgid "Edit data for"
|
||||
msgstr "Изменить данные для"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32041"
|
||||
msgid "Cancel updating"
|
||||
msgstr "Отменить обновление"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32042"
|
||||
msgid "Canceled"
|
||||
msgstr "Отменен"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32043"
|
||||
msgid "MPAA region"
|
||||
msgstr "MPAA регион"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32044"
|
||||
msgid "Skip updating of MPAA"
|
||||
msgstr "Пропустить обновление MPAA"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32045"
|
||||
msgid "Update episode ratings"
|
||||
msgstr "Обновление рейтингов эпизодов"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32046"
|
||||
msgid "Updating episode ratings"
|
||||
msgstr "Обновление рейтингов эпизодов"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32047"
|
||||
msgid "No default source defined"
|
||||
msgstr "Источник по умолчанию не определен"
|
||||
@@ -0,0 +1,329 @@
|
||||
# Metadata Editor language file
|
||||
# Addon Name: Metadata Editor
|
||||
# Addon id: script.metadata.editor
|
||||
# Addon Provider: sualfred
|
||||
# Translators:
|
||||
# Snn 1452 <snn1452@gmail.com>, 2020
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Metadata Editor\n"
|
||||
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"PO-Revision-Date: 2019-11-07 08:05+0000\n"
|
||||
"Last-Translator: Snn 1452 <snn1452@gmail.com>, 2020\n"
|
||||
"Language-Team: Turkish (Turkey) (https://www.transifex.com/sualfred/teams/80018/tr_TR/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: tr_TR\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32000"
|
||||
msgid "Metadata Editor"
|
||||
msgstr "Metaveri Düzenleyici"
|
||||
|
||||
#: /resources/lib/dialog.py
|
||||
msgctxt "#32001"
|
||||
msgid "User rating"
|
||||
msgstr "Kullanıcı derecelendirmesi"
|
||||
|
||||
#: /resources/lib/dialog_videogenres.py
|
||||
msgctxt "#32002"
|
||||
msgid "Available entries"
|
||||
msgstr "Mevcut girişler"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32003"
|
||||
msgid "Add/remove available tags"
|
||||
msgstr "Mevcut etiketleri ekle/kaldır"
|
||||
|
||||
#: /addon.xml
|
||||
msgctxt "#32004"
|
||||
msgid "Add/remove available genres"
|
||||
msgstr "Mevcut türleri ekle/kaldır"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32005"
|
||||
msgid "Add new item"
|
||||
msgstr "Yeni öğe ekle"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32006"
|
||||
msgid "Edit current list as string"
|
||||
msgstr "Geçerli listeyi dize olarak düzenle"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32007"
|
||||
msgid "Select from available items"
|
||||
msgstr "Mevcut öğelerden seç"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32008"
|
||||
msgid "Remove watchlist tag"
|
||||
msgstr "İzleme listesi etiketini kaldır"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32009"
|
||||
msgid "Add watchlist tag"
|
||||
msgstr "İzleme listesi etiketi ekle"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32010"
|
||||
msgid "Open editor"
|
||||
msgstr "Düzenleyiciyi aç"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32011"
|
||||
msgid "Enter floating number"
|
||||
msgstr "Yüzen numarayı girin"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32012"
|
||||
msgid "Select source"
|
||||
msgstr "Kaynak Seç"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32013"
|
||||
msgid "Available sources"
|
||||
msgstr "Mevcut kaynaklar"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32014"
|
||||
msgid "Default source"
|
||||
msgstr "Varsayılan kaynak"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32015"
|
||||
msgid "Select default source"
|
||||
msgstr "Varsayılan kaynağı seç"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32016"
|
||||
msgid "Edit ratings and votes"
|
||||
msgstr "Derecelendirmeleri ve oyları düzenle"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32017"
|
||||
msgid "Add source"
|
||||
msgstr "Kaynak ekle"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32018"
|
||||
msgid "Only values between 1.0 and 10.0 are allowed."
|
||||
msgstr "Yalnızca 1.0 ile 10.0 arasındaki değerlere izin verilir."
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32019"
|
||||
msgid "Attention"
|
||||
msgstr "Dikkat"
|
||||
|
||||
#: /resources/lib/utils.py
|
||||
msgctxt "#32020"
|
||||
msgid "Set as default?"
|
||||
msgstr "Varsayılan olarak ayarla?"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32021"
|
||||
msgid "Enable .nfo updating for movies, TV shows and music videos"
|
||||
msgstr ""
|
||||
"Filmler, TV programları ve müzik videoları için .nfo güncellemesini "
|
||||
"etkinleştir"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32022"
|
||||
msgid "value unkown (missing Kodi feature)"
|
||||
msgstr "bilinmeyen değer (eksik Kodi özelliği)"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32023"
|
||||
msgid "Record label"
|
||||
msgstr "Kayıt etiketi"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32025"
|
||||
msgid "Preferred language"
|
||||
msgstr "Tercih edilen dil"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32026"
|
||||
msgid "Scraper settings"
|
||||
msgstr "Scraper ayarları"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32024"
|
||||
msgid "Heavy server load. Please wait."
|
||||
msgstr "Ağır sunucu yükü. Lütfen bekleyin."
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32027"
|
||||
msgid "TV show library is based on informations of"
|
||||
msgstr "TV programları kitaplığı bilgilerine dayanmaktadır:"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32029"
|
||||
msgid "Enable JSON logging"
|
||||
msgstr "JSON günlüğünü etkinleştir"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32030"
|
||||
msgid "Rating updater"
|
||||
msgstr "Derecelendirme güncelleyici"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32028"
|
||||
msgid "Run updating process in the background"
|
||||
msgstr "Güncelleme işlemini arka planda çalıştır"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32031"
|
||||
msgid "Your personal OMDb API key (www.omdbapi.com)"
|
||||
msgstr "Kişisel OMDb API anahtarınız (www.omdbapi.com)"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32032"
|
||||
msgid "Search by title/year if IMDb ID is missing (not recommended)"
|
||||
msgstr "IMDb kimliği eksikse başlığa/yıla göre ara (önerilmez)"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32035"
|
||||
msgid ""
|
||||
"No OMDb API key is configured, which is required to update IMDb, Rotten "
|
||||
"Tomatoes and Metacritic ratings. Please visit www.omdbapi.com and create "
|
||||
"your own API key.[CR][CR]Note: The free key is limited to 1000 calls a day. "
|
||||
"Please suggest to become a patreon of OMDb to increase the limit to "
|
||||
"100.000.[CR][CR]Do you want to proceed updating The Movie DB ratings? This "
|
||||
"only works if you have a TMDb ID stored."
|
||||
msgstr ""
|
||||
"IMDb, Çürük Domates ve Metakritik derecelendirmelerini güncellemek için "
|
||||
"gerekli olan hiçbir OMDb API anahtarı yapılandırılmadı. Lütfen "
|
||||
"www.omdbapi.com adresini ziyaret edin ve kendi API anahtarınızı "
|
||||
"oluşturun.[CR][CR]Not: Ücretsiz anahtar günde 1000 çağrı ile sınırlıdır. "
|
||||
"Lütfen limiti 100.000'e çıkarmak için OMDb'de patron olun.[CR][CR]The Movie "
|
||||
"DB derecelendirmelerini güncellemeye devam etmek ister misiniz? Bu yalnızca "
|
||||
"kayıtlı bir TMDb kimliğiniz varsa çalışır."
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32036"
|
||||
msgid "Update TV show ratings"
|
||||
msgstr "TV programı derecelendirmelerini güncelle"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32033"
|
||||
msgid ""
|
||||
"OMDB API limit reached. Please consider to become a Patreon to increase your"
|
||||
" daily call limitation. Proceed by only using The Movie DB?"
|
||||
msgstr ""
|
||||
"OMDB API sınırına ulaşıldı. Günlük arama sınırınızı artırmak için lütfen bir"
|
||||
" Patreon olmayı düşünün. Yalnızca The Movie DB kullanarak devam edilsin mi?"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32034"
|
||||
msgid "Create .nfo file if missing"
|
||||
msgstr "Eksikse .nfo dosyası oluştur"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32037"
|
||||
msgid "Update movie ratings"
|
||||
msgstr "Film derecelendirmelerini güncelle"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32038"
|
||||
msgid "Update all ratings"
|
||||
msgstr "Tüm derecelendirmeleri güncelle"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32039"
|
||||
msgid "Update ratings"
|
||||
msgstr "Derecelendirmeleri güncelle"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32040"
|
||||
msgid "Edit data for"
|
||||
msgstr "Verilerini düzenle:"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32042"
|
||||
msgid "Canceled"
|
||||
msgstr "İptal edildi"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32043"
|
||||
msgid "MPAA region"
|
||||
msgstr "MPAA bölgesi"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32041"
|
||||
msgid "Update premiered/year if database value is different"
|
||||
msgstr "Veritabanı değeri farklıysa gösterim/yıl değerini güncelle"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32044"
|
||||
msgid "Skip updating of MPAA"
|
||||
msgstr "MPAA'nın güncellenmesini atla"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32045"
|
||||
msgid "Update episode ratings"
|
||||
msgstr "Bölüm derecelendirmelerini güncelle"
|
||||
|
||||
#: /resources/lib/editor.py
|
||||
msgctxt "#32047"
|
||||
msgid "No default source defined"
|
||||
msgstr "Tanımlanmış varsayılan kaynak yok"
|
||||
|
||||
#: /resources/lib/rating_updater.py
|
||||
msgctxt "#32048"
|
||||
msgid "No items found"
|
||||
msgstr "Hiç öğe bulunamadı"
|
||||
|
||||
#: /context.py
|
||||
msgctxt "#32046"
|
||||
msgid "Update .nfo"
|
||||
msgstr ".nfo güncelle"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32049"
|
||||
msgid "Incomplete arguments or content type not supported"
|
||||
msgstr "Eksik argümanlar veya içerik türü desteklenmiyor"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32050"
|
||||
msgid "Do you want to cancel the update?"
|
||||
msgstr "Güncellemeyi iptal etmek istiyor musunuz?"
|
||||
|
||||
#: /default.py
|
||||
msgctxt "#32051"
|
||||
msgid "Content"
|
||||
msgstr "İçerik"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32052"
|
||||
msgid "Fallback to US MPAA if configured country has no certification stored"
|
||||
msgstr ""
|
||||
"Yapılandırılmış ülkenin kayıtlı sertifikası yoksa ABD MPAA'ya geri dön"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32053"
|
||||
msgid "Don't store \"NR\" (Not rated) MPAA rating"
|
||||
msgstr "\"NR\" (Derecelendirilmedi) MPAA derecelendirmesini saklama"
|
||||
|
||||
#: /service.py
|
||||
msgctxt "#32054"
|
||||
msgid "Do you want to rate the following item?"
|
||||
msgstr "Takip edilen öğeyi derecelendirmek istiyor musunuz?"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32055"
|
||||
msgid "Automatically update changed watched states to .nfo"
|
||||
msgstr "İzlenme durumları değiştiğinde .nfo'yu otomatik güncelle"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32056"
|
||||
msgid "Rate your media if playback has ended"
|
||||
msgstr "Oynatma sona erdiğinde medyanızı derecelendirin"
|
||||
|
||||
#: /resources/settings.xml
|
||||
msgctxt "#32057"
|
||||
msgid "Write watched flag and playcount to .nfo"
|
||||
msgstr "İzlenen durumunu ve çalma sayısını .nfo'ya yaz"
|
||||
@@ -0,0 +1,153 @@
|
||||
#!/usr/bin/python
|
||||
# coding: utf-8
|
||||
|
||||
########################
|
||||
|
||||
from resources.lib.helper import *
|
||||
from resources.lib.json_map import *
|
||||
|
||||
########################
|
||||
|
||||
class Database(object):
|
||||
def __init__(self,dbid=None,dbtype=None,append=''):
|
||||
self.dbid = dbid
|
||||
self.append = append
|
||||
self.data = {}
|
||||
|
||||
if dbtype:
|
||||
if dbtype in ['movie', 'tvshow', 'season', 'episode', 'musicvideo']:
|
||||
library = 'Video'
|
||||
self.data['nfo'] = True
|
||||
|
||||
elif dbtype in ['set']:
|
||||
library = 'Video'
|
||||
self.data['nfo'] = False
|
||||
|
||||
else:
|
||||
library = 'Audio'
|
||||
self.data['nfo'] = False
|
||||
|
||||
self.set_details = '%sLibrary.Set%sDetails' % (library, dbtype.replace('set', 'movieset'))
|
||||
self.param = '%sid' % dbtype
|
||||
|
||||
def result(self):
|
||||
return self.data
|
||||
|
||||
def write(self,key,value):
|
||||
if not isinstance(key, list):
|
||||
key = [key]
|
||||
value = [value]
|
||||
|
||||
for k in key:
|
||||
json_call(self.set_details,
|
||||
params={'%s' % k: value[key.index(k)], self.param: int(self.dbid)},
|
||||
debug=LOG_JSON
|
||||
)
|
||||
|
||||
def movies(self):
|
||||
self._items('video', 'movie')
|
||||
|
||||
def movie(self):
|
||||
self._item('video', 'movie')
|
||||
|
||||
def sets(self):
|
||||
self._items('video', 'set')
|
||||
|
||||
def set(self):
|
||||
self._item('video', 'set')
|
||||
|
||||
def tvshows(self):
|
||||
self._items('video', 'tvshow')
|
||||
|
||||
def tvshow(self):
|
||||
self._item('video', 'tvshow')
|
||||
|
||||
if self.data['tvshow'] and 'episodes' in self.append:
|
||||
tvshowid = self.data['tvshow'][0].get('tvshowid')
|
||||
self._items('video', 'episode', {'tvshowid': int(tvshowid)})
|
||||
|
||||
def episode(self):
|
||||
self._item('video', 'episode')
|
||||
|
||||
def episodes(self):
|
||||
self._items('video', 'episode')
|
||||
|
||||
def musicvideo(self):
|
||||
self._item('video', 'musicvideo')
|
||||
|
||||
def musicvideos(self):
|
||||
self._items('video', 'musicvideo')
|
||||
|
||||
def artist(self):
|
||||
self._item('audio', 'artist')
|
||||
|
||||
def artists(self):
|
||||
self._items('audio', 'artist')
|
||||
|
||||
def album(self):
|
||||
self._item('audio', 'album')
|
||||
|
||||
def albums(self):
|
||||
self._items('audio', 'album')
|
||||
|
||||
def song(self):
|
||||
self._item('audio', 'song')
|
||||
|
||||
def songs(self):
|
||||
self._items('audio', 'song')
|
||||
|
||||
def genre(self):
|
||||
movie = []
|
||||
tvshow = []
|
||||
musicvideo = []
|
||||
music = []
|
||||
video = []
|
||||
audio = []
|
||||
|
||||
# video db
|
||||
for i in ['movie', 'tvshow', 'musicvideo']:
|
||||
genres = json_call('VideoLibrary.GetGenres',
|
||||
properties=['title'],
|
||||
params={'type': i}
|
||||
)
|
||||
genres = genres.get('result', {}).get('genres', [])
|
||||
|
||||
for genre in genres:
|
||||
eval(i).append(genre.get('label'))
|
||||
|
||||
# audio db
|
||||
genres = json_call('AudioLibrary.GetGenres',
|
||||
properties=['title']
|
||||
)
|
||||
genres = genres.get('result', {}).get('genres', [])
|
||||
|
||||
for genre in genres:
|
||||
music.append(genre.get('label'))
|
||||
|
||||
self.data['moviegenres'] = movie
|
||||
self.data['tvshowgenres'] = tvshow
|
||||
self.data['musicvideogenres'] = musicvideo
|
||||
self.data['musicgenres'] = music
|
||||
self.data['videogenres'] = list(set(movie + tvshow + musicvideo))
|
||||
self.data['audiogenres'] = list(set(music + musicvideo))
|
||||
|
||||
def tags(self):
|
||||
tags = json_call('VideoLibrary.GetTags',
|
||||
properties=['title']
|
||||
)
|
||||
self.data['tags'] = tags.get('result', {}).get('tags', [])
|
||||
|
||||
def _item(self,library,dbtype):
|
||||
item = json_call('%sLibrary.Get%sDetails' % (library, dbtype.replace('set', 'movieset')),
|
||||
properties=JSON_MAP.get('%s_properties' % dbtype),
|
||||
params={'%sid' % dbtype: int(self.dbid)}
|
||||
)
|
||||
self.data[dbtype] = [item.get('result', {}).get('%sdetails' % dbtype)]
|
||||
|
||||
def _items(self,library,dbtype,params=None,query_filter=None):
|
||||
items = json_call('%sLibrary.Get%ss' % (library, dbtype.replace('set', 'movieset')),
|
||||
properties=JSON_MAP.get('%ss_properties' % dbtype),
|
||||
params=params,
|
||||
query_filter=query_filter
|
||||
)
|
||||
self.data[dbtype] = items.get('result', {}).get('%ss' % dbtype, [])
|
||||
@@ -0,0 +1,338 @@
|
||||
#!/usr/bin/python
|
||||
# coding: utf-8
|
||||
|
||||
########################
|
||||
|
||||
from resources.lib.helper import *
|
||||
from resources.lib.json_map import *
|
||||
from resources.lib.functions import *
|
||||
from resources.lib.database import *
|
||||
from resources.lib.nfo_updater import *
|
||||
|
||||
########################
|
||||
|
||||
class EditDialog(object):
|
||||
def __init__(self,dbid,dbtype):
|
||||
winprop('SelectDialogPreselect', clear=True)
|
||||
self.dbid = dbid
|
||||
self.dbtype = dbtype
|
||||
|
||||
self.db = Database(dbid=self.dbid, dbtype=self.dbtype)
|
||||
self.nfo_support = self.db.result().get('nfo')
|
||||
self.status = None
|
||||
self.get_details()
|
||||
|
||||
def get_details(self):
|
||||
getattr(self.db, self.dbtype)()
|
||||
self.details = self.db.result().get(self.dbtype)[0]
|
||||
self.file = self.details.get('file') if self.nfo_support else False
|
||||
|
||||
def editor(self):
|
||||
self.modeselect = []
|
||||
self.keylist = []
|
||||
self.presetlist = []
|
||||
self.typelist = []
|
||||
self.optionlist = []
|
||||
self.generate_list()
|
||||
self.dialog()
|
||||
|
||||
def set(self,key,type):
|
||||
preset = self.details.get(key)
|
||||
|
||||
if isinstance(preset, list):
|
||||
preset = get_joined_items(preset)
|
||||
elif isinstance(preset, float):
|
||||
preset = str(get_rounded_value(preset))
|
||||
elif isinstance(preset, int):
|
||||
preset = str(preset)
|
||||
|
||||
self._handle_dbitem(value_type=type,
|
||||
key=key,
|
||||
preset=preset
|
||||
)
|
||||
self.get_details()
|
||||
self.quit()
|
||||
|
||||
def quit(self):
|
||||
if self.file:
|
||||
|
||||
if self.status:
|
||||
self.details['status'] = self.status
|
||||
|
||||
update_nfo(file=self.file,
|
||||
dbtype=self.dbtype,
|
||||
dbid=self.dbid,
|
||||
details=self.details
|
||||
)
|
||||
|
||||
reload_widgets()
|
||||
|
||||
def dialog(self):
|
||||
preselect = winprop('SelectDialogPreselect')
|
||||
if not preselect:
|
||||
preselect = -1
|
||||
|
||||
if self.details.get('title'):
|
||||
headline = ADDON.getLocalizedString(32040) + ' "' + self.details.get('title') + '"'
|
||||
elif self.details.get('artist'):
|
||||
headline = ADDON.getLocalizedString(32040) + ' "' + self.details.get('artist') + '"'
|
||||
else:
|
||||
headline = ADDON.getLocalizedString(32000)
|
||||
|
||||
self.editdialog = DIALOG.select(headline, self.modeselect, preselect=int(preselect), useDetails=True)
|
||||
|
||||
# Dialog closed -> write changes to nfo and exit
|
||||
if self.editdialog == -1:
|
||||
winprop('SelectDialogPreselect', clear=True)
|
||||
self.quit()
|
||||
|
||||
else:
|
||||
# Edit value based on the type
|
||||
winprop('SelectDialogPreselect', str(self.editdialog))
|
||||
|
||||
self._handle_dbitem(value_type=self.typelist[self.editdialog],
|
||||
key=self.keylist[self.editdialog],
|
||||
preset=self.presetlist[self.editdialog],
|
||||
option=self.optionlist[self.editdialog]
|
||||
)
|
||||
|
||||
# Refetch updated data and return to entry_point to populate the changes in the dialog
|
||||
self.get_details()
|
||||
self.editor()
|
||||
|
||||
def generate_list(self):
|
||||
details = self.details
|
||||
uniqueid = details.get('uniqueid', {})
|
||||
ratings = details.get('ratings')
|
||||
votes = details.get('votes', 0)
|
||||
|
||||
if not votes or votes == -1:
|
||||
votes = 0
|
||||
|
||||
# Fallback rule. Create own ratings dict if it's missing in the database.
|
||||
if not ratings:
|
||||
ratings = {'default': {'default': True,
|
||||
'rating': details.get('rating', 0.0),
|
||||
'votes': details.get('votes', 0)}
|
||||
}
|
||||
|
||||
ratings_default = None
|
||||
for item in ratings:
|
||||
if ratings[item].get('default'):
|
||||
ratings_value = str(get_rounded_value(ratings[item].get('rating', 0.0)))
|
||||
votes_value = str(ratings[item].get('votes', '0'))
|
||||
ratings_default = ratings_value + ' / ' + votes_value + ' (' + xbmc.getLocalizedString(21870) + ': ' + item + ')'
|
||||
break
|
||||
|
||||
if not ratings_default and len(ratings) > 0:
|
||||
ratings_default = ADDON.getLocalizedString(32047)
|
||||
|
||||
if self.dbtype == 'movie':
|
||||
self._create_list(xbmc.getLocalizedString(369), 'title', value=details.get('title'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(20376), 'originaltitle', value=details.get('originaltitle'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(171), 'sorttitle', value=details.get('sorttitle'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(345) + ' / ' + xbmc.getLocalizedString(172), 'premiered', value=details.get('premiered'), type='date')
|
||||
self._create_list(xbmc.getLocalizedString(515), 'genre', value=get_joined_items(details.get('genre')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(202), 'tagline', value=details.get('tagline'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(207), 'plot', value=details.get('plot'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(203), 'plotoutline', value=details.get('plotoutline'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(20457), 'set', value=details.get('set'), type='movieset')
|
||||
self._create_list(xbmc.getLocalizedString(563) + ' / ' + xbmc.getLocalizedString(205), 'ratings', value=ratings_default, type='ratings', option=ratings)
|
||||
self._create_list(ADDON.getLocalizedString(32001), 'userrating', value=str(details.get('userrating')), type='userrating')
|
||||
self._create_list(xbmc.getLocalizedString(20074), 'mpaa', value=details.get('mpaa'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(20339), 'director', value=get_joined_items(details.get('director')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(20417), 'writer', value=get_joined_items(details.get('writer')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(21875), 'country', value=get_joined_items(details.get('country')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(572), 'studio', value=get_joined_items(details.get('studio')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(20459), 'tag', value=get_joined_items(details.get('tag')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(20410), 'trailer', value=details.get('trailer'), type='string')
|
||||
self._create_list('IMDb ID', 'uniqueid', value=uniqueid.get('imdb'), type='uniqueid', option={'type': 'imdb', 'uniqueids': uniqueid})
|
||||
self._create_list('TMDb ID', 'uniqueid', value=uniqueid.get('tmdb'), type='uniqueid', option={'type': 'tmdb', 'uniqueids': uniqueid})
|
||||
self._create_list(xbmc.getLocalizedString(13409), 'top250', value=str(details.get('top250')), type='integer')
|
||||
self._create_list(xbmc.getLocalizedString(570), 'dateadded', value=details.get('dateadded'), type='datetime')
|
||||
self._create_list(xbmc.getLocalizedString(568), 'lastplayed', value=details.get('lastplayed'), type='datetime')
|
||||
self._create_list(xbmc.getLocalizedString(567), 'playcount', value=str(details.get('playcount', 0)), type='integer')
|
||||
|
||||
elif self.dbtype == 'tvshow':
|
||||
if KODI_VERSION < 19:
|
||||
status = ADDON.getLocalizedString(32022)
|
||||
else:
|
||||
status = details.get('status', '')
|
||||
|
||||
self._create_list(xbmc.getLocalizedString(369), 'title', value=details.get('title'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(20376),'originaltitle', value=details.get('originaltitle'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(171), 'sorttitle', value=details.get('sorttitle'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(345) + ' / ' + xbmc.getLocalizedString(172), 'premiered', value=details.get('premiered'), type='date')
|
||||
self._create_list(xbmc.getLocalizedString(515), 'genre', value=get_joined_items(details.get('genre')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(207), 'plot', value=details.get('plot'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(563) + ' / ' + xbmc.getLocalizedString(205), 'ratings', value=ratings_default, type='ratings', option=ratings)
|
||||
self._create_list(ADDON.getLocalizedString(32001), 'userrating', value=str(details.get('userrating')), type='userrating')
|
||||
self._create_list(xbmc.getLocalizedString(20074), 'mpaa', value=details.get('mpaa'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(572), 'studio', value=get_joined_items(details.get('studio')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(20459), 'tag', value=get_joined_items(details.get('tag')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(126), 'status', value=status, type='status')
|
||||
self._create_list('IMDb ID', 'uniqueid', value=uniqueid.get('imdb'), type='uniqueid', option={'type': 'imdb', 'uniqueids': uniqueid, 'episodeguide': details.get('episodeguide')})
|
||||
self._create_list('TMDb ID', 'uniqueid', value=uniqueid.get('tmdb'), type='uniqueid', option={'type': 'tmdb', 'uniqueids': uniqueid, 'episodeguide': details.get('episodeguide')})
|
||||
self._create_list('TVDb ID', 'uniqueid', value=uniqueid.get('tvdb'), type='uniqueid', option={'type': 'tvdb', 'uniqueids': uniqueid, 'episodeguide': details.get('episodeguide')})
|
||||
self._create_list('aniDB ID', 'uniqueid', value=uniqueid.get('anidb'), type='uniqueid', option={'type': 'anidb', 'uniqueids': uniqueid, 'episodeguide': details.get('episodeguide')})
|
||||
|
||||
elif self.dbtype == 'episode':
|
||||
self._create_list(xbmc.getLocalizedString(369), 'title', value=details.get('title'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(20376), 'originaltitle', value=details.get('originaltitle'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(20416), 'firstaired', value=details.get('firstaired'), type='date')
|
||||
self._create_list(xbmc.getLocalizedString(207), 'plot', value=details.get('plot'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(563) + ' / ' + xbmc.getLocalizedString(205), 'ratings', value=ratings_default, type='ratings', option=ratings)
|
||||
self._create_list(ADDON.getLocalizedString(32001), 'userrating', value=str(details.get('userrating')), type='userrating')
|
||||
self._create_list(xbmc.getLocalizedString(20339), 'director', value=get_joined_items(details.get('director')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(20417), 'writer', value=get_joined_items(details.get('writer')), type='array')
|
||||
self._create_list('IMDb ID', 'uniqueid', value=uniqueid.get('imdb'), type='uniqueid', option={'type': 'imdb', 'uniqueids': uniqueid})
|
||||
self._create_list('TMDb ID', 'uniqueid', value=uniqueid.get('tmdb'), type='uniqueid', option={'type': 'tmdb', 'uniqueids': uniqueid})
|
||||
self._create_list('TVDb ID', 'uniqueid', value=uniqueid.get('tvdb'), type='uniqueid', option={'type': 'tvdb', 'uniqueids': uniqueid})
|
||||
self._create_list('aniDB ID', 'uniqueid', value=uniqueid.get('anidb'), type='uniqueid', option={'type': 'anidb', 'uniqueids': uniqueid})
|
||||
self._create_list(xbmc.getLocalizedString(570), 'dateadded', value=details.get('dateadded'), type='datetime')
|
||||
self._create_list(xbmc.getLocalizedString(568), 'lastplayed', value=details.get('lastplayed'), type='datetime')
|
||||
self._create_list(xbmc.getLocalizedString(567), 'playcount', value=str(details.get('playcount', 0)), type='integer')
|
||||
|
||||
elif self.dbtype == 'set':
|
||||
self._create_list(xbmc.getLocalizedString(369), 'title', value=details.get('title'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(207), 'plot', value=details.get('plot'), type='string')
|
||||
|
||||
elif self.dbtype == 'musicvideo':
|
||||
self._create_list(xbmc.getLocalizedString(369), 'title', value=details.get('title'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(557), 'artist', value=get_joined_items(details.get('artist')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(558), 'album', value=details.get('album'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(345) + ' / ' + xbmc.getLocalizedString(172), 'premiered', value=details.get('premiered'), type='date')
|
||||
self._create_list(xbmc.getLocalizedString(554), 'track', value=str(details.get('track')), type='integer')
|
||||
self._create_list(xbmc.getLocalizedString(207), 'plot', value=details.get('plot'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(515), 'genre', value=get_joined_items(details.get('genre')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(20339), 'director', value=get_joined_items(details.get('director')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(572), 'studio', value=get_joined_items(details.get('studio')), type='array')
|
||||
# self._create_list(xbmc.getLocalizedString(563), 'rating', value=str(get_rounded_value(details.get('rating'))), type='integer') broken in kodi? cannot be set
|
||||
self._create_list(ADDON.getLocalizedString(32001), 'userrating', value=str(details.get('userrating')), type='userrating')
|
||||
self._create_list(xbmc.getLocalizedString(20459), 'tag', value=get_joined_items(details.get('tag')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(570), 'dateadded', value=details.get('dateadded'), type='datetime')
|
||||
self._create_list(xbmc.getLocalizedString(568), 'lastplayed', value=details.get('lastplayed'), type='datetime')
|
||||
self._create_list(xbmc.getLocalizedString(567), 'playcount', value=str(details.get('playcount', 0)), type='integer')
|
||||
|
||||
elif self.dbtype == 'artist':
|
||||
self._create_list(xbmc.getLocalizedString(515), 'genre', value=get_joined_items(details.get('genre')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(21821), 'description', value=details.get('description'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(39026), 'disambiguation', value=details.get('disambiguation'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(736), 'style', value=get_joined_items(details.get('style')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(175), 'mood', value=get_joined_items(details.get('mood')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(21892), 'instrument', value=get_joined_items(details.get('instrument')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(21893), 'born', value=details.get('born'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(21897), 'died', value=details.get('died'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(21894), 'formed', value=details.get('formed'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(21896), 'disbanded', value=details.get('disbanded'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(21898), 'yearsactive', value=get_joined_items(details.get('yearsactive')), type='array')
|
||||
|
||||
elif self.dbtype == 'album':
|
||||
self._create_list(ADDON.getLocalizedString(32023), 'albumlabel', value=details.get('albumlabel'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(21821), 'description', value=details.get('description'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(345), 'year', value=str(details.get('year')), type='integer')
|
||||
self._create_list(xbmc.getLocalizedString(467), 'type', value=details.get('type'), type='string')
|
||||
self._create_list(xbmc.getLocalizedString(515), 'genre', value=get_joined_items(details.get('genre')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(15111), 'theme', value=get_joined_items(details.get('theme')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(175), 'mood', value=get_joined_items(details.get('mood')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(736), 'style', value=get_joined_items(details.get('style')), type='array')
|
||||
self._create_list(xbmc.getLocalizedString(563), 'rating', value=str(get_rounded_value(details.get('rating'))), type='float')
|
||||
self._create_list(xbmc.getLocalizedString(205), 'votes', value=str(votes), type='integer')
|
||||
self._create_list(ADDON.getLocalizedString(32001), 'userrating', value=str(details.get('userrating')), type='userrating')
|
||||
|
||||
elif self.dbtype == 'song':
|
||||
self._create_list(xbmc.getLocalizedString(563), 'rating', value=str(get_rounded_value(details.get('rating'))), type='float')
|
||||
#self._create_list(xbmc.getLocalizedString(205), 'votes', value=str(details.get('votes')), type='integer') not available in methods.json? DaveBlake will fix it.
|
||||
self._create_list(ADDON.getLocalizedString(32001), 'userrating', value=str(details.get('userrating')), type='userrating')
|
||||
self._create_list(xbmc.getLocalizedString(568), 'lastplayed', value=details.get('lastplayed'), type='datetime')
|
||||
self._create_list(xbmc.getLocalizedString(567), 'playcount', value=str(details.get('playcount', 0)), type='integer')
|
||||
|
||||
def _create_list(self,label,key,type,value,option=None):
|
||||
if type in ['uniqueid', 'status', 'movieset']:
|
||||
icon = 'string'
|
||||
elif type == ('userrating'):
|
||||
icon = 'integer'
|
||||
elif type.startswith('date'):
|
||||
icon = 'date'
|
||||
elif type.startswith('rating'):
|
||||
icon = 'float'
|
||||
else:
|
||||
icon = type
|
||||
|
||||
li_item = xbmcgui.ListItem(label=label, label2='n/a' if not value else value)
|
||||
li_item.setArt({'icon': 'special://home/addons/script.metadata.editor/resources/media/icon_%s.png' % icon})
|
||||
|
||||
self.modeselect.append(li_item)
|
||||
self.keylist.append(key)
|
||||
self.typelist.append(type)
|
||||
self.optionlist.append(option)
|
||||
self.presetlist.append('' if not value else value)
|
||||
|
||||
def _handle_dbitem(self,key,value_type,preset=None,option=None):
|
||||
if preset:
|
||||
preset = preset.replace('n/a','')
|
||||
|
||||
if value_type == 'array':
|
||||
value = set_array(self.dbtype, key, preset)
|
||||
|
||||
elif value_type == 'select':
|
||||
value = modify_array(self.dbtype, key, preset)
|
||||
|
||||
elif value_type == 'string':
|
||||
value = set_string(preset)
|
||||
|
||||
elif value_type == 'integer':
|
||||
value = set_integer(preset)
|
||||
|
||||
elif value_type == 'float':
|
||||
value = set_float(preset)
|
||||
|
||||
elif value_type == 'date':
|
||||
value = set_date(preset)
|
||||
|
||||
elif value_type == 'datetime':
|
||||
preset = preset.split(' ') if preset else ['', '']
|
||||
date = set_date(preset[0])
|
||||
time = set_time(preset[1][:-3])
|
||||
value = date + ' ' + time + ':00'
|
||||
|
||||
elif value_type == 'userrating':
|
||||
value = set_integer_range(preset, 11)
|
||||
|
||||
elif value_type == 'ratings':
|
||||
value = set_ratings(option)
|
||||
|
||||
elif value_type == 'status':
|
||||
value = set_status(preset)
|
||||
self.status = value
|
||||
|
||||
elif value_type == 'watchlist':
|
||||
value = toggle_tag(preset)
|
||||
|
||||
elif value_type == 'movieset':
|
||||
value = set_movieset(preset)
|
||||
|
||||
elif value_type == ('uniqueid'):
|
||||
returned_value = set_string(preset)
|
||||
returned_value_json = returned_value if returned_value else None
|
||||
returned_value_str = returned_value if returned_value else ''
|
||||
|
||||
uniqueid_key = option.get('type')
|
||||
uniqueids = option.get('uniqueids')
|
||||
|
||||
value = {uniqueid_key: returned_value_json}
|
||||
|
||||
# build nfo info
|
||||
updated_dict = {}
|
||||
for item in uniqueids:
|
||||
if item == uniqueid_key:
|
||||
updated_dict[item] = returned_value_json
|
||||
else:
|
||||
updated_dict[item] = uniqueids.get(item)
|
||||
|
||||
if uniqueid_key not in updated_dict:
|
||||
updated_dict[uniqueid_key] = returned_value_str
|
||||
|
||||
nfo_value = [updated_dict, option.get('episodeguide')]
|
||||
|
||||
self.db.write(key=key, value=value)
|
||||
@@ -0,0 +1,321 @@
|
||||
#!/usr/bin/python
|
||||
# coding: utf-8
|
||||
|
||||
########################
|
||||
|
||||
from resources.lib.helper import *
|
||||
from resources.lib.database import *
|
||||
|
||||
########################
|
||||
|
||||
def set_ratings(ratings):
|
||||
providerlist = []
|
||||
for item in ratings:
|
||||
providerlist.append(str(item))
|
||||
|
||||
preselect = -1
|
||||
for item in providerlist:
|
||||
if ratings[item].get('default'):
|
||||
preselect = providerlist.index(item)
|
||||
|
||||
menu = DIALOG.select(xbmc.getLocalizedString(424), [ADDON.getLocalizedString(32015), ADDON.getLocalizedString(32016), ADDON.getLocalizedString(32017)])
|
||||
|
||||
if menu == 0: # set default provider
|
||||
providerdefault = DIALOG.select(ADDON.getLocalizedString(32014), providerlist, preselect=preselect)
|
||||
|
||||
if providerdefault >= 0:
|
||||
name = providerlist[providerdefault]
|
||||
|
||||
for item in ratings:
|
||||
default = True if item == name else False
|
||||
ratings[item] = {'default': default,
|
||||
'rating': ratings[item].get('rating'),
|
||||
'votes': ratings[item].get('votes')}
|
||||
|
||||
elif menu == 1: # edit votes/rating
|
||||
providerratings = DIALOG.select(ADDON.getLocalizedString(32012), providerlist, preselect=preselect)
|
||||
|
||||
if providerratings >= 0:
|
||||
name = providerlist[providerratings]
|
||||
cur_rating = round(ratings[name].get('rating', 0.0), 1)
|
||||
cur_votes = ratings[name].get('votes', 0)
|
||||
|
||||
rating = set_float(cur_rating)
|
||||
votes = set_integer(cur_votes)
|
||||
|
||||
if not rating:
|
||||
rating = 0.0
|
||||
|
||||
if not votes:
|
||||
votes = 0
|
||||
|
||||
ratings[name] = {'default': ratings[name].get('default'),
|
||||
'rating': rating,
|
||||
'votes': votes}
|
||||
|
||||
elif menu == 2: # add new rating provider
|
||||
supportedlist = ['imdb', 'themoviedb', 'tomatometerallcritics', 'tomatometeravgcritics', 'tomatometerallaudience', 'tomatometeravgaudience', 'metacritic']
|
||||
|
||||
for item in supportedlist:
|
||||
if item in providerlist:
|
||||
supportedlist.remove(item)
|
||||
|
||||
newprovider = DIALOG.select(ADDON.getLocalizedString(32013), supportedlist)
|
||||
|
||||
if newprovider >= 0:
|
||||
name = supportedlist[newprovider]
|
||||
rating = set_float(heading='Enter rating (floating number - min 0.1 / max 10.0)')
|
||||
|
||||
if not rating or float(rating) > 10:
|
||||
DIALOG.ok(xbmc.getLocalizedString(257), ADDON.getLocalizedString(32018))
|
||||
|
||||
else:
|
||||
votes = set_integer()
|
||||
if not votes:
|
||||
votes = 0
|
||||
|
||||
if not DIALOG.yesno(ADDON.getLocalizedString(32019), ADDON.getLocalizedString(32020)):
|
||||
default = False
|
||||
else:
|
||||
default = True
|
||||
|
||||
for item in ratings:
|
||||
ratings[item] = {'default': False,
|
||||
'rating': ratings[item].get('rating'),
|
||||
'votes': ratings[item].get('votes')}
|
||||
|
||||
ratings[name] = {'default': default,
|
||||
'rating': rating,
|
||||
'votes': votes}
|
||||
|
||||
return ratings
|
||||
|
||||
def set_movieset(preset):
|
||||
db = Database()
|
||||
db.sets()
|
||||
sets = db.result().get('set', [])
|
||||
|
||||
selectlist = []
|
||||
for item in sets:
|
||||
selectlist.append(item.get('title'))
|
||||
selectlist.sort()
|
||||
selectlist.insert(0, xbmc.getLocalizedString(231))
|
||||
selectlist.insert(1, ADDON.getLocalizedString(32005))
|
||||
|
||||
preselect = selectlist.index(preset) if preset in selectlist else -1
|
||||
|
||||
selectdialog = DIALOG.select(xbmc.getLocalizedString(20466), selectlist, preselect=preselect)
|
||||
|
||||
if selectdialog == 0:
|
||||
return ''
|
||||
|
||||
elif selectdialog == 1:
|
||||
value = set_string()
|
||||
return value
|
||||
|
||||
elif selectdialog > 1:
|
||||
return selectlist[selectdialog]
|
||||
|
||||
return preset
|
||||
|
||||
def set_array(dbtype,key,preset):
|
||||
actionlist = [ADDON.getLocalizedString(32005), ADDON.getLocalizedString(32007), ADDON.getLocalizedString(32006)]
|
||||
array_action = DIALOG.select(xbmc.getLocalizedString(14241), actionlist)
|
||||
array_list = get_list_items(preset)
|
||||
|
||||
if array_action == 0:
|
||||
keyboard = xbmc.Keyboard()
|
||||
keyboard.doModal()
|
||||
|
||||
if keyboard.isConfirmed():
|
||||
new_item = keyboard.getText()
|
||||
|
||||
if new_item not in array_list:
|
||||
array_list.append(new_item)
|
||||
|
||||
return remove_empty(array_list)
|
||||
|
||||
elif array_action == 1:
|
||||
array = modify_array(dbtype, key, array_list)
|
||||
return array
|
||||
|
||||
elif array_action == 2:
|
||||
keyboard = xbmc.Keyboard(preset)
|
||||
keyboard.doModal()
|
||||
|
||||
if keyboard.isConfirmed():
|
||||
array = keyboard.getText()
|
||||
else:
|
||||
array = preset
|
||||
|
||||
return get_list_items(array)
|
||||
|
||||
else:
|
||||
return array_list
|
||||
|
||||
|
||||
def modify_array(dbtype,key,values):
|
||||
modified = []
|
||||
all_values = []
|
||||
|
||||
if not isinstance(values, list):
|
||||
values = get_list_items(values)
|
||||
|
||||
if key in ['genre', 'tags']:
|
||||
db = Database()
|
||||
getattr(db, key)()
|
||||
result = db.result()
|
||||
|
||||
if key == 'genre':
|
||||
if dbtype in ['musicvideo', 'artist', 'album']:
|
||||
for genre in result.get('audiogenres'):
|
||||
all_values.append(genre)
|
||||
else:
|
||||
for genre in result.get('videogenres'):
|
||||
all_values.append(genre)
|
||||
|
||||
elif key == 'tags':
|
||||
for tag in result.get('tags'):
|
||||
if tag not in values:
|
||||
all_values.append(tag)
|
||||
|
||||
all_values = list(set(values + all_values))
|
||||
all_values.sort()
|
||||
values.sort()
|
||||
|
||||
# open common array dialog if all_values are empty
|
||||
if not all_values:
|
||||
notification(ADDON.getLocalizedString(32000), ADDON.getLocalizedString(32048))
|
||||
value = set_array(dbtype, key, '')
|
||||
return value
|
||||
|
||||
preselectlist = []
|
||||
for item in values:
|
||||
preselectlist.append(all_values.index(item))
|
||||
|
||||
selectdialog = DIALOG.multiselect(ADDON.getLocalizedString(32002), all_values, preselect=preselectlist)
|
||||
|
||||
if selectdialog == -1 or selectdialog is None:
|
||||
return values
|
||||
|
||||
for index in selectdialog:
|
||||
modified.append(all_values[index])
|
||||
|
||||
return modified
|
||||
|
||||
|
||||
def set_integer(preset=''):
|
||||
preset = str(preset)
|
||||
if preset == '0':
|
||||
preset = ''
|
||||
|
||||
value = xbmcgui.Dialog().numeric(0, xbmc.getLocalizedString(16028), preset)
|
||||
|
||||
if not value:
|
||||
return None
|
||||
|
||||
return int(value)
|
||||
|
||||
|
||||
def set_float(preset='',heading=ADDON.getLocalizedString(32011)):
|
||||
try:
|
||||
preset = float(preset)
|
||||
preset = round(preset,1)
|
||||
|
||||
except Exception:
|
||||
preset = ''
|
||||
|
||||
keyboard = xbmc.Keyboard(str(preset))
|
||||
keyboard.setHeading(heading)
|
||||
keyboard.doModal()
|
||||
|
||||
if keyboard.isConfirmed():
|
||||
try:
|
||||
value = float(keyboard.getText())
|
||||
value = round(value,1)
|
||||
return value
|
||||
|
||||
except Exception:
|
||||
set_float(preset)
|
||||
|
||||
return preset
|
||||
|
||||
|
||||
def set_date(preset):
|
||||
try:
|
||||
conv = time.strptime(preset,'%Y-%m-%d')
|
||||
conv = time.strftime('%d/%m/%Y', conv)
|
||||
|
||||
except Exception:
|
||||
conv = '01/01/1900'
|
||||
|
||||
value = xbmcgui.Dialog().numeric(1, xbmc.getLocalizedString(16028), conv)
|
||||
|
||||
if value:
|
||||
value = value.replace(' ','0')
|
||||
value = time.strptime(value,'%d/%m/%Y')
|
||||
value = time.strftime('%Y-%m-%d',value)
|
||||
return value
|
||||
|
||||
return preset
|
||||
|
||||
|
||||
def set_time(preset):
|
||||
value = xbmcgui.Dialog().numeric(2, xbmc.getLocalizedString(16028), preset)
|
||||
|
||||
if value:
|
||||
return value
|
||||
|
||||
return preset
|
||||
|
||||
|
||||
def set_string(preset=''):
|
||||
value = preset.replace('\n', '[CR]')
|
||||
keyboard = xbmc.Keyboard(value)
|
||||
keyboard.doModal()
|
||||
|
||||
if keyboard.isConfirmed():
|
||||
value = keyboard.getText()
|
||||
|
||||
return value.replace('[CR]', '\n')
|
||||
|
||||
|
||||
def set_integer_range(preset, maximum):
|
||||
preset = int(preset) if preset else 0
|
||||
rangelist = []
|
||||
|
||||
for i in range(0, maximum):
|
||||
rangelist.append(str(i))
|
||||
|
||||
value = DIALOG.select(xbmc.getLocalizedString(424), rangelist, preselect=preset)
|
||||
|
||||
if value >= 0:
|
||||
return value
|
||||
|
||||
return preset
|
||||
|
||||
|
||||
def set_status(preset):
|
||||
statuslist = ['Returning series', 'In production', 'Planned', 'Cancelled', 'Ended']
|
||||
|
||||
if preset == ADDON.getLocalizedString(32022):
|
||||
preset = ''
|
||||
|
||||
value = DIALOG.select(xbmc.getLocalizedString(126), statuslist)
|
||||
|
||||
if value >= 0:
|
||||
return statuslist[value]
|
||||
|
||||
return preset
|
||||
|
||||
|
||||
def toggle_tag(preset):
|
||||
tag = 'Watchlist'
|
||||
tags = get_list_items(preset)
|
||||
|
||||
if tag in tags:
|
||||
tags.remove(tag)
|
||||
else:
|
||||
tags.append(tag)
|
||||
|
||||
return tags
|
||||
@@ -0,0 +1,250 @@
|
||||
#!/usr/bin/python
|
||||
# coding: utf-8
|
||||
|
||||
########################
|
||||
|
||||
import sys
|
||||
import xbmc
|
||||
import xbmcaddon
|
||||
import xbmcgui
|
||||
import xbmcvfs
|
||||
import xbmcplugin
|
||||
import json
|
||||
import time
|
||||
import datetime
|
||||
import os
|
||||
import hashlib
|
||||
import xml.etree.ElementTree as ET
|
||||
import requests
|
||||
import urllib.request as urllib
|
||||
from urllib.parse import urlencode
|
||||
from contextlib import contextmanager
|
||||
|
||||
########################
|
||||
|
||||
ADDON = xbmcaddon.Addon()
|
||||
ADDON_ID = ADDON.getAddonInfo('id')
|
||||
ADDON_DATA_PATH = os.path.join(xbmcvfs.translatePath("special://profile/addon_data/%s" % ADDON_ID))
|
||||
|
||||
NOTICE = xbmc.LOGINFO
|
||||
WARNING = xbmc.LOGWARNING
|
||||
DEBUG = xbmc.LOGDEBUG
|
||||
ERROR = xbmc.LOGERROR
|
||||
LOG_JSON = ADDON.getSettingBool('json_log')
|
||||
KODI_VERSION = int(xbmc.getInfoLabel('System.BuildVersion')[:2])
|
||||
|
||||
DIALOG = xbmcgui.Dialog()
|
||||
|
||||
########################
|
||||
|
||||
|
||||
def log(txt,loglevel=DEBUG,json=False,force=False):
|
||||
if loglevel in [DEBUG, WARNING, ERROR] or force:
|
||||
if force:
|
||||
loglevel = NOTICE
|
||||
|
||||
if json:
|
||||
txt = json_prettyprint(txt)
|
||||
|
||||
message = u'[ %s ] %s' % (ADDON_ID,txt)
|
||||
xbmc.log(msg=message, level=loglevel)
|
||||
|
||||
|
||||
def unicode_string(string):
|
||||
string = u'%s' % string
|
||||
return string
|
||||
|
||||
|
||||
def remove_quotes(label):
|
||||
if not label:
|
||||
return ''
|
||||
|
||||
if label.startswith("'") and label.endswith("'") and len(label) > 2:
|
||||
label = label[1:-1]
|
||||
if label.startswith('"') and label.endswith('"') and len(label) > 2:
|
||||
label = label[1:-1]
|
||||
elif label.startswith('"') and label.endswith('"'):
|
||||
label = label[6:-6]
|
||||
|
||||
return label
|
||||
|
||||
|
||||
def get_joined_items(item):
|
||||
if len(item) > 0 and item is not None:
|
||||
item = '; '.join(item)
|
||||
item = item + ';'
|
||||
else:
|
||||
item = ''
|
||||
|
||||
return item
|
||||
|
||||
|
||||
def get_list_items(string):
|
||||
return remove_empty(string.replace('; ',';').split(';'))
|
||||
|
||||
|
||||
def get_key_item(items,key):
|
||||
try:
|
||||
return items.get(key)
|
||||
except Exception:
|
||||
return
|
||||
|
||||
|
||||
def get_rounded_value(value):
|
||||
try:
|
||||
if not isinstance(value, str) and not isinstance(value, float):
|
||||
value = str(value)
|
||||
if not isinstance(value, float):
|
||||
value = float(value)
|
||||
|
||||
return round(value,1)
|
||||
|
||||
except Exception:
|
||||
return
|
||||
|
||||
|
||||
def remove_empty(array):
|
||||
cleaned_array = []
|
||||
|
||||
for item in array:
|
||||
if not item or item in ['', ';']:
|
||||
continue
|
||||
cleaned_array.append(item)
|
||||
|
||||
return cleaned_array
|
||||
|
||||
|
||||
def execute(cmd):
|
||||
xbmc.executebuiltin(cmd)
|
||||
|
||||
|
||||
def condition(condition):
|
||||
return xbmc.getCondVisibility(condition)
|
||||
|
||||
|
||||
def winprop(key, value=None, clear=False, window_id=10000):
|
||||
window = xbmcgui.Window(window_id)
|
||||
|
||||
if clear:
|
||||
window.clearProperty(key.replace('.json', '').replace('.bool', '').replace('.str', ''))
|
||||
|
||||
elif value is not None:
|
||||
|
||||
if key.endswith('.json'):
|
||||
key = key.replace('.json', '')
|
||||
value = json.dumps(value)
|
||||
|
||||
elif key.endswith('.bool'):
|
||||
key = key.replace('.bool', '')
|
||||
value = 'true' if value else 'false'
|
||||
|
||||
elif key.endswith('.str'):
|
||||
key = key.replace('.str', '')
|
||||
value = str(value)
|
||||
|
||||
window.setProperty(key, value)
|
||||
|
||||
else:
|
||||
result = window.getProperty(key.replace('.json', '').replace('.bool', '').replace('.str', ''))
|
||||
|
||||
if result:
|
||||
if key.endswith('.json'):
|
||||
result = json.loads(result)
|
||||
|
||||
elif key.endswith('.bool'):
|
||||
result = result in ('true', '1')
|
||||
|
||||
elif key.endswith('.str'):
|
||||
result = eval(result)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def json_call(method,properties=None,sort=None,query_filter=None,limit=None,params=None,item=None,options=None,limits=None,debug=False):
|
||||
json_string = {'jsonrpc': '2.0', 'id': 1, 'method': method, 'params': {}}
|
||||
|
||||
if properties is not None:
|
||||
json_string['params']['properties'] = properties
|
||||
|
||||
if limit is not None:
|
||||
json_string['params']['limits'] = {'start': 0, 'end': int(limit)}
|
||||
|
||||
if sort is not None:
|
||||
json_string['params']['sort'] = sort
|
||||
|
||||
if query_filter is not None:
|
||||
json_string['params']['filter'] = query_filter
|
||||
|
||||
if options is not None:
|
||||
json_string['params']['options'] = options
|
||||
|
||||
if limits is not None:
|
||||
json_string['params']['limits'] = limits
|
||||
|
||||
if item is not None:
|
||||
json_string['params']['item'] = item
|
||||
|
||||
if params is not None:
|
||||
json_string['params'].update(params)
|
||||
|
||||
jsonrpc_call = json.dumps(json_string)
|
||||
|
||||
result = xbmc.executeJSONRPC(jsonrpc_call)
|
||||
result = json.loads(result)
|
||||
|
||||
if debug:
|
||||
log('--> JSON CALL: ' + json_prettyprint(json_string), force=True)
|
||||
log('--> JSON RESULT: ' + json_prettyprint(result), force=True)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def json_prettyprint(string):
|
||||
return json.dumps(string, sort_keys=True, indent=4, separators=(',', ': '))
|
||||
|
||||
|
||||
def xml_prettyprint(root,level=0):
|
||||
i = '\n' + level * ' '
|
||||
|
||||
if len(root):
|
||||
if not root.text or not root.text.strip():
|
||||
root.text = i + ' '
|
||||
|
||||
if not root.tail or not root.tail.strip():
|
||||
root.tail = i
|
||||
|
||||
for root in root:
|
||||
xml_prettyprint(root, level+1)
|
||||
|
||||
if not root.tail or not root.tail.strip():
|
||||
root.tail = i
|
||||
|
||||
else:
|
||||
if level and (not root.tail or not root.tail.strip()):
|
||||
root.tail = i
|
||||
|
||||
|
||||
def notification(header=ADDON.getLocalizedString(32000),message=''):
|
||||
DIALOG.notification(header, message, icon='special://home/addons/script.metadata.editor/resources/icon.png')
|
||||
|
||||
|
||||
def reload_widgets():
|
||||
# Notifies script.embuary.helper to reload widgets
|
||||
execute('NotifyAll(%s,Finished)' % ADDON_ID)
|
||||
|
||||
|
||||
@contextmanager
|
||||
def busy_dialog(force=False):
|
||||
if force:
|
||||
execute('ActivateWindow(busydialognocancel)')
|
||||
|
||||
elif not winprop('UpdatingRatings.bool'):
|
||||
# NFO writing usually only takes < 1s. Just show BusyDialog if it takes longer for whatever reason.
|
||||
execute('AlarmClock(BusyAlarmDelay,ActivateWindow(busydialognocancel),00:02,silent)')
|
||||
|
||||
try:
|
||||
yield
|
||||
|
||||
finally:
|
||||
execute('CancelAlarm(BusyAlarmDelay,silent)')
|
||||
execute('Dialog.Close(busydialognocancel)')
|
||||
@@ -0,0 +1,267 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
JSON_MAP = {
|
||||
'movie_properties': [
|
||||
'title',
|
||||
'originaltitle',
|
||||
'sorttitle',
|
||||
'votes',
|
||||
'playcount',
|
||||
'year',
|
||||
'genre',
|
||||
'studio',
|
||||
'country',
|
||||
'tagline',
|
||||
'tag',
|
||||
'plot',
|
||||
'runtime',
|
||||
'premiered',
|
||||
'file',
|
||||
'plotoutline',
|
||||
'lastplayed',
|
||||
'trailer',
|
||||
'rating',
|
||||
'ratings',
|
||||
'userrating',
|
||||
'resume',
|
||||
'art',
|
||||
'mpaa',
|
||||
'director',
|
||||
'writer',
|
||||
'cast',
|
||||
'set',
|
||||
'setid',
|
||||
'top250',
|
||||
'dateadded',
|
||||
'imdbnumber',
|
||||
'uniqueid'
|
||||
],
|
||||
|
||||
'movies_properties': [
|
||||
'title',
|
||||
'year'
|
||||
],
|
||||
|
||||
'set_properties': [
|
||||
'title',
|
||||
'plot'
|
||||
],
|
||||
|
||||
'sets_properties': [
|
||||
'title'
|
||||
],
|
||||
|
||||
'episode_properties': [
|
||||
'title',
|
||||
'playcount',
|
||||
'season',
|
||||
'episode',
|
||||
'showtitle',
|
||||
'originaltitle',
|
||||
'plot',
|
||||
'votes',
|
||||
'file',
|
||||
'rating',
|
||||
'ratings',
|
||||
'userrating',
|
||||
'resume',
|
||||
'tvshowid',
|
||||
'firstaired',
|
||||
'art',
|
||||
'runtime',
|
||||
'director',
|
||||
'writer',
|
||||
'cast',
|
||||
'dateadded',
|
||||
'lastplayed',
|
||||
'uniqueid'
|
||||
],
|
||||
|
||||
'episodes_properties': [
|
||||
'title',
|
||||
'showtitle'
|
||||
],
|
||||
|
||||
'season_properties': [
|
||||
'season',
|
||||
'episode',
|
||||
'art',
|
||||
'userrating',
|
||||
'watchedepisodes',
|
||||
'showtitle',
|
||||
'playcount',
|
||||
'tvshowid'
|
||||
],
|
||||
|
||||
'seasons_properties': [
|
||||
'season',
|
||||
'showtitle',
|
||||
'tvshowid'
|
||||
],
|
||||
|
||||
'tvshow_properties': [
|
||||
'title',
|
||||
'studio',
|
||||
'year',
|
||||
'plot',
|
||||
'cast',
|
||||
'rating',
|
||||
'ratings',
|
||||
'userrating',
|
||||
'votes',
|
||||
'file',
|
||||
'genre',
|
||||
'episode',
|
||||
'season',
|
||||
'runtime',
|
||||
'mpaa',
|
||||
'premiered',
|
||||
'playcount',
|
||||
'lastplayed',
|
||||
'sorttitle',
|
||||
'originaltitle',
|
||||
'episodeguide',
|
||||
'art',
|
||||
'tag',
|
||||
'dateadded',
|
||||
'watchedepisodes',
|
||||
'imdbnumber',
|
||||
'uniqueid'
|
||||
],
|
||||
|
||||
'tvshows_properties': [
|
||||
'title',
|
||||
'year'
|
||||
],
|
||||
|
||||
'musicvideo_properties': [
|
||||
'title',
|
||||
'playcount',
|
||||
'runtime',
|
||||
'director',
|
||||
'studio',
|
||||
'year',
|
||||
'plot',
|
||||
'album',
|
||||
'artist',
|
||||
'genre',
|
||||
'track',
|
||||
'lastplayed',
|
||||
'fanart',
|
||||
'thumbnail',
|
||||
'file',
|
||||
'resume',
|
||||
'dateadded',
|
||||
'tag',
|
||||
'art',
|
||||
'rating',
|
||||
'userrating',
|
||||
'premiered'
|
||||
],
|
||||
|
||||
'musicvideos_properties': [
|
||||
'title',
|
||||
'year'
|
||||
],
|
||||
|
||||
'artist_properties': [
|
||||
'instrument',
|
||||
'style',
|
||||
'mood',
|
||||
'born',
|
||||
'formed',
|
||||
'description',
|
||||
'genre',
|
||||
'died',
|
||||
'disbanded',
|
||||
'yearsactive',
|
||||
'musicbrainzartistid',
|
||||
'fanart',
|
||||
'thumbnail',
|
||||
'compilationartist',
|
||||
'dateadded',
|
||||
'roles',
|
||||
'songgenres',
|
||||
'isalbumartist',
|
||||
'disambiguation'
|
||||
],
|
||||
|
||||
'artists_properties': [
|
||||
'dateadded'
|
||||
],
|
||||
|
||||
'album_properties': [
|
||||
'title',
|
||||
'description',
|
||||
'artist',
|
||||
'genre',
|
||||
'theme',
|
||||
'mood',
|
||||
'style',
|
||||
'type',
|
||||
'albumlabel',
|
||||
'rating',
|
||||
'votes',
|
||||
'userrating',
|
||||
'year',
|
||||
'musicbrainzalbumid',
|
||||
'musicbrainzalbumartistid',
|
||||
'fanart',
|
||||
'thumbnail',
|
||||
'playcount',
|
||||
'artistid',
|
||||
'displayartist',
|
||||
'compilation',
|
||||
'releasetype',
|
||||
'dateadded'
|
||||
],
|
||||
|
||||
'albums_properties': [
|
||||
'title',
|
||||
'year'
|
||||
],
|
||||
|
||||
'song_properties': [
|
||||
'title',
|
||||
'artist',
|
||||
'albumartist',
|
||||
'genre',
|
||||
'year',
|
||||
'rating',
|
||||
'album',
|
||||
'track',
|
||||
'duration',
|
||||
'comment',
|
||||
'lyrics',
|
||||
'musicbrainztrackid',
|
||||
'musicbrainzartistid',
|
||||
'musicbrainzalbumid',
|
||||
'musicbrainzalbumartistid',
|
||||
'playcount',
|
||||
'fanart',
|
||||
'thumbnail',
|
||||
'file',
|
||||
'albumid',
|
||||
'lastplayed',
|
||||
'disc',
|
||||
'genreid',
|
||||
'artistid',
|
||||
'displayartist',
|
||||
'albumartistid',
|
||||
'albumreleasetype',
|
||||
'dateadded',
|
||||
'votes',
|
||||
'userrating',
|
||||
'mood',
|
||||
'contributors',
|
||||
'displaycomposer',
|
||||
'displayconductor',
|
||||
'displayorchestra',
|
||||
'displaylyricist'
|
||||
],
|
||||
|
||||
'songs_properties': [
|
||||
'title',
|
||||
'artist'
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
#!/usr/bin/python
|
||||
# coding: utf-8
|
||||
|
||||
########################
|
||||
|
||||
from resources.lib.helper import *
|
||||
from resources.lib.database import *
|
||||
|
||||
########################
|
||||
|
||||
def update_nfo(dbtype,dbid,details=None,file=None, forced=False):
|
||||
if not forced and not ADDON.getSettingBool('nfo_updating'):
|
||||
winprop('updatenfo', clear=True)
|
||||
return
|
||||
|
||||
if not details:
|
||||
db = Database(dbid, dbtype)
|
||||
getattr(db, dbtype)()
|
||||
details = db.result().get(dbtype)[0]
|
||||
|
||||
if not details:
|
||||
log('NFO updater: No item details found or provided --> ID: %s Type: %s' % (dbid, dbtype), ERROR)
|
||||
return
|
||||
|
||||
if not file:
|
||||
file = details.get('file')
|
||||
if not file:
|
||||
log('NFO updater: No item path available --> ID: %s Type: %s' % (dbid, dbtype), ERROR)
|
||||
return
|
||||
|
||||
if dbtype == 'tvshow':
|
||||
path = os.path.join(file,'tvshow.nfo')
|
||||
else:
|
||||
path = file.replace(os.path.splitext(file)[1], '.nfo')
|
||||
|
||||
UpdateNFO(file=path,
|
||||
dbtype=dbtype,
|
||||
dbid=dbid,
|
||||
details=details)
|
||||
|
||||
# support for additional movie.nfo
|
||||
if dbtype == 'movie':
|
||||
path = file.replace(os.path.basename(file), 'movie.nfo')
|
||||
|
||||
if xbmcvfs.exists(path):
|
||||
UpdateNFO(file=path,
|
||||
dbtype=dbtype,
|
||||
dbid=dbid,
|
||||
details=details)
|
||||
|
||||
|
||||
class UpdateNFO():
|
||||
def __init__(self,file,dbtype,dbid,details):
|
||||
self.targetfile = file
|
||||
self.dbtype = dbtype
|
||||
self.dbid = dbid
|
||||
self.details = details
|
||||
self.root = None
|
||||
self.sortlist = []
|
||||
self.run()
|
||||
|
||||
def run(self):
|
||||
with busy_dialog():
|
||||
try:
|
||||
if xbmcvfs.exists(self.targetfile):
|
||||
self.root = self.read_file()
|
||||
self.existing_nfo = True
|
||||
|
||||
elif ADDON.getSettingBool('create_nfo'):
|
||||
self.root = ET.Element(self.dbtype.replace('episode', 'episodedetails'))
|
||||
self.existing_nfo = False
|
||||
|
||||
else:
|
||||
raise Exception('File not found')
|
||||
|
||||
self.handle_details()
|
||||
self.write_file()
|
||||
success = True
|
||||
|
||||
except Exception as error:
|
||||
log('Cannot process .nfo file: %s --> %s' % (self.targetfile, error), ERROR)
|
||||
success = False
|
||||
|
||||
if winprop('updatenfo.bool'):
|
||||
msg = xbmc.getLocalizedString(20177) if success else xbmc.getLocalizedString(257)
|
||||
notification(ADDON.getLocalizedString(32046), msg)
|
||||
winprop('updatenfo', clear=True)
|
||||
|
||||
def read_file(self):
|
||||
file = xbmcvfs.File(self.targetfile)
|
||||
content = file.read()
|
||||
file.close()
|
||||
|
||||
if content:
|
||||
tree = ET.ElementTree(ET.fromstring(content))
|
||||
root = tree.getroot()
|
||||
return root
|
||||
|
||||
def write_file(self):
|
||||
# sort nfo
|
||||
if self.existing_nfo:
|
||||
index = 0
|
||||
for key in self.sortlist:
|
||||
for elem in self.root.findall(key):
|
||||
self.root.remove(elem)
|
||||
self.root.insert(index, elem)
|
||||
index += 1
|
||||
|
||||
xml_prettyprint(self.root)
|
||||
|
||||
content = ET.tostring(self.root, encoding='UTF8', method='xml').decode()
|
||||
|
||||
with xbmcvfs.File(self.targetfile, 'w') as f:
|
||||
result = f.write(content)
|
||||
|
||||
def handle_details(self):
|
||||
li = [{'key': 'title', 'value': self.details.get('title')},
|
||||
{'key': 'originaltitle', 'value': self.details.get('originaltitle')},
|
||||
{'key': 'showtitle', 'value': self.details.get('showtitle')},
|
||||
{'key': 'sorttitle', 'value': self.details.get('sorttitle')},
|
||||
{'key': 'userrating', 'value': self.details.get('userrating')},
|
||||
{'key': 'outline', 'value': self.details.get('plotoutline')},
|
||||
{'key': 'plot', 'value': self.details.get('plot')},
|
||||
{'key': 'tagline', 'value': self.details.get('tagline')},
|
||||
{'key': 'mpaa', 'value': self.details.get('mpaa')},
|
||||
{'key': 'premiered', 'value': self.details.get('premiered')},
|
||||
{'key': 'releasedate', 'value': self.details.get('releasedate')}, #emby
|
||||
{'key': 'year', 'value': self.details.get('premiered', '')[:4]}, #emby
|
||||
{'key': 'country', 'value': self.details.get('country')},
|
||||
{'key': 'studio', 'value': self.details.get('studio')},
|
||||
{'key': 'director', 'value': self.details.get('director')},
|
||||
{'key': 'credits', 'value': self.details.get('writer')},
|
||||
{'key': 'writer', 'value': self.details.get('writer')}, #emby
|
||||
{'key': 'tag', 'value': self.details.get('tag')},
|
||||
{'key': 'isuserfavorite', 'value': 'true' if 'Favorite movies' in self.details.get('tag', []) or 'Favorite tvshows' in self.details.get('tag', []) else 'false'}, #emby
|
||||
{'key': 'genre', 'value': self.details.get('genre')},
|
||||
{'key': 'top250', 'value': self.details.get('top250')},
|
||||
{'key': 'ratings', 'value': self.details.get('ratings')},
|
||||
{'key': 'uniqueid', 'value': self.details.get('uniqueid')},
|
||||
{'key': 'status', 'value': self.details.get('status')},
|
||||
{'key': 'aired', 'value': self.details.get('firstaired')},
|
||||
{'key': 'dateadded', 'value': self.details.get('dateadded')}
|
||||
]
|
||||
|
||||
if ADDON.getSettingBool('write_watched_stated'):
|
||||
li.append({'key': 'playcount', 'value': self.details.get('playcount')})
|
||||
li.append({'key': 'watched', 'value': 'true' if self.details.get('playcount', 0) > 0 else 'false'}) #emby
|
||||
li.append({'key': 'lastplayed', 'value': self.details.get('lastplayed')})
|
||||
|
||||
for item in li:
|
||||
key = item.get('key')
|
||||
value = item.get('value')
|
||||
self.sortlist.append(key)
|
||||
|
||||
if key == 'ratings':
|
||||
self.handle_ratings(value)
|
||||
|
||||
elif key == 'uniqueid':
|
||||
self.handle_uniqueid(value, self.details.get('episodeguide', ''))
|
||||
|
||||
else:
|
||||
self.handle_elem(key, value)
|
||||
|
||||
def handle_elem(self,key,value):
|
||||
if key != 'status' or (key == 'status' and value): # Keep status value. Required for leia because status isn't returned thru json.
|
||||
for elem in self.root.findall(key):
|
||||
self.root.remove(elem)
|
||||
|
||||
if isinstance(value, list):
|
||||
for i in value:
|
||||
if i:
|
||||
elem = ET.SubElement(self.root, key)
|
||||
elem.text = unicode_string(i)
|
||||
|
||||
elif value:
|
||||
elem = ET.SubElement(self.root, key)
|
||||
elem.text = unicode_string(value)
|
||||
|
||||
def handle_ratings(self,value):
|
||||
for elem in self.root.findall('ratings'):
|
||||
self.root.remove(elem)
|
||||
|
||||
elem = ET.SubElement(self.root, 'ratings')
|
||||
for item in value:
|
||||
rating = float(value[item].get('rating', 0.0))
|
||||
rating = str(round(rating, 1))
|
||||
votes = str(value[item].get('votes', 0))
|
||||
|
||||
subelem = ET.SubElement(elem, 'rating')
|
||||
subelem.set('name', item)
|
||||
subelem.set('max', '10')
|
||||
|
||||
if value[item].get('default'):
|
||||
subelem.set('default', 'true')
|
||||
|
||||
# Emby <votes>, <rating>
|
||||
for key in ['rating', 'votes']:
|
||||
for defaultelem in self.root.findall(key):
|
||||
self.root.remove(defaultelem)
|
||||
|
||||
defaultelem = ET.SubElement(self.root, key)
|
||||
defaultelem.text = eval(key)
|
||||
|
||||
self.sortlist.append(key)
|
||||
|
||||
else:
|
||||
subelem.set('default', 'false')
|
||||
|
||||
rating_elem = ET.SubElement(subelem, 'value')
|
||||
rating_elem.text = rating
|
||||
|
||||
votes_elem = ET.SubElement(subelem, 'votes')
|
||||
votes_elem.text = votes
|
||||
|
||||
# Emby <criticrating> Rotten ratings
|
||||
if item == 'tomatometerallcritics':
|
||||
normalized_rating = int(float(rating) * 10)
|
||||
if normalized_rating > 100:
|
||||
normalized_rating = ''
|
||||
|
||||
for emby_elem in self.root.findall('criticrating'):
|
||||
self.root.remove(emby_elem)
|
||||
|
||||
emby_rotten = ET.SubElement(self.root, 'criticrating')
|
||||
emby_rotten.text = str(normalized_rating)
|
||||
|
||||
self.sortlist.append('criticrating')
|
||||
|
||||
def handle_uniqueid(self,uniqueids,episodeguide):
|
||||
# find default uniqueid
|
||||
default = ''
|
||||
if 'tvdb' in episodeguide:
|
||||
default = 'tvdb'
|
||||
elif 'tmdb' in episodeguide:
|
||||
default = 'tmdb'
|
||||
else:
|
||||
for elem in self.root.findall('uniqueid'):
|
||||
if elem.get('default'):
|
||||
default = elem.get('type')
|
||||
break
|
||||
|
||||
# set fallback default uniqueid
|
||||
if not default:
|
||||
if self.dbtype == 'movie':
|
||||
if uniqueids.get('tmdb'):
|
||||
default = 'tmdb'
|
||||
elif uniqueids.get('imdb'):
|
||||
default = 'imdb'
|
||||
|
||||
elif self.dbtype == 'tvshow':
|
||||
scraper_default = ADDON.getSetting('tv_scraper_base')
|
||||
|
||||
if (scraper_default == 'TVDb' and uniqueids.get('tvdb')):
|
||||
default = 'tvdb'
|
||||
elif scraper_default == 'TMDb' and uniqueids.get('tmdb'):
|
||||
default = 'tmdb'
|
||||
|
||||
# <uniqueid> fields
|
||||
for elem in self.root.findall('uniqueid'):
|
||||
self.root.remove(elem)
|
||||
|
||||
for item in uniqueids:
|
||||
value = uniqueids.get(item, '')
|
||||
|
||||
if value:
|
||||
elem = ET.SubElement(self.root, 'uniqueid')
|
||||
elem.set('type', item)
|
||||
elem.text = value
|
||||
|
||||
if default == item:
|
||||
elem.set('default', 'true')
|
||||
if self.dbtype == 'tvshow':
|
||||
self._set_episodeguide(item, value)
|
||||
|
||||
self.sortlist.append(item)
|
||||
|
||||
# Emby <imdbid>, <tmdbid>, etc.
|
||||
emby_uniqueids = {}
|
||||
for item in uniqueids:
|
||||
if item == 'imdb':
|
||||
emby_uniqueids['imdbid'] = uniqueids.get(item)
|
||||
emby_uniqueids['imdb_id'] = uniqueids.get(item) # emby is using a underscore for tvshows Oo
|
||||
|
||||
elif item == 'tmdbcollection':
|
||||
emby_uniqueids['collectionnumber'] = uniqueids.get(item)
|
||||
|
||||
elif item.lower() in ['zap2it', 'tvrage', 'tvdb', 'tmdb']:
|
||||
emby_uniqueids['%sid' % item] = uniqueids.get(item)
|
||||
|
||||
for item in emby_uniqueids:
|
||||
for elem in self.root.findall(item):
|
||||
self.root.remove(elem)
|
||||
|
||||
value = emby_uniqueids.get(item)
|
||||
|
||||
if value:
|
||||
elem = ET.SubElement(self.root, item)
|
||||
elem.text = value
|
||||
|
||||
self.sortlist.append(item)
|
||||
|
||||
def _set_episodeguide(self,type,value):
|
||||
post = False
|
||||
cache = ''
|
||||
|
||||
if type == 'tvdb':
|
||||
post = 'yes'
|
||||
cache = 'auth.json'
|
||||
url = 'https://api.thetvdb.com/login?{"apikey":"439DFEBA9D3059C6","id":%s}|Content-Type=application/json' % str(value)
|
||||
json_value = '<episodeguide><url post="%s" cache="%s"><url>%s</url></episodeguide>' % (post, cache, url)
|
||||
|
||||
elif type == 'tmdb':
|
||||
language = ADDON.getSetting('tmdb_language')
|
||||
cache = 'tmdb-%s-%s.json' % (str(value), language)
|
||||
url = 'http://api.themoviedb.org/3/tv/%s?api_key=6a5be4999abf74eba1f9a8311294c267&language=%s' % (str(value), language)
|
||||
json_value = '<episodeguide><url cache="%s"><url>%s</url></episodeguide>' % (cache, url)
|
||||
|
||||
else:
|
||||
url = ''
|
||||
json_value = '<episodeguide><url cache=""><url></url></episodeguide>'
|
||||
|
||||
for elem in self.root.findall('episodeguide'):
|
||||
self.root.remove(elem)
|
||||
|
||||
episodeguide_elem = ET.SubElement(self.root, 'episodeguide')
|
||||
url_elem = ET.SubElement(episodeguide_elem, 'url')
|
||||
if post:
|
||||
url_elem.set('post', post)
|
||||
url_elem.set('cache', cache)
|
||||
url_elem.text = url
|
||||
|
||||
self.sortlist.append('episodeguide')
|
||||
|
||||
json_call('VideoLibrary.SetTVShowDetails',
|
||||
params={'episodeguide': json_value, 'tvshowid': int(self.dbid)},
|
||||
debug=LOG_JSON
|
||||
)
|
||||
@@ -0,0 +1,601 @@
|
||||
#!/usr/bin/python
|
||||
# coding: utf-8
|
||||
|
||||
########################
|
||||
|
||||
from __future__ import division
|
||||
|
||||
from resources.lib.helper import *
|
||||
from resources.lib.functions import *
|
||||
from resources.lib.database import *
|
||||
from resources.lib.nfo_updater import *
|
||||
|
||||
########################
|
||||
|
||||
RUN_IN_BACKGROUND = ADDON.getSettingBool('update_background')
|
||||
BUSYDIALOG = False if RUN_IN_BACKGROUND else True
|
||||
OMDB_FALLBACK = ADDON.getSettingBool('omdb_fallback_search')
|
||||
OMDB_API = ADDON.getSetting('omdb_api_key')
|
||||
COUNTRY_CODE = ADDON.getSetting('country_code')
|
||||
SKIP_MPAA = ADDON.getSettingBool('mpaa_skip')
|
||||
SKIP_NOT_RATED = ADDON.getSettingBool('mpaa_skip_nr')
|
||||
MPAA_FALLBACK = ADDON.getSettingBool('mpaa_fallback')
|
||||
TMDB_LANGUAGE = ADDON.getSetting('tmdb_language')
|
||||
RATING_DEBUG = ADDON.getSetting('debug_rating_updater')
|
||||
|
||||
########################
|
||||
|
||||
def update_ratings(dbid=None,dbtype=None,content=None):
|
||||
# no omdb API key message
|
||||
if not OMDB_API:
|
||||
if not DIALOG.yesno(xbmc.getLocalizedString(14117), ADDON.getLocalizedString(32035)):
|
||||
return
|
||||
|
||||
winprop('UpdatingRatings.bool', True)
|
||||
msg_text = xbmc.getLocalizedString(19256)
|
||||
|
||||
# get database ids
|
||||
if isinstance(dbtype, str):
|
||||
dbtype = dbtype.split('+')
|
||||
|
||||
with busy_dialog(force=BUSYDIALOG):
|
||||
db = Database(dbid=dbid, append=['episodes'])
|
||||
for i in dbtype:
|
||||
getattr(db, i)()
|
||||
result = db.result()
|
||||
|
||||
# calc total items to process
|
||||
total_items = 0
|
||||
for i in result:
|
||||
if result.get(i):
|
||||
total_items = total_items + len(result[i])
|
||||
|
||||
if total_items > 1:
|
||||
# show progress if 1< will be processed
|
||||
progressdialog = ProgressDialog(total_items)
|
||||
|
||||
for i in result:
|
||||
if i == 'movie':
|
||||
cat = xbmc.getLocalizedString(20338)
|
||||
elif i == 'tvshow':
|
||||
cat = xbmc.getLocalizedString(20364)
|
||||
elif i == 'episode':
|
||||
cat = xbmc.getLocalizedString(20359)
|
||||
|
||||
for item in result[i]:
|
||||
if progressdialog.canceled():
|
||||
break
|
||||
|
||||
if item.get('showtitle') and item.get('label'):
|
||||
label = item.get('showtitle') + ' - ' + item.get('label')
|
||||
else:
|
||||
label = item.get('title')
|
||||
|
||||
if item.get('year'):
|
||||
label = label + ' (' + str(item.get('year')) + ')'
|
||||
|
||||
progressdialog.update(cat, label)
|
||||
|
||||
UpdateRating({'dbid': item.get('%sid' % i),
|
||||
'type': i})
|
||||
#xbmc.sleep(50)
|
||||
|
||||
if progressdialog.canceled():
|
||||
msg_text = ADDON.getLocalizedString(32042)
|
||||
break
|
||||
|
||||
progressdialog.close()
|
||||
|
||||
elif total_items == 1:
|
||||
# process single item
|
||||
for i in result:
|
||||
UpdateRating({'dbid': result[i][0].get('%sid' % i),
|
||||
'type': i})
|
||||
|
||||
else:
|
||||
# error message
|
||||
msg_text = ADDON.getLocalizedString(32048)
|
||||
|
||||
winprop('UpdatingRatings', clear=True)
|
||||
notification(ADDON.getLocalizedString(32030), msg_text)
|
||||
|
||||
|
||||
class ProgressDialog(object):
|
||||
def __init__(self,total_items):
|
||||
if RUN_IN_BACKGROUND:
|
||||
self.progressdialog = xbmcgui.DialogProgressBG()
|
||||
else:
|
||||
self.progressdialog = xbmcgui.DialogProgress()
|
||||
|
||||
self.progressdialog.create('Updating', '')
|
||||
self.total_items = total_items
|
||||
self.processed_items = 0
|
||||
self.progress = 0
|
||||
|
||||
def canceled(self):
|
||||
if RUN_IN_BACKGROUND:
|
||||
return True if winprop('CancelRatingUpdater.bool') else False
|
||||
else:
|
||||
return True if self.progressdialog.iscanceled() or winprop('CancelRatingUpdater.bool') else False
|
||||
|
||||
def update(self,cat,label):
|
||||
self.processed_items += 1
|
||||
progress = int(100 / self.total_items * self.processed_items)
|
||||
processed = str(self.processed_items) + ' / ' + str(self.total_items)
|
||||
|
||||
if RUN_IN_BACKGROUND:
|
||||
self.progressdialog.update(progress, processed, cat + ':' + label)
|
||||
else:
|
||||
self.progressdialog.update(progress, cat + ':[CR]' + label + '[CR]' + processed)
|
||||
|
||||
def close(self):
|
||||
self.progressdialog.close()
|
||||
self.progressdialog = None
|
||||
winprop('CancelRatingUpdater', clear=True)
|
||||
|
||||
|
||||
class UpdateRating(object):
|
||||
def __init__(self,params):
|
||||
self.dbid = params.get('dbid')
|
||||
self.dbtype = params.get('type')
|
||||
self.tmdb_type = 'movie' if self.dbtype == 'movie' else 'tv'
|
||||
self.tmdb_tv_status = None
|
||||
self.tmdb_mpaa = None
|
||||
self.tmdb_mpaa_fallback = None
|
||||
self.tmdb_rating = None
|
||||
self.imdb_rating = None
|
||||
self.omdb_limit = False
|
||||
self.update_uniqueid = False
|
||||
self.episodeguide = None
|
||||
|
||||
# collect db data
|
||||
self.db = Database(dbid=self.dbid, dbtype=self.dbtype)
|
||||
self.get_details()
|
||||
|
||||
self.uniqueid = self.details.get('uniqueid', {})
|
||||
self.ratings = self.details.get('ratings', {})
|
||||
self.file = self.details.get('file')
|
||||
self.year = self.details.get('year')
|
||||
self.premiered = self.details.get('premiered') or self.details.get('firstaired')
|
||||
self.title = self.details.get('title')
|
||||
self.original_title = self.details.get('originaltitle') or self.title
|
||||
self.tags = self.details.get('tag')
|
||||
|
||||
if any(string in self.details.get('episodeguide', '') for string in ['tvdb', 'tmdb']):
|
||||
self.episodeguide = self.details.get('episodeguide')
|
||||
else:
|
||||
self.episodeguide = None
|
||||
|
||||
if self.uniqueid:
|
||||
self.run()
|
||||
|
||||
def get_details(self):
|
||||
getattr(self.db, self.dbtype)()
|
||||
self.details = self.db.result().get(self.dbtype)[0]
|
||||
|
||||
def run(self):
|
||||
log('Run rating updater - %s: %s - ID: %s' % (self.dbtype, self.title, str(self.dbid)), force=RATING_DEBUG)
|
||||
self.imdb = self.uniqueid.get('imdb')
|
||||
self.tmdb = self.uniqueid.get('tmdb')
|
||||
self.tvdb = self.uniqueid.get('tvdb')
|
||||
|
||||
# don't proceed for episodes if no IMDb is available
|
||||
if self.dbtype == 'episode' and not self.imdb:
|
||||
log('Episode with no IMDb. Skip.', force=RATING_DEBUG)
|
||||
return
|
||||
|
||||
# get the default used rating
|
||||
self.default_rating = None
|
||||
for rating in self.ratings:
|
||||
if self.ratings[rating].get('default'):
|
||||
self.default_rating = rating
|
||||
break
|
||||
|
||||
if self.dbtype != 'episode':
|
||||
# get TMDb ID (if not available) by using the ID of IMDb or TVDb
|
||||
if not self.tmdb and self.imdb:
|
||||
log('No TMDb. Try to get by IMDb ID %s' % self.imdb, force=RATING_DEBUG)
|
||||
self.get_tmdb_externalid(self.imdb)
|
||||
|
||||
elif not self.tmdb and self.tvdb:
|
||||
log('No TMDb. Try to get by TVDb ID %s' % str(self.tvdb), force=RATING_DEBUG)
|
||||
self.get_tmdb_externalid(self.tvdb)
|
||||
|
||||
# get TMDb rating and IMDb number if not available
|
||||
if self.tmdb:
|
||||
log('Fetch data by TMDb ID %s' % str(self.tmdb), force=RATING_DEBUG)
|
||||
self.get_tmdb()
|
||||
|
||||
# get Rotten, Metacritic and IMDb ratings of OMDb
|
||||
if not self.omdb_limit:
|
||||
log('Fetch OMDb data', force=RATING_DEBUG)
|
||||
self.get_omdb()
|
||||
|
||||
# if no TMDb ID was known before but OMDb return the IMDb ID -> try to get TMDb data again
|
||||
if self.dbtype != 'episode' and not self.tmdb and self.imdb:
|
||||
log('Try to get TMDb ID by returned IMDb ID %s of OMDb' % self.imdb, force=RATING_DEBUG)
|
||||
self.get_tmdb_externalid(self.imdb)
|
||||
|
||||
if self.tmdb:
|
||||
log('Fetch data by TMDb ID %s' % str(self.tmdb), force=RATING_DEBUG)
|
||||
self.get_tmdb()
|
||||
|
||||
# emby <ratings> and <votes>
|
||||
if 'default' in self.ratings:
|
||||
self.emby_ratings()
|
||||
|
||||
# update db + nfo
|
||||
log('Updating info', force=RATING_DEBUG)
|
||||
self.update_info()
|
||||
|
||||
def emby_ratings(self):
|
||||
# Emby For Kodi is storing the rating as 'default'
|
||||
if self.imdb_rating:
|
||||
self._update_ratings_dict(key='default',
|
||||
rating=float(self.imdb_rating),
|
||||
votes=int(self.imdb_votes)
|
||||
)
|
||||
|
||||
elif self.tmdb_rating:
|
||||
self._update_ratings_dict(key='default',
|
||||
rating=float(self.tmdb_rating),
|
||||
votes=int(self.tmdb_votes)
|
||||
)
|
||||
|
||||
def get_tmdb(self):
|
||||
result = self._tmdb(action=self.tmdb_type,
|
||||
call=str(self.tmdb),
|
||||
params={'append_to_response': 'release_dates,content_ratings,external_ids'}
|
||||
)
|
||||
|
||||
if not result:
|
||||
return
|
||||
|
||||
self.tmdb_rating = result.get('vote_average')
|
||||
self.tmdb_votes = result.get('vote_count')
|
||||
|
||||
if not self.original_title:
|
||||
self.original_title = result.get('original_title') or resultresult.get('original_name')
|
||||
|
||||
# update original title if missing
|
||||
if self.original_title:
|
||||
self._set_value('originaltitle', self.original_title)
|
||||
|
||||
if self.tmdb_type == 'tv':
|
||||
premiered = result.get('first_air_date')
|
||||
self.tmdb_tv_status = result.get('status')
|
||||
|
||||
# update TV status as well
|
||||
if self.tmdb_tv_status:
|
||||
self._set_value('status', self.tmdb_tv_status)
|
||||
|
||||
else:
|
||||
premiered = result.get('release_date')
|
||||
|
||||
# update the year if not correct
|
||||
if premiered and self.premiered != premiered:
|
||||
self.year = premiered[:4]
|
||||
|
||||
if ADDON.getSettingBool('update_premiered') or not self.premiered:
|
||||
self._set_value('premiered', premiered)
|
||||
|
||||
if self.tmdb_rating:
|
||||
self._update_ratings_dict(key='themoviedb',
|
||||
rating=self.tmdb_rating,
|
||||
votes=self.tmdb_votes
|
||||
)
|
||||
|
||||
# set MPAA based on setting
|
||||
if not SKIP_MPAA:
|
||||
if self.tmdb_type == 'movie':
|
||||
release_dates = result['release_dates']['results']
|
||||
|
||||
for country in release_dates:
|
||||
if country.get('iso_3166_1') == COUNTRY_CODE:
|
||||
for item in country['release_dates']:
|
||||
if item.get('certification'):
|
||||
self.tmdb_mpaa = item.get('certification')
|
||||
break
|
||||
break
|
||||
|
||||
elif country.get('iso_3166_1') == 'US':
|
||||
for item in country['release_dates']:
|
||||
if item.get('certification'):
|
||||
self.tmdb_mpaa_fallback = item.get('certification')
|
||||
break
|
||||
|
||||
if self.tmdb_type == 'tv':
|
||||
content_ratings = result['content_ratings']['results']
|
||||
|
||||
for country in content_ratings:
|
||||
if country.get('iso_3166_1') == COUNTRY_CODE:
|
||||
self.tmdb_mpaa = country.get('rating')
|
||||
break
|
||||
|
||||
elif country.get('iso_3166_1') == 'US':
|
||||
self.tmdb_mpaa_fallback = country.get('rating')
|
||||
|
||||
if SKIP_NOT_RATED:
|
||||
if self.tmdb_mpaa == 'NR':
|
||||
self.tmdb_mpaa = None
|
||||
|
||||
if self.tmdb_mpaa_fallback == 'NR':
|
||||
self.tmdb_mpaa_fallback = None
|
||||
|
||||
if self.tmdb_mpaa:
|
||||
if COUNTRY_CODE == 'DE':
|
||||
self.tmdb_mpaa = 'FSK ' + self.tmdb_mpaa
|
||||
|
||||
self._set_value('mpaa', self.tmdb_mpaa)
|
||||
|
||||
elif self.tmdb_mpaa_fallback and MPAA_FALLBACK:
|
||||
self._set_value('mpaa', self.tmdb_mpaa_fallback)
|
||||
|
||||
else:
|
||||
self._set_value('mpaa', '')
|
||||
|
||||
# set IMDb ID if not available in the library
|
||||
if not self.imdb:
|
||||
if self.tmdb_type == 'movie':
|
||||
self.imdb = result.get('imdb_id')
|
||||
|
||||
elif self.tmdb_type == 'tv':
|
||||
self.imdb = result['external_ids'].get('imdb_id')
|
||||
|
||||
if self.imdb:
|
||||
self._update_uniqueid_dict('imdb', self.imdb)
|
||||
|
||||
# add TVDb ID to uniqueid if missing
|
||||
if not self.tvdb and self.tmdb_type == 'tv':
|
||||
self.tvdb = result['external_ids'].get('tvdb_id')
|
||||
|
||||
if self.tvdb:
|
||||
self._update_uniqueid_dict('tvdb', self.tvdb)
|
||||
|
||||
def get_tmdb_externalid(self,external_id):
|
||||
result = self._tmdb(action='find',
|
||||
call=str(external_id),
|
||||
params={'external_source': 'imdb_id' if external_id.startswith('tt') else 'tvdb_id'}
|
||||
)
|
||||
|
||||
if self.dbtype == 'movie' and result.get('movie_results'):
|
||||
self.tmdb = result['movie_results'][0].get('id')
|
||||
|
||||
elif self.dbtype == 'tvshow' and result.get('tv_results'):
|
||||
self.tmdb = result['tv_results'][0].get('id')
|
||||
|
||||
if self.tmdb:
|
||||
self._update_uniqueid_dict('tmdb', self.tmdb)
|
||||
|
||||
def get_omdb(self):
|
||||
omdb = self._omdb()
|
||||
|
||||
if not omdb:
|
||||
return
|
||||
|
||||
tree = ET.ElementTree(ET.fromstring(omdb))
|
||||
root = tree.getroot()
|
||||
|
||||
for child in root:
|
||||
# imdb ratings
|
||||
self.imdb_rating = child.get('imdbRating', '').replace('N/A', '')
|
||||
self.imdb_votes = child.get('imdbVotes', '0').replace('N/A', '0').replace(',', '')
|
||||
if self.imdb_rating:
|
||||
self._update_ratings_dict(key='imdb',
|
||||
rating=float(self.imdb_rating),
|
||||
votes=int(self.imdb_votes)
|
||||
)
|
||||
|
||||
# regular rotten rating
|
||||
tomatometerallcritics = child.get('tomatoMeter', '').replace('N/A', '')
|
||||
tomatometerallcritics_avg = child.get('tomatoRating', '').replace('N/A', '')
|
||||
tomatometerallcritics_votes = child.get('tomatoReviews', '0').replace('N/A', '0').replace(',', '')
|
||||
|
||||
if tomatometerallcritics:
|
||||
self._update_ratings_dict(key='tomatometerallcritics',
|
||||
rating=int(tomatometerallcritics) / 10,
|
||||
votes=int(tomatometerallcritics_votes))
|
||||
|
||||
if tomatometerallcritics_avg:
|
||||
self._update_ratings_dict(key='tomatometeravgcritics',
|
||||
rating=float(tomatometerallcritics_avg),
|
||||
votes=int(tomatometerallcritics_votes))
|
||||
|
||||
# user rotten rating
|
||||
tomatometerallaudience = child.get('tomatoUserMeter', '').replace('N/A', '')
|
||||
tomatometerallaudience_avg = child.get('tomatoUserRating', '').replace('N/A', '')
|
||||
tomatometerallaudience_votes = child.get('tomatoUserReviews', '0').replace('N/A', '0').replace(',', '')
|
||||
|
||||
if tomatometerallaudience:
|
||||
self._update_ratings_dict(key='tomatometerallaudience',
|
||||
rating=int(tomatometerallaudience) / 10,
|
||||
votes=int(tomatometerallaudience_votes))
|
||||
|
||||
if tomatometerallaudience_avg:
|
||||
self._update_ratings_dict(key='tomatometeravgaudience',
|
||||
rating=float(tomatometerallaudience_avg),
|
||||
votes=int(tomatometerallaudience_votes))
|
||||
|
||||
# metacritic
|
||||
metacritic = child.get('metascore', '').replace('N/A', '')
|
||||
if metacritic:
|
||||
metacritic = int(metacritic) / 10
|
||||
self._update_ratings_dict(key='metacritic',
|
||||
rating=metacritic,
|
||||
votes=0)
|
||||
|
||||
# set imdb if not set before
|
||||
if not self.imdb and child.get('imdbID') and child.get('imdbID') != 'N/A':
|
||||
self.imdb = child.get('imdbID')
|
||||
self._update_uniqueid_dict('imdb', child.get('imdbID'))
|
||||
|
||||
break
|
||||
|
||||
def update_info(self):
|
||||
# set at least one default rating if none is set in the library
|
||||
if not self.default_rating and self.ratings:
|
||||
for item in ['imdb', 'themoviedb', 'tomatometerallcritics', 'tomatometeravgcritics', 'metacritic']:
|
||||
if item in self.ratings:
|
||||
self.default_rating = item
|
||||
break
|
||||
|
||||
# unkown rating source is stored -> use the first one
|
||||
if not self.default_rating:
|
||||
for item in self.ratings:
|
||||
self.default_rating = item
|
||||
break
|
||||
|
||||
# update to library
|
||||
self._set_value(key='ratings', value=self.ratings)
|
||||
|
||||
if self.update_uniqueid:
|
||||
self._set_value(key='uniqueid', value=self.uniqueid)
|
||||
|
||||
# episode guide verification
|
||||
if self.episodeguide:
|
||||
if 'thetvdb' in self.episodeguide and 'tvdb' not in self.uniqueid:
|
||||
self.episodeguide = None
|
||||
elif 'themoviedb' in self.episodeguide and 'tmdb' not in self.uniqueid:
|
||||
self.episodeguide = None
|
||||
|
||||
if self.dbtype == 'tvshow' and not self.episodeguide:
|
||||
if 'tvdb' in self.uniqueid:
|
||||
value = self.uniqueid.get('tvdb')
|
||||
url = 'https://api.thetvdb.com/login?{"apikey":"439DFEBA9D3059C6","id":%s}|Content-Type=application/json' % str(value)
|
||||
json_value = '<episodeguide><url post="yes" cache="auth.json"><url>%s</url></episodeguide>' % url
|
||||
|
||||
elif 'tmdb' in self.uniqueid:
|
||||
value = self.uniqueid.get('tmdb')
|
||||
cache = 'tmdb-%s-%s.json' % (str(value), TMDB_LANGUAGE)
|
||||
url = 'http://api.themoviedb.org/3/tv/%s?api_key=6a5be4999abf74eba1f9a8311294c267&language=%s' % (str(value), TMDB_LANGUAGE)
|
||||
json_value = '<episodeguide><url cache="%s"><url>%s</url></episodeguide>' % (cache, url)
|
||||
|
||||
else:
|
||||
json_value = '<episodeguide><url cache=""><url></url></episodeguide>'
|
||||
|
||||
self.episodeguide = json_value
|
||||
self._set_value('episodeguide', json_value)
|
||||
|
||||
# nfo updating
|
||||
if self.file:
|
||||
# get updated data
|
||||
self.get_details()
|
||||
|
||||
# TV status cannot be fetched in Leia
|
||||
if self.tmdb_tv_status and not self.details.get('status'):
|
||||
self.details['status'] = self.tmdb_tv_status
|
||||
|
||||
update_nfo(file=self.file,
|
||||
dbtype=self.dbtype,
|
||||
dbid=self.dbid,
|
||||
details=self.details
|
||||
)
|
||||
|
||||
def _update_ratings_dict(self,key,rating,votes):
|
||||
self.ratings[key] = {'default': True if key == self.default_rating else False,
|
||||
'rating': rating,
|
||||
'votes': votes}
|
||||
|
||||
def _update_uniqueid_dict(self,key,value):
|
||||
self.uniqueid[key] = str(value)
|
||||
self.update_uniqueid = True
|
||||
|
||||
def _set_value(self,key,value):
|
||||
self.db.write(key=key, value=value)
|
||||
|
||||
def _omdb(self):
|
||||
if not OMDB_API:
|
||||
log('No OMDb API key configured. Skip.', force=RATING_DEBUG)
|
||||
return
|
||||
|
||||
if self.imdb:
|
||||
url = 'http://www.omdbapi.com/?apikey=%s&i=%s&plot=short&r=xml&tomatoes=true' % (OMDB_API, self.imdb)
|
||||
|
||||
elif OMDB_FALLBACK and self.dbtype != 'episode' and self.original_title and self.year:
|
||||
# urllib has issues with some asian letters
|
||||
try:
|
||||
title = urllib.quote(self.original_title)
|
||||
except KeyError:
|
||||
return
|
||||
|
||||
url = 'http://www.omdbapi.com/?apikey=%s&t=%s&year=%s&plot=short&r=xml&tomatoes=true' % (OMDB_API, title, self.year)
|
||||
|
||||
else:
|
||||
return
|
||||
|
||||
error_msg = 'OMDb error for "%s (%s)" IMDBd "%s". Error --> ' % (self.original_title, self.year, self.imdb)
|
||||
|
||||
for i in range(1,4): # loop if heavy server load
|
||||
log('OMDb call try %s/3' % str(i), force=RATING_DEBUG)
|
||||
try:
|
||||
request = requests.get(url, timeout=5)
|
||||
if not str(request.status_code).startswith('5'):
|
||||
break
|
||||
elif i == 1:
|
||||
notification('OMDb', ADDON.getLocalizedString(32024))
|
||||
|
||||
except Exception:
|
||||
if i < 3:
|
||||
xbmc.sleep(500)
|
||||
else:
|
||||
log(error_msg + '408', WARNING)
|
||||
return
|
||||
|
||||
if request.status_code == 401:
|
||||
log('OMDb error --> API limit reached', WARNING)
|
||||
if DIALOG.yesno(xbmc.getLocalizedString(257), ADDON.getLocalizedString(32033)):
|
||||
log('OMDb limit reached and disabled for next calls', force=RATING_DEBUG)
|
||||
self.omdb_limit = True
|
||||
else:
|
||||
log('OMDb limit reached and rating updater canceled', force=RATING_DEBUG)
|
||||
winprop('CancelRatingUpdater.bool', True)
|
||||
return
|
||||
|
||||
elif not request.ok:
|
||||
log(error_msg + str(request.status_code), WARNING)
|
||||
return
|
||||
|
||||
result = request.text
|
||||
|
||||
if not result or '<root response="False">' in result:
|
||||
log(error_msg + 'Result = ' + str(result), WARNING)
|
||||
return
|
||||
|
||||
return result
|
||||
|
||||
def _tmdb(self,action,call=None,get=None,params=None):
|
||||
result = {}
|
||||
args = {}
|
||||
args['api_key'] = 'fc168650632c6597038cf7072a7c20da'
|
||||
|
||||
if params:
|
||||
args.update(params)
|
||||
|
||||
call = '/' + str(call) if call else ''
|
||||
get = '/' + get if get else ''
|
||||
|
||||
url = 'https://api.themoviedb.org/3/' + action + call + get
|
||||
url = '{0}?{1}'.format(url, urlencode(args))
|
||||
|
||||
for i in range(1,4): # loop if heavy server load
|
||||
log('TMDb call try %s/3' % str(i), force=RATING_DEBUG)
|
||||
try:
|
||||
request = requests.get(url, timeout=5)
|
||||
if not str(request.status_code).startswith('5'):
|
||||
break
|
||||
elif i == 1:
|
||||
notification('TMDb', ADDON.getLocalizedString(32024))
|
||||
|
||||
except Exception:
|
||||
if i < 3:
|
||||
xbmc.sleep(500)
|
||||
else:
|
||||
log('TMDb connection error', force=RATING_DEBUG)
|
||||
return result
|
||||
|
||||
if request.ok:
|
||||
result = request.json()
|
||||
else:
|
||||
log('TMDb returned nothing', force=RATING_DEBUG)
|
||||
|
||||
return result
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<settings>
|
||||
<category label="128">
|
||||
<setting label="$LOCALIZE[128]" type="lsep"/>
|
||||
<setting label="$ADDON[script.metadata.editor 32021]" type="bool" id="nfo_updating" default="true"/>
|
||||
<setting label="$ADDON[script.metadata.editor 32034]" type="bool" id="create_nfo" default="true" enable="eq(-1,true)" />
|
||||
<setting label="$ADDON[script.metadata.editor 32057]" type="bool" id="write_watched_stated" default="true" enable="eq(-2,true)" />
|
||||
<setting label="$ADDON[script.metadata.editor 32055]" type="bool" id="playback_update_playcount" default="true" enable="eq(-3,true) + eq(-1,true)" />
|
||||
<setting label="$ADDON[script.metadata.editor 32056]" type="bool" id="playback_user_rating" default="false" />
|
||||
<setting label="$ADDON[script.metadata.editor 32029]" type="bool" id="json_log" default="false"/>
|
||||
|
||||
<setting label="$ADDON[script.metadata.editor 32026]" type="lsep"/>
|
||||
<setting label="$ADDON[script.metadata.editor 32027]" type="select" values="TVDb|TMDb" id="tv_scraper_base" default="TVDb"/>
|
||||
<setting label="$ADDON[script.metadata.editor 32025]" type="select" values="bg|cs|da|de|ee|el|en|es|fa|fa-ir|fi|fr|fr-ca|he|hr|hu|it|ja|ko|nl|no|pl|pt|pt-br|ru|sl|sr|sv|tr|zh-cn|zh-tw" id="tmdb_language" default="en"/>
|
||||
<setting label="$ADDON[script.metadata.editor 32043]" type="select" values="AU|BG|BR|CA|DE|DK|ES|FI|FR|GB|HU|IN|IT|KR|LT|MY|NL|NO|NZ|PH|PT|RU|SE|SK|TH|US" id="country_code" default="US"/>
|
||||
<setting label="$ADDON[script.metadata.editor 32044]" type="bool" id="mpaa_skip" default="false"/>
|
||||
<setting label="$ADDON[script.metadata.editor 32052]" type="bool" id="mpaa_fallback" default="true" enable="eq(-1,false) + !eq(-2,US)" />
|
||||
<setting label="$ADDON[script.metadata.editor 32053]" type="bool" id="mpaa_skip_nr" default="false" enable="eq(-2,false) + !eq(-3,US)" />
|
||||
<setting label="$ADDON[script.metadata.editor 32032]" type="bool" id="omdb_fallback_search" default="true"/>
|
||||
<setting label="$ADDON[script.metadata.editor 32041]" type="bool" id="update_premiered" default="true"/>
|
||||
|
||||
<setting label="$ADDON[script.metadata.editor 32030]" type="lsep"/>
|
||||
<setting label="$ADDON[script.metadata.editor 32031]" type="text" id="omdb_api_key"/>
|
||||
<setting label="$ADDON[script.metadata.editor 32028]" type="bool" id="update_background" default="false"/>
|
||||
<setting label="$LOCALIZE[20191]" type="bool" id="debug_rating_updater" default="false"/>
|
||||
</category>
|
||||
</settings>
|
||||