From 1267a92daf8aea5e8dc3d16ae62f0cac77c7d173 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 09:16:03 +0200 Subject: [PATCH 01/20] Update Spanish and German --- .../resource.language.de_DE/strings.po | 22 ++++---- .../resource.language.es_ES/strings.po | 50 +++++++++++-------- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/resources/language/resource.language.de_DE/strings.po b/resources/language/resource.language.de_DE/strings.po index 13679ee9..b71de87b 100644 --- a/resources/language/resource.language.de_DE/strings.po +++ b/resources/language/resource.language.de_DE/strings.po @@ -1461,12 +1461,12 @@ msgid "" "CAUTION! If you choose \"Native\" mode , you might loose access to certain " "Plex features such as: Plex trailers and transcoding options. ALL Plex " "shares need to use direct paths (e.g. smb://myNAS/mymovie.mkv or " -"\\myNAS/mymovie.mkv)!" +"\\\\myNAS/mymovie.mkv)!" msgstr "" "WARNUNG! Mit dem \"Native\" Modus verlieren Sie Zugang zu Plex Funktionen " "wie z.B. Trailer und Transkodieren. ALLE Plex Bibliotheken müssen über " "direkte Plex Pfade für Kodi zugänglich sein (z.B. via " -"\\meinNas\\MeinFilm.mkv oder smb://meinNas/MeinFilm.mkv)!" +"smb://meinNas/MeinFilm.mkv oder \\\\meinNas\\MeinFilm.mkv)!" msgctxt "#39029" msgid "Network credentials" @@ -1497,21 +1497,23 @@ msgstr "" msgctxt "#39033" msgid "" -"Transform Plex UNC library paths \\myNas\\mymovie.mkv automatically to smb " -"paths, smb://myNas/mymovie.mkv? (recommended)" +"Transform Plex UNC library paths \\\\myNas\\mymovie.mkv automatically to smb" +" paths, smb://myNas/mymovie.mkv? (recommended)" msgstr "" -"Sollen alle Plex UNC Pfade \\meinNAS\\meinFilm.mkv automatisch durch SMB " +"Sollen alle Plex UNC Pfade \\\\meinNAS\\meinFilm.mkv automatisch durch SMB " "Pfade smb://meinNAS/meinFilm.mkv ersetzt werden? (empfohlen)" msgctxt "#39034" -msgid "Replace Plex UNC paths \\myNas with smb://myNas" -msgstr "Plex UNC Pfade \\meinNAS durch smb://meinNAS ersetzen" +msgid "Replace Plex UNC paths \\\\myNas with smb://myNas" +msgstr "Plex UNC Pfade \\\\meinNAS durch smb://meinNAS ersetzen" msgctxt "#39035" msgid "" -"Replace Plex paths /volume1/media or \\myserver\\media with custom SMB paths" -" smb://NAS/mystuff" -msgstr "Benutzerdefinierte smb Pfade für z.B. /volume1/media erstellen" +"Replace Plex paths /volume1/media or \\\\myserver\\media with custom SMB " +"paths smb://NAS/mystuff" +msgstr "" +"Plex Pfade /volume1/medien oder \\\\meinServer\\medien mit " +"benutzerdefinierten SMB Pfaden wie smb://NAS/Filme ersetzen" msgctxt "#39037" msgid "Original Plex MOVIE path to replace:" diff --git a/resources/language/resource.language.es_ES/strings.po b/resources/language/resource.language.es_ES/strings.po index 1c7dc3d9..a27e001b 100644 --- a/resources/language/resource.language.es_ES/strings.po +++ b/resources/language/resource.language.es_ES/strings.po @@ -1,13 +1,13 @@ # XBMC Media Center language file # Translators: -# Croneter None , 2017 +# Bartolome Soriano , 2017 msgid "" msgstr "" "Project-Id-Version: PlexKodiConnect\n" "Report-Msgid-Bugs-To: croneter@gmail.com\n" "POT-Creation-Date: 2017-04-15 13:13+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: Croneter None , 2017\n" +"Last-Translator: Bartolome Soriano , 2017\n" "Language-Team: Spanish (Spain) (https://www.transifex.com/croneter/teams/73837/es_ES/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,7 +18,7 @@ msgstr "" # Add-on settings msgctxt "#29999" msgid "PlexKodiConnect" -msgstr "" +msgstr "PlexKodiConnect" msgctxt "#30000" msgid "Server Address (IP)" @@ -62,7 +62,7 @@ msgstr "Sistema de almacenamiento en caché local" msgctxt "#30012" msgid "OK" -msgstr "" +msgstr "OK" msgctxt "#30013" msgid "Never show" @@ -106,11 +106,11 @@ msgstr "Soy dueño de este Plex Media Server" msgctxt "#30035" msgid "Number of recent Music Albums to show:" -msgstr "Número de álbumes de música recientes para mostrar:" +msgstr "Número de Álbumes de Música recientes para mostrar:" msgctxt "#30036" msgid "Number of recent Movies to show:" -msgstr "Número de películas recientes a mostrar:" +msgstr "Número de Películas recientes a mostrar:" msgctxt "#30037" msgid "Number of recent TV episodes to show:" @@ -231,7 +231,7 @@ msgstr "Documental" msgctxt "#30076" msgid "Drama" -msgstr "" +msgstr "Drama" msgctxt "#30077" msgid "Fantasy" @@ -251,11 +251,11 @@ msgstr "Terror" msgctxt "#30081" msgid "Music" -msgstr "Musica" +msgstr "Música" msgctxt "#30082" msgid "Musical" -msgstr "" +msgstr "Musical" msgctxt "#30083" msgid "Mystery" @@ -263,7 +263,7 @@ msgstr "Misterio" msgctxt "#30084" msgid "Romance" -msgstr "" +msgstr "Romance" msgctxt "#30085" msgid "Science Fiction" @@ -279,7 +279,7 @@ msgstr "Suspenso" msgctxt "#30088" msgid "Thriller" -msgstr "" +msgstr "Thriller" msgctxt "#30089" msgid "Western" @@ -440,7 +440,7 @@ msgstr "Esto afectará el rendimiento." msgctxt "#30135" msgid "Error" -msgstr "" +msgstr "Error" msgctxt "#30136" msgid "Monitoring service is not running" @@ -733,7 +733,7 @@ msgstr "En Curso " msgctxt "#30222" msgid "NextUp " -msgstr "" +msgstr "NextUp" msgctxt "#30223" msgid "User Views" @@ -769,7 +769,7 @@ msgstr "Recomendados" msgctxt "#30235" msgid "Extras" -msgstr "" +msgstr "Extras" msgctxt "#30236" msgid "Sync Theme Music" @@ -840,11 +840,11 @@ msgstr "Vídeos Caseros Favoritos" msgctxt "#30254" msgid "Favorite Photos" -msgstr "" +msgstr "Fotos Favoritas" msgctxt "#30255" msgid "Favorite Albums" -msgstr "" +msgstr "Álbumes Favoritos" msgctxt "#30256" msgid "Recently added Music videos" @@ -881,7 +881,7 @@ msgstr "Tráilers" msgctxt "#30305" msgid "Series" -msgstr "" +msgstr "Series" msgctxt "#30306" msgid "Seasons" @@ -1051,7 +1051,7 @@ msgstr "Reproducción" msgctxt "#30517" msgid "[COLOR yellow]Enter network credentials[/COLOR]" -msgstr "[COLOR yellos] Digitar credenciales de red[/COLOR]" +msgstr "[COLOR yellow] Digitar credenciales de red[/COLOR]" msgctxt "#30518" msgid "Enable Plex Trailers (Plexpass is needed)" @@ -1441,7 +1441,7 @@ msgstr "[COLOR yellow] Sincronizar Medios de Tema de Plex a Kodi[/COLOR]" msgctxt "#39022" msgid "local" -msgstr "" +msgstr "local" msgctxt "#39023" msgid "Failed to authenticate. Did you login to plex.tv?" @@ -1503,6 +1503,8 @@ msgid "" "Transform Plex UNC library paths \\myNas\\mymovie.mkv automatically to smb " "paths, smb://myNas/mymovie.mkv? (recommended)" msgstr "" +"¿Transformar rutas de colección UNC de Plex \\miNAS\\mipelicula.mkv " +"automáticamente a rutas SMB, smb://miNAS/mipelicula.mkv? (recomendado)" msgctxt "#39034" msgid "Replace Plex UNC paths \\myNas with smb://myNas" @@ -1970,7 +1972,7 @@ msgstr "ERROR en la sincronización de la biblioteca" # Plex videonodes.py msgctxt "#39500" msgid "On Deck" -msgstr "" +msgstr "On Deck" msgctxt "#39501" msgid "Collections" @@ -2017,7 +2019,7 @@ msgstr "Navegar por carpeta" # Addon Summary msgctxt "#39703" msgid "Native Integration of Plex into Kodi" -msgstr "" +msgstr "Integración Nativa de Plex en Kodi" # For use with addon.xml (PKC metadata for Kodi, e.g. description) # Addon Description @@ -2028,9 +2030,13 @@ msgid "" "stored in the Kodi video and music databases (as this plugin directly " "changes them). Use at your own risk!" msgstr "" +"Conecte Kodi a su Plex Media Server. Este plugin asume que usted gestiona " +"todos sus vídeos con Plex (y ninguno con Kodi). Puede perder datos ya " +"guardados en las bases de datos de vídeo y música de Kodi (ya que este " +"plugin las actualiza directamente). ¡Úselo a su propio riesgo!" # For use with addon.xml (PKC metadata for Kodi, e.g. description) # Addon Disclaimer msgctxt "#39705" msgid "Use at your own risk" -msgstr "" +msgstr "Usar a su propio riesgo" From 528c704b7766759f782b9fb00d48e9c895953996 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 09:17:29 +0200 Subject: [PATCH 02/20] Remove obsolete English translations --- addon.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/addon.xml b/addon.xml index 86e458f9..c699e98f 100644 --- a/addon.xml +++ b/addon.xml @@ -24,18 +24,12 @@ https://github.com/croneter/PlexKodiConnect Native Integration of Plex into Kodi - Native Integration of Plex into Kodi - Native Integration of Plex into Kodi - Native Integration of Plex into Kodi Úplná integrace Plexu do Kodi Komplette Integration von Plex in Kodi Indbygget Integration af Plex i Kodi Directe integratie van Plex in Kodi 將Plex直接內嵌至Kodi Connect Kodi to your Plex Media Server. This plugin assumes that you manage all your videos with Plex (and none with Kodi). You might lose data already stored in the Kodi video and music databases (as this plugin directly changes them). - Connect Kodi to your Plex Media Server. This plugin assumes that you manage all your videos with Plex (and none with Kodi). You might lose data already stored in the Kodi video and music databases (as this plugin directly changes them). - Connect Kodi to your Plex Media Server. This plugin assumes that you manage all your videos with Plex (and none with Kodi). You might lose data already stored in the Kodi video and music databases (as this plugin directly changes them). - Connect Kodi to your Plex Media Server. This plugin assumes that you manage all your videos with Plex (and none with Kodi). You might lose data already stored in the Kodi video and music databases (as this plugin directly changes them). Připojte Kodi ke svému Plex Media Serveru. Tento doplněk předpokládá, že spravujete veškerá svá videa pomocí Plexu (nikoliv pomocí Kodi). Můžete přijít o data uložená ve video a hudební databázi Kodi (tento doplněk je přímo mění). Verbindet Kodi mit deinem Plex Media Server. Dieses Addon geht davon aus, dass du all deine Videos mit Plex verwaltest (und keine direkt mit Kodi). Du wirst möglicherweise Daten verlieren, die bereits in der Kodi Video- und/oder Musik-Datenbank gespeichert sind (da dieses Addon beide Datenbanken direkt verändert). Tilslut Kodi til din Plex Media Server. Dette plugin forudsætter, at du administrere alle dine videoer med Plex (og ikke med Kodi). Du kan miste data som allerede er gemt i Kodi video og musik-databaser (dette plugin ændrer direkte i dem). From 86db783a021a7b0394a52905d12d815c91c18f5f Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 09:21:11 +0200 Subject: [PATCH 03/20] Add Spanish (Spain) Addon metadata --- addon.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/addon.xml b/addon.xml index c699e98f..eaef7628 100644 --- a/addon.xml +++ b/addon.xml @@ -29,12 +29,14 @@ Indbygget Integration af Plex i Kodi Directe integratie van Plex in Kodi 將Plex直接內嵌至Kodi + Integración Nativa de Plex en Kodi Connect Kodi to your Plex Media Server. This plugin assumes that you manage all your videos with Plex (and none with Kodi). You might lose data already stored in the Kodi video and music databases (as this plugin directly changes them). Připojte Kodi ke svému Plex Media Serveru. Tento doplněk předpokládá, že spravujete veškerá svá videa pomocí Plexu (nikoliv pomocí Kodi). Můžete přijít o data uložená ve video a hudební databázi Kodi (tento doplněk je přímo mění). Verbindet Kodi mit deinem Plex Media Server. Dieses Addon geht davon aus, dass du all deine Videos mit Plex verwaltest (und keine direkt mit Kodi). Du wirst möglicherweise Daten verlieren, die bereits in der Kodi Video- und/oder Musik-Datenbank gespeichert sind (da dieses Addon beide Datenbanken direkt verändert). Tilslut Kodi til din Plex Media Server. Dette plugin forudsætter, at du administrere alle dine videoer med Plex (og ikke med Kodi). Du kan miste data som allerede er gemt i Kodi video og musik-databaser (dette plugin ændrer direkte i dem). Verbind Kodi met je Plex Media Server. Deze plugin gaat ervan uit dat je al je video's met Plex (en niet met Kodi) beheerd. Je kunt gegevens reeds opgeslagen in de databases voor video en muziek van Kodi (deze plugin wijzigt deze gegevens direct) verliezen. 連接Kodi至您的Plex媒體伺服器.這個外掛程式假設你使用Plex伺服器管理您所有的媒體(完全沒用Kodi管理).您可能會失去已經儲存在Kodi資料庫中的視頻及音樂的資料(這個外掛程式會直接更改它們). + Conecte Kodi a su Plex Media Server. Este plugin asume que usted gestiona todos sus vídeos con Plex (y ninguno con Kodi). Puede perder datos ya guardados en las bases de datos de vídeo y música de Kodi (ya que este plugin las actualiza directamente). ¡Úselo a su propio riesgo! Use at your own risk Use at your own risk Use at your own risk @@ -44,6 +46,7 @@ Brug på eget ansvar Gebruik op eigen risico 使用風險由您自己承擔 + Usar a su propio riesgo version 1.7.8 (beta only) - Fix IMDB id for movies (resync by going to the PKC settings, Advanced, then Repair Local Database) - Increase timeouts for PMS, should fix some connection issues From 0a9b8f3da72847178c00b40c999379d5b77b19f8 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 09:21:56 +0200 Subject: [PATCH 04/20] Remove dangerous characters --- addon.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon.xml b/addon.xml index eaef7628..4cd41faa 100644 --- a/addon.xml +++ b/addon.xml @@ -67,7 +67,7 @@ version 1.7.5 - Dutch translation, thanks @mvanbaak version 1.7.4 (beta only) -- Show menu item only for appropriate Kodi library: Be careful to start video content through Videos -> Video Addons -> ... and pictures through Pictures -> Picture Addons -> ... +- Show menu item only for appropriate Kodi library: Be careful to start video content through Videos - Video Addons - ... and pictures through Pictures - Picture Addons - ... - Fix playback error popup when using Alexa - New Italian translations, thanks @nikkux, @chicco83 - Update translations From 7b33cc95b9333c1cd2fc7769979947508ee236bb Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 09:47:35 +0200 Subject: [PATCH 05/20] Update addon metadata for English --- addon.xml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/addon.xml b/addon.xml index 4cd41faa..9159bd5e 100644 --- a/addon.xml +++ b/addon.xml @@ -30,7 +30,7 @@ Directe integratie van Plex in Kodi 將Plex直接內嵌至Kodi Integración Nativa de Plex en Kodi - Connect Kodi to your Plex Media Server. This plugin assumes that you manage all your videos with Plex (and none with Kodi). You might lose data already stored in the Kodi video and music databases (as this plugin directly changes them). + Connect Kodi to your Plex Media Server. This plugin assumes that you manage all your videos with Plex (and none with Kodi). You might lose data already stored in the Kodi video and music databases (as this plugin directly changes them). Use at your own risk! Připojte Kodi ke svému Plex Media Serveru. Tento doplněk předpokládá, že spravujete veškerá svá videa pomocí Plexu (nikoliv pomocí Kodi). Můžete přijít o data uložená ve video a hudební databázi Kodi (tento doplněk je přímo mění). Verbindet Kodi mit deinem Plex Media Server. Dieses Addon geht davon aus, dass du all deine Videos mit Plex verwaltest (und keine direkt mit Kodi). Du wirst möglicherweise Daten verlieren, die bereits in der Kodi Video- und/oder Musik-Datenbank gespeichert sind (da dieses Addon beide Datenbanken direkt verändert). Tilslut Kodi til din Plex Media Server. Dette plugin forudsætter, at du administrere alle dine videoer med Plex (og ikke med Kodi). Du kan miste data som allerede er gemt i Kodi video og musik-databaser (dette plugin ændrer direkte i dem). @@ -38,9 +38,6 @@ 連接Kodi至您的Plex媒體伺服器.這個外掛程式假設你使用Plex伺服器管理您所有的媒體(完全沒用Kodi管理).您可能會失去已經儲存在Kodi資料庫中的視頻及音樂的資料(這個外掛程式會直接更改它們). Conecte Kodi a su Plex Media Server. Este plugin asume que usted gestiona todos sus vídeos con Plex (y ninguno con Kodi). Puede perder datos ya guardados en las bases de datos de vídeo y música de Kodi (ya que este plugin las actualiza directamente). ¡Úselo a su propio riesgo! Use at your own risk - Use at your own risk - Use at your own risk - Use at your own risk Používejte na vlastní nebezpečí Benutze auf eigene Gefahr Brug på eget ansvar From bc3a81b12a70d81dac77ba73f5fe7ba40f9f3a88 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 09:53:40 +0200 Subject: [PATCH 06/20] Fix TheTVDB ID for TV shows - Partially fixes #277 --- resources/lib/itemtypes.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/resources/lib/itemtypes.py b/resources/lib/itemtypes.py index 301649e3..6c5c8433 100644 --- a/resources/lib/itemtypes.py +++ b/resources/lib/itemtypes.py @@ -621,7 +621,7 @@ class TVShows(Items): self.kodi_db.update_uniqueid(showid, v.KODI_TYPE_SHOW, tvdb, - "tvdb", + "unknown", uniqueid) # Update the tvshow entry query = ''' @@ -631,8 +631,9 @@ class TVShows(Items): WHERE idShow = ? ''' kodicursor.execute(query, (title, plot, rating_id, - premieredate, genre, title, tvdb, - mpaa, studio, sorttitle, showid)) + premieredate, genre, title, + uniqueid, mpaa, studio, sorttitle, + showid)) else: # Update the tvshow entry query = ''' @@ -679,7 +680,8 @@ class TVShows(Items): rating, votecount) # add new uniqueid Kodi 17 - self.kodi_db.add_uniqueid(self.kodi_db.create_entry_uniqueid(), + uniqueid = self.kodi_db.create_entry_uniqueid() + self.kodi_db.add_uniqueid(uniqueid, showid, v.KODI_TYPE_SHOW, tvdb, From b715b16f059f9d9b64fc7f85c7750786ed270b36 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 09:57:24 +0200 Subject: [PATCH 07/20] Further Fix TheTVDB ID for TV shows - Partially fixes #277 --- resources/lib/itemtypes.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/lib/itemtypes.py b/resources/lib/itemtypes.py index 6c5c8433..62be1943 100644 --- a/resources/lib/itemtypes.py +++ b/resources/lib/itemtypes.py @@ -685,7 +685,7 @@ class TVShows(Items): showid, v.KODI_TYPE_SHOW, tvdb, - "tvdb") + "unknown") # Create the tvshow entry query = ''' INSERT INTO tvshow( @@ -694,8 +694,8 @@ class TVShows(Items): VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ''' kodicursor.execute(query, (showid, title, plot, rating_id, - premieredate, genre, title, tvdb, - mpaa, studio, sorttitle)) + premieredate, genre, title, + uniqueid, mpaa, studio, sorttitle)) else: # Create the tvshow entry query = ''' From 431e95706f3b244c1f550b5be14d714190c55e2b Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 10:08:23 +0200 Subject: [PATCH 08/20] Account for missing TheTVDB ids --- resources/lib/itemtypes.py | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/resources/lib/itemtypes.py b/resources/lib/itemtypes.py index 62be1943..0314fee2 100644 --- a/resources/lib/itemtypes.py +++ b/resources/lib/itemtypes.py @@ -617,12 +617,16 @@ class TVShows(Items): votecount, rating_id) # update new uniqueid Kodi 17 - uniqueid = self.kodi_db.get_uniqueid(showid, v.KODI_TYPE_SHOW) - self.kodi_db.update_uniqueid(showid, - v.KODI_TYPE_SHOW, - tvdb, - "unknown", - uniqueid) + if tvdb is not None: + uniqueid = self.kodi_db.get_uniqueid(showid, + v.KODI_TYPE_SHOW) + self.kodi_db.update_uniqueid(showid, + v.KODI_TYPE_SHOW, + tvdb, + "unknown", + uniqueid) + else: + uniqueid = -1 # Update the tvshow entry query = ''' UPDATE tvshow @@ -680,12 +684,15 @@ class TVShows(Items): rating, votecount) # add new uniqueid Kodi 17 - uniqueid = self.kodi_db.create_entry_uniqueid() - self.kodi_db.add_uniqueid(uniqueid, - showid, - v.KODI_TYPE_SHOW, - tvdb, - "unknown") + if tvdb is not None: + uniqueid = self.kodi_db.create_entry_uniqueid() + self.kodi_db.add_uniqueid(uniqueid, + showid, + v.KODI_TYPE_SHOW, + tvdb, + "unknown") + else: + uniqueid = -1 # Create the tvshow entry query = ''' INSERT INTO tvshow( From 002cbe90257bab4d92f5c8bfa0f4670883c504b1 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 10:32:04 +0200 Subject: [PATCH 09/20] Account for missing IMDB ids for movies --- resources/lib/itemtypes.py | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/resources/lib/itemtypes.py b/resources/lib/itemtypes.py index 0314fee2..b7175530 100644 --- a/resources/lib/itemtypes.py +++ b/resources/lib/itemtypes.py @@ -324,13 +324,16 @@ class Movies(Items): votecount, rating_id) # update new uniqueid Kodi 17 - uniqueid = self.kodi_db.get_uniqueid(movieid, - v.KODI_TYPE_MOVIE) - self.kodi_db.update_uniqueid(movieid, - v.KODI_TYPE_MOVIE, - imdb, - "imdb", - uniqueid) + if imdb is not None: + uniqueid = self.kodi_db.get_uniqueid(movieid, + v.KODI_TYPE_MOVIE) + self.kodi_db.update_uniqueid(movieid, + v.KODI_TYPE_MOVIE, + imdb, + "imdb", + uniqueid) + else: + uniqueid = -1 query = ''' UPDATE movie SET c00 = ?, c01 = ?, c02 = ?, c03 = ?, c04 = ?, c05 = ?, @@ -372,12 +375,15 @@ class Movies(Items): rating, votecount) # add new uniqueid Kodi 17 - uniqueid = self.kodi_db.create_entry_uniqueid() - self.kodi_db.add_uniqueid(uniqueid, - movieid, - v.KODI_TYPE_MOVIE, - imdb, - "imdb") + if imdb is not None: + uniqueid = self.kodi_db.create_entry_uniqueid() + self.kodi_db.add_uniqueid(uniqueid, + movieid, + v.KODI_TYPE_MOVIE, + imdb, + "imdb") + else: + uniqueid = -1 query = ''' INSERT INTO movie(idMovie, idFile, c00, c01, c02, c03, c04, c05, c06, c07, c09, c10, c11, c12, c14, c15, c16, From af1766697f603cd13865a9090a83787ff4515c7a Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 11:04:13 +0200 Subject: [PATCH 10/20] Remove obsolete method --- resources/lib/playutils.py | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/resources/lib/playutils.py b/resources/lib/playutils.py index 410819c5..b153086e 100644 --- a/resources/lib/playutils.py +++ b/resources/lib/playutils.py @@ -115,28 +115,6 @@ class PlayUtils(): return playurl - def fileExists(self): - - if 'Path' not in self.item: - # File has no path defined in server - return False - - # Convert path to direct play - path = self.directPlay() - log.info("Verifying path: %s" % path) - - if xbmcvfs.exists(path): - log.info("Path exists.") - return True - - elif ":" not in path: - log.info("Can't verify path, assumed linux. Still try to direct play.") - return True - - else: - log.info("Failed to find file.") - return False - def mustTranscode(self): """ Returns True if we need to transcode because From 587514a05e09c62b40fd13b4f64fc6788d183c7e Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 11:05:51 +0200 Subject: [PATCH 11/20] PEP fixes --- resources/lib/playutils.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/resources/lib/playutils.py b/resources/lib/playutils.py index b153086e..2564df16 100644 --- a/resources/lib/playutils.py +++ b/resources/lib/playutils.py @@ -292,11 +292,15 @@ class PlayUtils(): if type == "2": codec = stream.attrib.get('codec') channelLayout = stream.attrib.get('audioChannelLayout', "") - try: - track = "%s %s - %s %s" % (audioNum+1, stream.attrib['language'], codec, channelLayout) + track = "%s %s - %s %s" % (audioNum+1, + stream.attrib['language'], + codec, + channelLayout) except: - track = "%s 'unknown' - %s %s" % (audioNum+1, codec, channelLayout) + track = "%s 'unknown' - %s %s" % (audioNum+1, + codec, + channelLayout) audioStreamsList.append(index) audioStreams.append(tryEncode(track)) audioNum += 1 @@ -306,8 +310,8 @@ class PlayUtils(): try: track = "%s %s" % (subNum+1, stream.attrib['language']) except: - track = "%s 'unknown' (%s)" % (subNum+1, stream.attrib.get('codec')) - + track = "%s 'unknown' (%s)" % (subNum+1, + stream.attrib.get('codec')) default = stream.attrib.get('default') forced = stream.attrib.get('forced') downloadable = stream.attrib.get('key') @@ -334,9 +338,11 @@ class PlayUtils(): if resp > -1: # User selected audio playurlprefs['audioStreamID'] = audioStreamsList[resp] - else: # User backed out of selection - let PMS decide + else: + # User backed out of selection - let PMS decide pass - else: # There's only one audiotrack. + else: + # There's only one audiotrack. playurlprefs['audioStreamID'] = audioStreamsList[0] # Add audio boost From 57e12c423e2addb1fa060de96cf233e86d1deaf6 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 11:32:07 +0200 Subject: [PATCH 12/20] Remove obsolete import --- resources/lib/playutils.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/lib/playutils.py b/resources/lib/playutils.py index 2564df16..4f7eeebe 100644 --- a/resources/lib/playutils.py +++ b/resources/lib/playutils.py @@ -6,11 +6,9 @@ import logging from urllib import urlencode import xbmcgui -import xbmcvfs from utils import window, settings, tryEncode, language as lang import variables as v - import PlexAPI ############################################################################### From 0b7c9dc82035ccf78162ce7f3f74add99b7620a0 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 12:22:09 +0200 Subject: [PATCH 13/20] Allow for custom download from PMS, e.g. subtitles --- resources/lib/downloadutils.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/resources/lib/downloadutils.py b/resources/lib/downloadutils.py index 660c68ce..8d78d8ba 100644 --- a/resources/lib/downloadutils.py +++ b/resources/lib/downloadutils.py @@ -156,7 +156,7 @@ class DownloadUtils(): def downloadUrl(self, url, action_type="GET", postBody=None, parameters=None, authenticate=True, headerOptions=None, - verifySSL=True, timeout=None): + verifySSL=True, timeout=None, return_response=False): """ Override SSL check with verifySSL=False @@ -169,7 +169,8 @@ class DownloadUtils(): 401, ... integer if PMS answered with HTTP error 401 (unauthorized) or other http error codes xml xml etree root object, if applicable - JSON json() object, if applicable + json json() object, if applicable + if return_response=True is set (200, 201 only) """ kwargs = {'timeout': self.timeout} if authenticate is True: @@ -290,6 +291,9 @@ class DownloadUtils(): elif r.status_code in (200, 201): # 200: OK # 201: Created + if return_response is True: + # return the entire response object + return r try: # xml response r = etree.fromstring(r.content) From 04dfd78a9bc124a49d919da28b6ce8da1bc9887b Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 13:07:41 +0200 Subject: [PATCH 14/20] Fix for not detecting external subtitle language --- resources/lib/PlexAPI.py | 59 ++++++++++++++++++++++++++++++-------- resources/lib/variables.py | 3 ++ 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/resources/lib/PlexAPI.py b/resources/lib/PlexAPI.py index c80e6992..1d5261a6 100644 --- a/resources/lib/PlexAPI.py +++ b/resources/lib/PlexAPI.py @@ -43,7 +43,7 @@ from os import path as os_path import xbmcgui from xbmc import sleep, executebuiltin -from xbmcvfs import exists +from xbmcvfs import exists, mkdirs import clientinfo as client from downloadutils import DownloadUtils @@ -2301,24 +2301,58 @@ class API(): return kodiindex = 0 for stream in mediastreams: - index = stream.attrib['id'] # Since plex returns all possible tracks together, have to pull - # only external subtitles. + # only external subtitles - only for these a 'key' exists + if stream.attrib.get('streamType') != "3": + # Not a subtitle + continue + # Only set for additional external subtitles NOT lying beside video key = stream.attrib.get('key') - # IsTextSubtitleStream if true, is available to download from plex. - if stream.attrib.get('streamType') == "3" and key: - # Direct stream - url = ("%s%s" % (self.server, key)) - url = self.addPlexCredentialsToUrl(url) + # Only set for dedicated subtitle files lying beside video + # ext = stream.attrib.get('format') + if key: + # We do know the language - temporarily download + if stream.attrib.get('languageCode') is not None: + path = self.__download_external_subtitles( + "{server}%s" % key, + "subtitle.%s.%s" % (stream.attrib['languageCode'], + stream.attrib['codec'])) + # We don't know the language - no need to download + else: + path = self.addPlexCredentialsToUrl( + "%s%s" % (self.server, key)) # map external subtitles for mapping - mapping[kodiindex] = index - externalsubs.append(url) + mapping[kodiindex] = stream.attrib['id'] + externalsubs.append(path) kodiindex += 1 mapping = dumps(mapping) window('plex_%s.indexMapping' % playurl, value=mapping) log.info('Found external subs: %s' % externalsubs) return externalsubs + @staticmethod + def __download_external_subtitles(url, filename): + """ + One cannot pass the subtitle language for ListItems. Workaround; will + download the subtitle at url to the Kodi PKC directory in a temp dir + + Returns the path to the downloaded subtitle or None + """ + if not exists(v.EXTERNAL_SUBTITLE_TEMP_PATH): + mkdirs(v.EXTERNAL_SUBTITLE_TEMP_PATH) + path = os_path.join(v.EXTERNAL_SUBTITLE_TEMP_PATH, filename) + r = DownloadUtils().downloadUrl(url, return_response=True) + try: + r.status_code + except AttributeError: + log.error('Could not temporarily download subtitle %s' % url) + return + else: + r.encoding = 'utf-8' + with open(path, 'wb') as f: + f.write(r.content) + return path + def GetKodiPremierDate(self): """ Takes Plex' originallyAvailableAt of the form "yyyy-mm-dd" and returns @@ -2601,6 +2635,7 @@ class API(): # Append external subtitles to stream playmethod = window('%s.playmethod' % plexitem) + # Direct play automatically appends external + # BUT: Plex may add additional subtitles NOT if playmethod in ("DirectStream", "DirectPlay"): - subtitles = self.externalSubs(playurl) - listitem.setSubtitles(subtitles) + listitem.setSubtitles(self.externalSubs(playurl)) diff --git a/resources/lib/variables.py b/resources/lib/variables.py index 8b1b8e2d..0e032981 100644 --- a/resources/lib/variables.py +++ b/resources/lib/variables.py @@ -95,6 +95,9 @@ DB_TEXTURE_PATH = tryDecode(xbmc.translatePath( DB_PLEX_PATH = tryDecode(xbmc.translatePath("special://database/plex.db")) +EXTERNAL_SUBTITLE_TEMP_PATH = tryDecode(xbmc.translatePath( + "special://profile/addon_data/%s/temp/" % ADDON_ID)) + # Multiply Plex time by this factor to receive Kodi time PLEX_TO_KODI_TIMEFACTOR = 1.0 / 1000.0 From a4627ae1cbf220a9ebe8bb0164f8b2c5ecf27aa6 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 13:10:28 +0200 Subject: [PATCH 15/20] Add description --- resources/lib/PlexAPI.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/PlexAPI.py b/resources/lib/PlexAPI.py index 1d5261a6..ba5f27a5 100644 --- a/resources/lib/PlexAPI.py +++ b/resources/lib/PlexAPI.py @@ -2636,6 +2636,6 @@ class API(): # Append external subtitles to stream playmethod = window('%s.playmethod' % plexitem) # Direct play automatically appends external - # BUT: Plex may add additional subtitles NOT + # BUT: Plex may add additional subtitles NOT lying right next to video if playmethod in ("DirectStream", "DirectPlay"): listitem.setSubtitles(self.externalSubs(playurl)) From 56400e54da7da07eaf608da598ceb2e7912a1ff6 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 14:22:47 +0200 Subject: [PATCH 16/20] Change Plex transcoding profile to Android --- resources/lib/PlexAPI.py | 34 +++++++++++++++++----------------- resources/lib/playutils.py | 3 --- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/resources/lib/PlexAPI.py b/resources/lib/PlexAPI.py index ba5f27a5..7abc874b 100644 --- a/resources/lib/PlexAPI.py +++ b/resources/lib/PlexAPI.py @@ -2258,37 +2258,37 @@ class API(): return url # For Transcoding + headers = { + 'X-Plex-Platform': 'Android', + 'X-Plex-Platform-Version': '7.0', + 'X-Plex-Product': 'Plex for Android', + 'X-Plex-Version': '5.8.0.475' + } # Path/key to VIDEO item of xml PMS response is needed, not part path = self.item.attrib['key'] transcodePath = self.server + \ '/video/:/transcode/universal/start.m3u8?' args = { + 'audioBoost': settings('audioBoost'), + 'autoAdjustQuality': 0, + 'directPlay': 0, + 'directStream': 1, 'protocol': 'hls', # seen in the wild: 'dash', 'http', 'hls' 'session': window('plex_client_Id'), 'fastSeek': 1, 'path': path, 'mediaIndex': self.mediastream, 'partIndex': self.part, + 'hasMDE': 1, + 'location': 'lan', + 'mediaBufferSize': '16384', # 'copyts': 1, # 'offset': 0, # Resume point } - # Seem like PHT to let the PMS use the transcoding profile - xargs['X-Plex-Device'] = 'Plex Home Theater' - # Currently not used! - if action == "DirectStream": - argsUpdate = { - 'directPlay': '0', - 'directStream': '1', - } - args.update(argsUpdate) - elif action == 'Transcode': - argsUpdate = { - 'directPlay': '0', - 'directStream': '0' - } - log.debug("Setting transcode quality to: %s" % quality) - args.update(quality) - args.update(argsUpdate) + # Look like Android to let the PMS use the transcoding profile + xargs.update(headers) + log.debug("Setting transcode quality to: %s" % quality) + args.update(quality) url = transcodePath + urlencode(xargs) + '&' + urlencode(args) return url diff --git a/resources/lib/playutils.py b/resources/lib/playutils.py index 4f7eeebe..d047d269 100644 --- a/resources/lib/playutils.py +++ b/resources/lib/playutils.py @@ -343,9 +343,6 @@ class PlayUtils(): # There's only one audiotrack. playurlprefs['audioStreamID'] = audioStreamsList[0] - # Add audio boost - playurlprefs['audioBoost'] = settings('audioBoost') - selectSubsIndex = None if subNum > 1: if (settings('pickPlexSubtitles') == 'true' and From 72ed20e47f0d025ffc3d5176add909998fc125c8 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 19:51:10 +0200 Subject: [PATCH 17/20] Big transcoding overhaul - Fixes #278 --- .../resource.language.en_gb/strings.po | 27 ++- resources/lib/PlexAPI.py | 5 +- resources/lib/kodimonitor.py | 38 ++-- resources/lib/playbackutils.py | 17 +- resources/lib/player.py | 3 +- resources/lib/playutils.py | 204 ++++++++++-------- 6 files changed, 169 insertions(+), 125 deletions(-) diff --git a/resources/language/resource.language.en_gb/strings.po b/resources/language/resource.language.en_gb/strings.po index 5bbcc7a3..07db049c 100644 --- a/resources/language/resource.language.en_gb/strings.po +++ b/resources/language/resource.language.en_gb/strings.po @@ -1851,7 +1851,6 @@ msgctxt "#39702" msgid "Browse by folder" msgstr "" - # For use with addon.xml (PKC metadata for Kodi, e.g. description) # Addon Summary msgctxt "#39703" @@ -1869,3 +1868,29 @@ msgstr "" msgctxt "#39705" msgid "Use at your own risk" msgstr "" + + +# If user gets prompted to choose between several subtitles. Leave the number one at the beginning of the string! +msgctxt "#39706" +msgid "1 No subtitles" +msgstr "" + +# If user gets prompted to choose between several audio/subtitle tracks and language is unknown +msgctxt "#39707" +msgid "unknown" +msgstr "" + +# If user gets prompted to choose between several subtitles and Plex adds the "default" flag +msgctxt "#39708" +msgid "Default" +msgstr "" + +# If user gets prompted to choose between several subtitles and Plex adds the "forced" flag +msgctxt "#39709" +msgid "Forced" +msgstr "" + +# If user gets prompted to choose between several subtitles the subtitle cannot be downloaded (has no 'key' attribute from the PMS), the subtitle needs to be burned in +msgctxt "#39710" +msgid "burn-in" +msgstr "" diff --git a/resources/lib/PlexAPI.py b/resources/lib/PlexAPI.py index 7abc874b..7067fd08 100644 --- a/resources/lib/PlexAPI.py +++ b/resources/lib/PlexAPI.py @@ -2282,6 +2282,7 @@ class API(): 'hasMDE': 1, 'location': 'lan', 'mediaBufferSize': '16384', + 'subtitleSize': settings('subtitleSize') # 'copyts': 1, # 'offset': 0, # Resume point } @@ -2313,7 +2314,7 @@ class API(): if key: # We do know the language - temporarily download if stream.attrib.get('languageCode') is not None: - path = self.__download_external_subtitles( + path = self.download_external_subtitles( "{server}%s" % key, "subtitle.%s.%s" % (stream.attrib['languageCode'], stream.attrib['codec'])) @@ -2331,7 +2332,7 @@ class API(): return externalsubs @staticmethod - def __download_external_subtitles(url, filename): + def download_external_subtitles(url, filename): """ One cannot pass the subtitle language for ListItems. Workaround; will download the subtitle at url to the Kodi PKC directory in a temp dir diff --git a/resources/lib/kodimonitor.py b/resources/lib/kodimonitor.py index 0dc17443..4e19721e 100644 --- a/resources/lib/kodimonitor.py +++ b/resources/lib/kodimonitor.py @@ -106,7 +106,8 @@ class KodiMonitor(Monitor): log.error("Could not find itemid in plex database for a " "video library update") else: - # Stop from manually marking as watched unwatched, with actual playback. + # Stop from manually marking as watched unwatched, with + # actual playback. if window('plex_skipWatched%s' % itemid) == "true": # property is set in player.py window('plex_skipWatched%s' % itemid, clear=True) @@ -171,11 +172,11 @@ class KodiMonitor(Monitor): # Try to get a Kodi ID # If PKC was used - native paths, not direct paths - plexid = window('plex_%s.itemid' % tryEncode(currentFile)) + plex_id = window('plex_%s.itemid' % tryEncode(currentFile)) # Get rid of the '' if the window property was not set - plexid = None if not plexid else plexid + plex_id = None if not plex_id else plex_id kodiid = None - if plexid is None: + if plex_id is None: log.debug('Did not get Plex id from window properties') try: kodiid = data['item']['id'] @@ -183,30 +184,39 @@ class KodiMonitor(Monitor): log.debug('Did not get a Kodi id from Kodi, darn') # For direct paths, if we're not streaming something # When using Widgets, Kodi doesn't tell us shit so we need this hack - if (kodiid is None and plexid is None and typus != 'song' + if (kodiid is None and plex_id is None and typus != 'song' and not currentFile.startswith('http')): (kodiid, typus) = get_kodiid_from_filename(currentFile) if kodiid is None: return - if plexid is None: + if plex_id is None: # Get Plex' item id with plexdb.Get_Plex_DB() as plexcursor: plex_dbitem = plexcursor.getItem_byKodiId(kodiid, typus) try: - plexid = plex_dbitem[0] + plex_id = plex_dbitem[0] except TypeError: log.info("No Plex id returned for kodiid %s. Aborting playback" " report" % kodiid) return log.debug("Found Plex id %s for Kodi id %s for type %s" - % (plexid, kodiid, typus)) + % (plex_id, kodiid, typus)) + + # Switch subtitle tracks if applicable + subtitle = window('plex_%s.subtitle' % tryEncode(currentFile)) + if window(tryEncode('plex_%s.playmethod' % currentFile)) \ + == 'Transcode' and subtitle: + if window('plex_%s.subtitle' % currentFile) == 'None': + self.xbmcplayer.showSubtitles(False) + else: + self.xbmcplayer.setSubtitleStream(int(subtitle)) # Set some stuff if Kodi initiated playback if ((settings('useDirectPaths') == "1" and not typus == "song") or (typus == "song" and settings('enableMusic') == "true")): - if self.StartDirectPath(plexid, + if self.StartDirectPath(plex_id, typus, tryEncode(currentFile)) is False: log.error('Could not initiate monitoring; aborting') @@ -214,19 +224,19 @@ class KodiMonitor(Monitor): # Save currentFile for cleanup later and to be able to access refs window('plex_lastPlayedFiled', value=currentFile) - window('plex_currently_playing_itemid', value=plexid) - window("plex_%s.itemid" % tryEncode(currentFile), value=plexid) + window('plex_currently_playing_itemid', value=plex_id) + window("plex_%s.itemid" % tryEncode(currentFile), value=plex_id) log.info('Finish playback startup') - def StartDirectPath(self, plexid, type, currentFile): + def StartDirectPath(self, plex_id, type, currentFile): """ Set some additional stuff if playback was initiated by Kodi, not PKC """ - xml = self.doUtils('{server}/library/metadata/%s' % plexid) + xml = self.doUtils('{server}/library/metadata/%s' % plex_id) try: xml[0].attrib except: - log.error('Did not receive a valid XML for plexid %s.' % plexid) + log.error('Did not receive a valid XML for plex_id %s.' % plex_id) return False # Setup stuff, because playback was started by Kodi, not PKC api = API(xml[0]) diff --git a/resources/lib/playbackutils.py b/resources/lib/playbackutils.py index fabbda83..56a45695 100644 --- a/resources/lib/playbackutils.py +++ b/resources/lib/playbackutils.py @@ -75,10 +75,7 @@ class PlaybackUtils(): playmethod = window('plex_%s.playmethod' % playurl) if playmethod == "Transcode": - window('plex_%s.playmethod' % playurl, clear=True) - playurl = tryEncode(playutils.audioSubsPref( - listitem, tryDecode(playurl))) - window('plex_%s.playmethod' % playurl, "Transcode") + playutils.audioSubsPref(listitem, tryDecode(playurl)) listitem.setPath(playurl) api.set_playback_win_props(playurl, listitem) result.listitem = listitem @@ -195,12 +192,7 @@ class PlaybackUtils(): # Would be using the direct path log.debug("Adding contextmenu item for direct paths") if window('plex_%s.playmethod' % playurl) == "Transcode": - window('plex_%s.playmethod' % playurl, - clear=True) - playurl = tryEncode(playutils.audioSubsPref( - listitem, tryDecode(playurl))) - window('plex_%s.playmethod' % playurl, - value="Transcode") + playutils.audioSubsPref(listitem, tryDecode(playurl)) api.CreateListItemFromPlexItem(listitem) api.set_playback_win_props(playurl, listitem) api.set_listitem_artwork(listitem) @@ -246,10 +238,7 @@ class PlaybackUtils(): # For transcoding only, ask for audio/subs pref if (window('plex_%s.playmethod' % playurl) == "Transcode" and not contextmenu_play): - window('plex_%s.playmethod' % playurl, clear=True) - playurl = tryEncode(playutils.audioSubsPref( - listitem, tryDecode(playurl))) - window('plex_%s.playmethod' % playurl, value="Transcode") + playutils.audioSubsPref(listitem, tryDecode(playurl)) listitem.setPath(playurl) api.set_playback_win_props(playurl, listitem) diff --git a/resources/lib/player.py b/resources/lib/player.py index bba39909..b5f2389f 100644 --- a/resources/lib/player.py +++ b/resources/lib/player.py @@ -396,7 +396,8 @@ class Player(xbmc.Player): '%s.type' % plex_item, '%s.runtime' % plex_item, '%s.playcount' % plex_item, - '%s.playlistPosition' % plex_item + '%s.playlistPosition' % plex_item, + '%s.subtitle' % plex_item, ) for item in cleanup: window(item, clear=True) diff --git a/resources/lib/playutils.py b/resources/lib/playutils.py index d047d269..046e5a4f 100644 --- a/resources/lib/playutils.py +++ b/resources/lib/playutils.py @@ -3,11 +3,9 @@ ############################################################################### import logging -from urllib import urlencode +from downloadutils import DownloadUtils -import xbmcgui - -from utils import window, settings, tryEncode, language as lang +from utils import window, settings, tryEncode, language as lang, dialog import variables as v import PlexAPI @@ -24,6 +22,7 @@ class PlayUtils(): self.item = item self.API = PlexAPI.API(item) + self.doUtils = DownloadUtils().downloadUrl self.userid = window('currUserId') self.server = window('pms_server') @@ -254,131 +253,150 @@ class PlayUtils(): return res[chosen] def audioSubsPref(self, listitem, url, part=None): - dialog = xbmcgui.Dialog() - # For transcoding only - # Present the list of audio to select from - audioStreamsList = [] - audioStreams = [] - # audioStreamsChannelsList = [] - subtitleStreamsList = [] - subtitleStreams = ['1 No subtitles'] - downloadableStreams = [] - # selectAudioIndex = "" - selectSubsIndex = "" - playurlprefs = {} + """ + For transcoding only - # Set part where we're at - self.API.setPartNumber(part) + Called at the very beginning of play; used to change audio and subtitle + stream by a PUT request to the PMS + """ + # Set media and part where we're at + if self.API.mediastream is None: + self.API.getMediastreamNumber() if part is None: part = 0 try: - mediastreams = self.item[0][part] - except (TypeError, KeyError, IndexError): - return url - - audioNum = 0 + mediastreams = self.item[self.API.mediastream][part] + except (TypeError, IndexError): + log.error('Could not get media %s, part %s' + % (self.API.mediastream, part)) + return + part_id = mediastreams.attrib['id'] + audio_streams_list = [] + audio_streams = [] + subtitle_streams_list = [] + # No subtitles as an option + subtitle_streams = [lang(39706)] + downloadable_streams = [] + download_subs = [] + # selectAudioIndex = "" + select_subs_index = "" + audio_numb = 0 # Remember 'no subtitles' - subNum = 1 - defaultSub = None + sub_num = 1 + default_sub = None + for stream in mediastreams: # Since Plex returns all possible tracks together, have to sort # them. index = stream.attrib.get('id') - type = stream.attrib.get('streamType') - + typus = stream.attrib.get('streamType') # Audio - if type == "2": + if typus == "2": codec = stream.attrib.get('codec') channelLayout = stream.attrib.get('audioChannelLayout', "") try: - track = "%s %s - %s %s" % (audioNum+1, + track = "%s %s - %s %s" % (audio_numb+1, stream.attrib['language'], codec, channelLayout) except: - track = "%s 'unknown' - %s %s" % (audioNum+1, - codec, - channelLayout) - audioStreamsList.append(index) - audioStreams.append(tryEncode(track)) - audioNum += 1 + track = "%s %s - %s %s" % (audio_numb+1, + lang(39707), # unknown + codec, + channelLayout) + audio_streams_list.append(index) + audio_streams.append(tryEncode(track)) + audio_numb += 1 # Subtitles - elif type == "3": + elif typus == "3": try: - track = "%s %s" % (subNum+1, stream.attrib['language']) - except: - track = "%s 'unknown' (%s)" % (subNum+1, - stream.attrib.get('codec')) + track = "%s %s" % (sub_num+1, stream.attrib['language']) + except KeyError: + track = "%s %s (%s)" % (sub_num+1, + lang(39707), # unknown + stream.attrib.get('codec')) default = stream.attrib.get('default') forced = stream.attrib.get('forced') downloadable = stream.attrib.get('key') if default: - track = "%s - Default" % track + track = "%s - %s" % (track, lang(39708)) # Default if forced: - track = "%s - Forced" % track + track = "%s - %s" % (track, lang(39709)) # Forced if downloadable: - downloadableStreams.append(index) + # We do know the language - temporarily download + if 'language' in stream.attrib: + path = self.API.download_external_subtitles( + '{server}%s' % stream.attrib['key'], + "subtitle.%s.%s" % (stream.attrib['language'], + stream.attrib['codec'])) + # We don't know the language - no need to download + else: + path = self.API.addPlexCredentialsToUrl( + "%s%s" % (self.server, stream.attrib['key'])) + downloadable_streams.append(index) + download_subs.append(tryEncode(path)) else: - track = "%s (burn-in)" % track + track = "%s (%s)" % (track, lang(39710)) # burn-in if stream.attrib.get('selected') == '1' and downloadable: # Only show subs without asking user if they can be # turned off - defaultSub = index + default_sub = index - subtitleStreamsList.append(index) - subtitleStreams.append(tryEncode(track)) - subNum += 1 + subtitle_streams_list.append(index) + subtitle_streams.append(tryEncode(track)) + sub_num += 1 - if audioNum > 1: - resp = dialog.select(lang(33013), audioStreams) + if audio_numb > 1: + resp = dialog('select', lang(33013), audio_streams) if resp > -1: - # User selected audio - playurlprefs['audioStreamID'] = audioStreamsList[resp] - else: - # User backed out of selection - let PMS decide - pass + # User selected some audio track + args = { + 'audioStreamID': audio_streams_list[resp], + 'allParts': 1 + } + self.doUtils('{server}/library/parts/%s' % part_id, + action_type='PUT', + parameters=args) + + if sub_num == 1: + # No subtitles + return + + select_subs_index = None + if (settings('pickPlexSubtitles') == 'true' and + default_sub is not None): + log.info('Using default Plex subtitle: %s' % default_sub) + select_subs_index = default_sub else: - # There's only one audiotrack. - playurlprefs['audioStreamID'] = audioStreamsList[0] - - selectSubsIndex = None - if subNum > 1: - if (settings('pickPlexSubtitles') == 'true' and - defaultSub is not None): - log.info('Using default Plex subtitle: %s' % defaultSub) - selectSubsIndex = defaultSub + resp = dialog('select', lang(33014), subtitle_streams) + if resp > 0: + select_subs_index = subtitle_streams_list[resp-1] else: - resp = dialog.select(lang(33014), subtitleStreams) - if resp > 0: - selectSubsIndex = subtitleStreamsList[resp-1] - else: - # User selected no subtitles or backed out of dialog - playurlprefs["skipSubtitles"] = 1 - if selectSubsIndex is not None: - # Load subtitles in the listitem if downloadable - if selectSubsIndex in downloadableStreams: - sub_url = self.API.addPlexHeadersToUrl( - "%s/library/streams/%s" - % (self.server, selectSubsIndex)) - log.info("Downloadable sub: %s: %s" - % (selectSubsIndex, sub_url)) - listitem.setSubtitles([tryEncode(sub_url)]) - # Don't additionally burn in subtitles - playurlprefs["skipSubtitles"] = 1 - else: - log.info('Need to burn in subtitle %s' % selectSubsIndex) - playurlprefs["subtitleStreamID"] = selectSubsIndex - playurlprefs["subtitleSize"] = settings('subtitleSize') + # User selected no subtitles or backed out of dialog + select_subs_index = '' - url += '&' + urlencode(playurlprefs) + log.debug('Adding external subtitles: %s' % download_subs) + # Enable Kodi to switch autonomously to downloadable subtitles + if download_subs: + listitem.setSubtitles(download_subs) - # Get number of channels for selected audio track - # audioChannels = audioStreamsChannelsList.get(selectAudioIndex, 0) - # if audioChannels > 2: - # playurlprefs += "&AudioBitrate=384000" - # else: - # playurlprefs += "&AudioBitrate=192000" + if select_subs_index in downloadable_streams: + for i, stream in enumerate(downloadable_streams): + if stream == select_subs_index: + # Set the correct subtitle + window('plex_%s.subtitle' % tryEncode(url), value=str(i)) + break + # Don't additionally burn in subtitles + select_subs_index = '' + else: + window('plex_%s.subtitle' % tryEncode(url), value='None') - return url + args = { + 'subtitleStreamID': select_subs_index, + 'allParts': 1 + } + self.doUtils('{server}/library/parts/%s' % part_id, + action_type='PUT', + parameters=args) From 65c31b1eaaeea2f9e10186bd8a3a470f401c2d02 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 20:29:28 +0200 Subject: [PATCH 18/20] Use Kodi video cache setting for transcoding --- resources/lib/PlexAPI.py | 1 - resources/lib/initialsetup.py | 13 +++++++++++- resources/lib/playutils.py | 3 ++- resources/lib/utils.py | 37 +++++++++++++++++++++++++++++++++-- resources/settings.xml | 1 + 5 files changed, 50 insertions(+), 5 deletions(-) diff --git a/resources/lib/PlexAPI.py b/resources/lib/PlexAPI.py index 7067fd08..b466d1b6 100644 --- a/resources/lib/PlexAPI.py +++ b/resources/lib/PlexAPI.py @@ -2281,7 +2281,6 @@ class API(): 'partIndex': self.part, 'hasMDE': 1, 'location': 'lan', - 'mediaBufferSize': '16384', 'subtitleSize': settings('subtitleSize') # 'copyts': 1, # 'offset': 0, # Resume point diff --git a/resources/lib/initialsetup.py b/resources/lib/initialsetup.py index 9890fb74..534241aa 100644 --- a/resources/lib/initialsetup.py +++ b/resources/lib/initialsetup.py @@ -6,7 +6,8 @@ import logging import xbmc import xbmcgui -from utils import settings, window, language as lang, tryEncode +from utils import settings, window, language as lang, tryEncode, \ + get_advancessettings_xml_setting import downloadutils from userclient import UserClient @@ -399,6 +400,16 @@ class InitialSetup(): log.info("Initial setup called.") dialog = self.dialog + # Get current Kodi video cache setting + cache = get_advancessettings_xml_setting(['cache', 'memorysize']) + if cache is not None: + cache = str(cache.text) + else: + # Kodi default cache + cache = '20971520' + log.info('Current Kodi video memory cache in bytes: %s' % cache) + settings('kodi_video_cache', value=cache) + # Optionally sign into plex.tv. Will not be called on very first run # as plexToken will be '' settings('plex_status', value='Not logged in to plex.tv') diff --git a/resources/lib/playutils.py b/resources/lib/playutils.py index 046e5a4f..6f6415de 100644 --- a/resources/lib/playutils.py +++ b/resources/lib/playutils.py @@ -59,7 +59,8 @@ class PlayUtils(): quality={ 'maxVideoBitrate': self.get_bitrate(), 'videoResolution': self.get_resolution(), - 'videoQuality': '100' + 'videoQuality': '100', + 'mediaBufferSize': int(settings('kodi_video_cache'))/1024, })) # Set playmethod property window('plex_%s.playmethod' % playurl, value="Transcode") diff --git a/resources/lib/utils.py b/resources/lib/utils.py index bdfe6e9d..e416fe59 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -548,6 +548,40 @@ def __setSubElement(element, subelement): return answ +def get_advancessettings_xml_setting(node_list): + """ + Returns the etree element for nodelist (if it exists) and None if not set + + node_list is a list of node names starting from the outside, ignoring the + outter advancedsettings. Example nodelist=['video', 'busydialogdelayms'] + for the following xml would return the etree Element: + + 750 + + Example xml: + + + + + + """ + path = tryDecode(xbmc.translatePath("special://profile/")) + try: + xmlparse = etree.parse("%sadvancedsettings.xml" % path) + except: + log.debug('Could not parse advancedsettings.xml, returning None') + return + root = xmlparse.getroot() + + for node in node_list: + root = root.find(node) + if root is None: + break + return root + + def advancedSettingsXML(): """ Kodi tweaks @@ -595,12 +629,11 @@ def sourcesXML(): try: xmlparse = etree.parse(xmlpath) - except: # Document is blank or missing + except: # Document is blank or missing root = etree.Element('sources') else: root = xmlparse.getroot() - video = root.find('video') if video is None: video = etree.SubElement(root, 'video') diff --git a/resources/settings.xml b/resources/settings.xml index 429c7173..bb80d34e 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -110,6 +110,7 @@ + From f4ad85cfeb1a3486bba6e733bc0223be0e9dc4f7 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 20:45:02 +0200 Subject: [PATCH 19/20] Fix UnicodeDecodeError on user switch - Partially fixes #285 --- resources/lib/variables.py | 2 +- service.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/resources/lib/variables.py b/resources/lib/variables.py index 0e032981..98c345f6 100644 --- a/resources/lib/variables.py +++ b/resources/lib/variables.py @@ -27,7 +27,7 @@ ADDON_VERSION = _ADDON.getAddonInfo('version') KODILANGUAGE = xbmc.getLanguage(xbmc.ISO_639_1) KODIVERSION = int(xbmc.getInfoLabel("System.BuildVersion")[:2]) KODILONGVERSION = xbmc.getInfoLabel('System.BuildVersion') -KODI_PROFILE = xbmc.translatePath("special://profile") +KODI_PROFILE = tryDecode(xbmc.translatePath("special://profile")) if xbmc.getCondVisibility('system.platform.osx'): PLATFORM = "MacOSX" diff --git a/service.py b/service.py index 696a87b9..1c7fc843 100644 --- a/service.py +++ b/service.py @@ -30,7 +30,7 @@ sys_path.append(_base_resource) ############################################################################### -from utils import settings, window, language as lang, dialog +from utils import settings, window, language as lang, dialog, tryDecode from userclient import UserClient import initialsetup from kodimonitor import KodiMonitor @@ -164,11 +164,12 @@ class Service(): counter = 0 while not monitor.abortRequested(): - if window('plex_kodiProfile') != kodiProfile: + if tryDecode(window('plex_kodiProfile')) != kodiProfile: # Profile change happened, terminate this thread and others log.warn("Kodi profile was: %s and changed to: %s. " "Terminating old PlexKodiConnect thread." - % (kodiProfile, window('plex_kodiProfile'))) + % (kodiProfile, + tryDecode(window('plex_kodiProfile')))) break # Before proceeding, need to make sure: From b6d95e55c4878fc3d472b2c7303351250db74a02 Mon Sep 17 00:00:00 2001 From: tomkat83 Date: Mon, 1 May 2017 20:49:43 +0200 Subject: [PATCH 20/20] Version bump --- README.md | 2 +- addon.xml | 15 +++++++++++++-- changelog.txt | 11 +++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2dd8f582..2dc54eb6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![stable version](https://img.shields.io/badge/stable_version-1.7.7-blue.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect/bin/repository.plexkodiconnect/repository.plexkodiconnect-1.0.0.zip) -[![beta version](https://img.shields.io/badge/beta_version-1.7.8-red.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect_BETA/bin-BETA/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.0.zip) +[![beta version](https://img.shields.io/badge/beta_version-1.7.9-red.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect_BETA/bin-BETA/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.0.zip) [![Installation](https://img.shields.io/badge/wiki-installation-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/Installation) [![FAQ](https://img.shields.io/badge/wiki-FAQ-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/faq) diff --git a/addon.xml b/addon.xml index 9159bd5e..1f8c79cb 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + @@ -44,7 +44,18 @@ Gebruik op eigen risico 使用風險由您自己承擔 Usar a su propio riesgo - version 1.7.8 (beta only) + version 1.7.9 (beta only) +- Big transcoding overhaul +- Fix for not detecting external subtitle language +- Change Plex transcoding profile to Android +- Use Kodi video cache setting for transcoding +- Fix TheTVDB ID for TV shows +- Account for missing IMDB ids for movies +- Account for missing TheTVDB ids +- Fix UnicodeDecodeError on user switch +- Update English, Spanish and German + +version 1.7.8 (beta only) - Fix IMDB id for movies (resync by going to the PKC settings, Advanced, then Repair Local Database) - Increase timeouts for PMS, should fix some connection issues - Move translations to new strings.po system diff --git a/changelog.txt b/changelog.txt index 72cbea82..aa2c9e14 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,14 @@ +version 1.7.9 (beta only) +- Big transcoding overhaul +- Fix for not detecting external subtitle language +- Change Plex transcoding profile to Android +- Use Kodi video cache setting for transcoding +- Fix TheTVDB ID for TV shows +- Account for missing IMDB ids for movies +- Account for missing TheTVDB ids +- Fix UnicodeDecodeError on user switch +- Update English, Spanish and German + version 1.7.8 (beta only) - Fix IMDB id for movies (resync by going to the PKC settings, Advanced, then Repair Local Database) - Increase timeouts for PMS, should fix some connection issues