From 58ab6432f6ae126d3d89002371a70daf353fd12c Mon Sep 17 00:00:00 2001 From: im85288 Date: Tue, 16 Jun 2015 20:38:36 +0100 Subject: [PATCH 01/39] remove beta support and use latest as default so that future changes hopefully are not needed --- resources/lib/Utils.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/resources/lib/Utils.py b/resources/lib/Utils.py index 40bba457..3392a2ed 100644 --- a/resources/lib/Utils.py +++ b/resources/lib/Utils.py @@ -73,12 +73,7 @@ def getKodiVideoDBPath(): dbVersion = "90" elif kodibuild.startswith("15"): # Isengard - if "BETA1" in kodibuild: - # Beta 1 - dbVersion = "92" - elif "BETA2" in kodibuild: - # Beta 2 - dbVersion = "93" + dbVersion = "93" else: # Not a compatible build xbmc.log("This Kodi version is incompatible. Current version: %s" % kodibuild) From 0dc19eb87f7cb20f4d9bfe3e41aafc6a2beeb794 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Tue, 16 Jun 2015 18:39:12 -0500 Subject: [PATCH 02/39] Fix ratio poster 1000*1500 Should be correct with and without cover art. --- resources/lib/API.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/resources/lib/API.py b/resources/lib/API.py index 03e3b0f1..459b5bb4 100644 --- a/resources/lib/API.py +++ b/resources/lib/API.py @@ -373,9 +373,14 @@ class API(): query = "" height = "10000" width = "10000" + dimensions = "" played = "0" totalbackdrops = 0 + # Force ratio + if type == "Primary": + dimensions = "&Width=1000&Height=1500" + if originalType =="BackdropNoIndicators" and index == "0" and data.get("BackdropImageTags") != None: totalbackdrops = len(data.get("BackdropImageTags")) if totalbackdrops != 0: @@ -391,9 +396,8 @@ class API(): if imageTag == None: imageTag = "e3ab56fe27d389446754d0fb04910a34" - - artwork = "%s/mediabrowser/Items/%s/Images/%s/%s?MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" % (server, id, type, index, width, height, imageTag, query) - #artwork = "%s/mediabrowser/Items/%s/Images/%s/%s/%s/original/%s/%s/%s?%s" % (server, id, type, index, imageTag, width, height, played, query) <- broken + + artwork = "%s/mediabrowser/Items/%s/Images/%s/%s?MaxWidth=%s&MaxHeight=%s%s&Format=original&Tag=%s%s" % (server, id, type, index, width, height, dimensions, imageTag, query) if addonSettings.getSetting('disableCoverArt')=='true': artwork = artwork + "&EnableImageEnhancers=false" From 3c1ce16da00c4aa556d9252b2183fcb897b80666 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Tue, 16 Jun 2015 19:32:42 -0500 Subject: [PATCH 03/39] Use proper DB path without guessing. --- resources/lib/Utils.py | 62 +++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 40 deletions(-) diff --git a/resources/lib/Utils.py b/resources/lib/Utils.py index 3392a2ed..8f81f5e2 100644 --- a/resources/lib/Utils.py +++ b/resources/lib/Utils.py @@ -63,49 +63,31 @@ def KodiSQL(type="video"): def getKodiVideoDBPath(): - kodibuild = xbmc.getInfoLabel("System.BuildVersion") - - if kodibuild.startswith("13"): - # Gotham - dbVersion = "78" - elif kodibuild.startswith("14"): - # Helix - dbVersion = "90" - elif kodibuild.startswith("15"): - # Isengard - dbVersion = "93" - else: - # Not a compatible build - xbmc.log("This Kodi version is incompatible. Current version: %s" % kodibuild) - - dbPath = xbmc.translatePath("special://profile/Database/MyVideos" + dbVersion + ".db") + dirs, files = xbmcvfs.listdir("special://database") + dbVersion = "" - return dbPath + for database in files: + if "MyVideos" in database: + dbVersion = database + + dbPath = xbmc.translatePath("special://database/%s" % dbVersion) + logMsg("Utils", "Path to Video database: %s" % dbPath, 0) + + return dbPath def getKodiMusicDBPath(): - if xbmc.getInfoLabel("System.BuildVersion").startswith("13"): - #gotham - dbVersion = "46" - elif xbmc.getInfoLabel("System.BuildVersion").startswith("15"): - #isengard - dbVersion = "52" - else: - #helix - dbVersion = "48" - - dbPath = xbmc.translatePath("special://profile/Database/MyMusic" + dbVersion + ".db") - - return dbPath - - -def checkAuthentication(): - #check authentication - if addonSettings.getSetting('username') != "" and addonSettings.getSetting('ipaddress') != "": - try: - downloadUtils.authenticate() - except Exception, e: - logMsg("Emby authentication failed",e) - pass + + dirs, files = xbmcvfs.listdir("special://database") + dbVersion = "" + + for database in files: + if "MyMusic" in database: + dbVersion = database + + dbPath = xbmc.translatePath("special://database/%s" % dbVersion) + logMsg("Utils", "Path to Music database: %s" % dbPath, 0) + + return dbPath def prettifyXml(elem): rough_string = etree.tostring(elem, "utf-8") From 7f2610642b1dd26c849869deb410bada9523551f Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Tue, 16 Jun 2015 20:24:54 -0500 Subject: [PATCH 04/39] Quick follow up Prevent from picking up the temp journal file Kodi creates. --- resources/lib/Utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/lib/Utils.py b/resources/lib/Utils.py index 8f81f5e2..5722e6a8 100644 --- a/resources/lib/Utils.py +++ b/resources/lib/Utils.py @@ -66,7 +66,7 @@ def getKodiVideoDBPath(): dirs, files = xbmcvfs.listdir("special://database") dbVersion = "" - for database in files: + for database in files and "journal" not in database: if "MyVideos" in database: dbVersion = database @@ -80,7 +80,7 @@ def getKodiMusicDBPath(): dirs, files = xbmcvfs.listdir("special://database") dbVersion = "" - for database in files: + for database in files and "journal" not in database: if "MyMusic" in database: dbVersion = database From 0b0d1aaacc8d907d8802a91936e5a3fea0481c1c Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Tue, 16 Jun 2015 21:11:50 -0500 Subject: [PATCH 05/39] Revert "Quick follow up" This reverts commit 7f2610642b1dd26c849869deb410bada9523551f. --- resources/lib/Utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/lib/Utils.py b/resources/lib/Utils.py index 5722e6a8..8f81f5e2 100644 --- a/resources/lib/Utils.py +++ b/resources/lib/Utils.py @@ -66,7 +66,7 @@ def getKodiVideoDBPath(): dirs, files = xbmcvfs.listdir("special://database") dbVersion = "" - for database in files and "journal" not in database: + for database in files: if "MyVideos" in database: dbVersion = database @@ -80,7 +80,7 @@ def getKodiMusicDBPath(): dirs, files = xbmcvfs.listdir("special://database") dbVersion = "" - for database in files and "journal" not in database: + for database in files: if "MyMusic" in database: dbVersion = database From ce312bd2c832d35bb4e9c55ca98e0c01bc67b3d1 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Tue, 16 Jun 2015 21:27:50 -0500 Subject: [PATCH 06/39] Quick follow To make sure it doesn't pick up the temp file Kodi creates which is the same name as the database. --- resources/lib/Utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/lib/Utils.py b/resources/lib/Utils.py index 8f81f5e2..8920fb78 100644 --- a/resources/lib/Utils.py +++ b/resources/lib/Utils.py @@ -67,7 +67,7 @@ def getKodiVideoDBPath(): dbVersion = "" for database in files: - if "MyVideos" in database: + if "MyVideos" in database and database.endswith("db"): dbVersion = database dbPath = xbmc.translatePath("special://database/%s" % dbVersion) @@ -81,7 +81,7 @@ def getKodiMusicDBPath(): dbVersion = "" for database in files: - if "MyMusic" in database: + if "MyMusic" in database and database.endswith("db"): dbVersion = database dbPath = xbmc.translatePath("special://database/%s" % dbVersion) From ac95b1ce23676d677ed0400e038b64753ab80bd6 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Wed, 17 Jun 2015 00:26:12 -0500 Subject: [PATCH 07/39] Added support for youtube trailers --- resources/lib/WriteKodiVideoDB.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/resources/lib/WriteKodiVideoDB.py b/resources/lib/WriteKodiVideoDB.py index a980ce22..c61abc25 100644 --- a/resources/lib/WriteKodiVideoDB.py +++ b/resources/lib/WriteKodiVideoDB.py @@ -123,6 +123,11 @@ class WriteKodiVideoDB(): if(jsonData != ""): trailerItem = jsonData trailerUrl = "plugin://plugin.video.emby/trailer/?id=%s&mode=play" % trailerItem[0][u'Id'] + elif MBitem.get("RemoteTrailers") != None: + trailerUrl = MBitem.get("RemoteTrailers")[0].get("Url") + if trailerUrl.startswith("http"): + trailerId = trailerUrl.split('=')[1] + trailerUrl = "plugin://plugin.video.youtube/play/?video_id=%s" % trailerId if MBitem.get("DateCreated") != None: dateadded = MBitem["DateCreated"].split('.')[0].replace('T', " ") From 874aab05d557e3d092042caa91c7e66075025234 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Wed, 17 Jun 2015 00:32:10 -0500 Subject: [PATCH 08/39] Revert "Added support for youtube trailers" This reverts commit ac95b1ce23676d677ed0400e038b64753ab80bd6. --- resources/lib/WriteKodiVideoDB.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/resources/lib/WriteKodiVideoDB.py b/resources/lib/WriteKodiVideoDB.py index c61abc25..a980ce22 100644 --- a/resources/lib/WriteKodiVideoDB.py +++ b/resources/lib/WriteKodiVideoDB.py @@ -123,11 +123,6 @@ class WriteKodiVideoDB(): if(jsonData != ""): trailerItem = jsonData trailerUrl = "plugin://plugin.video.emby/trailer/?id=%s&mode=play" % trailerItem[0][u'Id'] - elif MBitem.get("RemoteTrailers") != None: - trailerUrl = MBitem.get("RemoteTrailers")[0].get("Url") - if trailerUrl.startswith("http"): - trailerId = trailerUrl.split('=')[1] - trailerUrl = "plugin://plugin.video.youtube/play/?video_id=%s" % trailerId if MBitem.get("DateCreated") != None: dateadded = MBitem["DateCreated"].split('.')[0].replace('T', " ") From 591214590e2f0bc8c2e48a4f8474477c3dff88ca Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Wed, 17 Jun 2015 00:35:07 -0500 Subject: [PATCH 09/39] Added support for youtube trailers --- resources/lib/WriteKodiVideoDB.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/resources/lib/WriteKodiVideoDB.py b/resources/lib/WriteKodiVideoDB.py index a980ce22..e135ec5f 100644 --- a/resources/lib/WriteKodiVideoDB.py +++ b/resources/lib/WriteKodiVideoDB.py @@ -123,6 +123,13 @@ class WriteKodiVideoDB(): if(jsonData != ""): trailerItem = jsonData trailerUrl = "plugin://plugin.video.emby/trailer/?id=%s&mode=play" % trailerItem[0][u'Id'] + elif MBitem.get("RemoteTrailers") != None: + try: + trailerUrl = MBitem.get("RemoteTrailers")[0].get("Url") + trailerId = trailerUrl.split('=')[1] + trailerUrl = "plugin://plugin.video.youtube/play/?video_id=%s" % trailerId + except: + trailerUrl = MBitem.get("RemoteTrailers")[0].get("Url") if MBitem.get("DateCreated") != None: dateadded = MBitem["DateCreated"].split('.')[0].replace('T', " ") From 079adfb6194bc2a5a7f21e9c36e70237a40c7199 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Wed, 17 Jun 2015 01:13:21 -0500 Subject: [PATCH 10/39] Revert "Fix ratio poster" This reverts commit 0dc19eb87f7cb20f4d9bfe3e41aafc6a2beeb794. --- resources/lib/API.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/resources/lib/API.py b/resources/lib/API.py index 459b5bb4..03e3b0f1 100644 --- a/resources/lib/API.py +++ b/resources/lib/API.py @@ -373,14 +373,9 @@ class API(): query = "" height = "10000" width = "10000" - dimensions = "" played = "0" totalbackdrops = 0 - # Force ratio - if type == "Primary": - dimensions = "&Width=1000&Height=1500" - if originalType =="BackdropNoIndicators" and index == "0" and data.get("BackdropImageTags") != None: totalbackdrops = len(data.get("BackdropImageTags")) if totalbackdrops != 0: @@ -396,8 +391,9 @@ class API(): if imageTag == None: imageTag = "e3ab56fe27d389446754d0fb04910a34" - - artwork = "%s/mediabrowser/Items/%s/Images/%s/%s?MaxWidth=%s&MaxHeight=%s%s&Format=original&Tag=%s%s" % (server, id, type, index, width, height, dimensions, imageTag, query) + + artwork = "%s/mediabrowser/Items/%s/Images/%s/%s?MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s" % (server, id, type, index, width, height, imageTag, query) + #artwork = "%s/mediabrowser/Items/%s/Images/%s/%s/%s/original/%s/%s/%s?%s" % (server, id, type, index, imageTag, width, height, played, query) <- broken if addonSettings.getSetting('disableCoverArt')=='true': artwork = artwork + "&EnableImageEnhancers=false" From 7b041d879536723322cd22db18a8f52084089bfe Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Wed, 17 Jun 2015 01:32:59 -0500 Subject: [PATCH 11/39] Fix for filename using utils cleanname and encoding for special characters --- resources/lib/Entrypoint.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/lib/Entrypoint.py b/resources/lib/Entrypoint.py index d64bd28d..f04cae12 100644 --- a/resources/lib/Entrypoint.py +++ b/resources/lib/Entrypoint.py @@ -166,6 +166,7 @@ def getThemeMedia(): for item in result[u'Items']: itemId = item[u'Id'] folderName = item[u'Name'] + folderName = utils.CleanName(folderName) itemIds[itemId] = folderName # Get paths @@ -189,7 +190,7 @@ def getThemeMedia(): playurl = playUtils.directPlay(theme) else: playurl = playUtils.directStream(result, server, theme[u'Id'], "Audio") - pathstowrite += ('%s' % playurl) + pathstowrite += ('%s' % playurl.encode('utf-8')) nfo_file.write( '%s' % pathstowrite From 56c2c9aef2e235be98c4b04e8804f0cf0e194b2e Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Wed, 17 Jun 2015 01:57:09 -0500 Subject: [PATCH 12/39] Added tv tunes compatibility Automatically set the proper path for tv tunes --- resources/lib/Entrypoint.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/resources/lib/Entrypoint.py b/resources/lib/Entrypoint.py index f04cae12..b18fe2c7 100644 --- a/resources/lib/Entrypoint.py +++ b/resources/lib/Entrypoint.py @@ -144,6 +144,14 @@ def getThemeMedia(): playback = "DirectStream" else:return + # Set custom path for user + tvtunes_path = xbmc.translatePath("special://profile/addon_data/script.tvtunes/") + if xbmcvfs.exists(tvtunes_path): + tvtunes = xbmcaddon.Addon(id="script.tvtunes") + tvtunes.setSetting('custom_path_enable', "true") + tvtunes.setSetting('custom_path', library) + xbmc.log("TV Tunes custom path is enabled and set.") + # Create library directory if not xbmcvfs.exists(library): xbmcvfs.mkdir(library) From fc7916c69b4d7304e6f7144b8b5a5ec94ccbe710 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Wed, 17 Jun 2015 03:19:08 -0500 Subject: [PATCH 13/39] Quick correction for youtube trailer --- resources/lib/WriteKodiVideoDB.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/WriteKodiVideoDB.py b/resources/lib/WriteKodiVideoDB.py index e135ec5f..b9816812 100644 --- a/resources/lib/WriteKodiVideoDB.py +++ b/resources/lib/WriteKodiVideoDB.py @@ -123,7 +123,7 @@ class WriteKodiVideoDB(): if(jsonData != ""): trailerItem = jsonData trailerUrl = "plugin://plugin.video.emby/trailer/?id=%s&mode=play" % trailerItem[0][u'Id'] - elif MBitem.get("RemoteTrailers") != None: + elif MBitem.get("RemoteTrailers"): try: trailerUrl = MBitem.get("RemoteTrailers")[0].get("Url") trailerId = trailerUrl.split('=')[1] From 9c1f8476aaad31f4683224e3bc4d1d797caf8deb Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Wed, 17 Jun 2015 21:34:45 -0500 Subject: [PATCH 14/39] Database follow up When upgrading Kodi, it will leave the old database in the folder. As to not conflict, use the higher database version number. --- resources/lib/Utils.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/resources/lib/Utils.py b/resources/lib/Utils.py index 8920fb78..4ed7b2c9 100644 --- a/resources/lib/Utils.py +++ b/resources/lib/Utils.py @@ -64,13 +64,16 @@ def KodiSQL(type="video"): def getKodiVideoDBPath(): dirs, files = xbmcvfs.listdir("special://database") - dbVersion = "" - + dbVersions = {} + for database in files: if "MyVideos" in database and database.endswith("db"): - dbVersion = database + version = database[len("MyVideos"):-len(".db")] + dbVersions[int(version)] = database + # Sort by highest version number + versions = sorted(dbVersions.keys(), reverse=True) - dbPath = xbmc.translatePath("special://database/%s" % dbVersion) + dbPath = xbmc.translatePath("special://database/%s" % dbVersions[versions[0]]) logMsg("Utils", "Path to Video database: %s" % dbPath, 0) return dbPath @@ -78,13 +81,16 @@ def getKodiVideoDBPath(): def getKodiMusicDBPath(): dirs, files = xbmcvfs.listdir("special://database") - dbVersion = "" + dbVersions = {} for database in files: if "MyMusic" in database and database.endswith("db"): - dbVersion = database + version = database[len("MyMusic"):-len(".db")] + dbVersions[int(version)] = database + # Sort by highest version number + versions = sorted(dbVersions.keys(), reverse=True) - dbPath = xbmc.translatePath("special://database/%s" % dbVersion) + dbPath = xbmc.translatePath("special://database/%s" % dbVersions[versions[0]]) logMsg("Utils", "Path to Music database: %s" % dbPath, 0) return dbPath From 7120c688a047a79e94a33f3ab2a78abc2edeffa4 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Wed, 17 Jun 2015 23:10:33 -0500 Subject: [PATCH 15/39] Version bump 1.0.09 --- addon.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon.xml b/addon.xml index a43e3393..e0384a79 100644 --- a/addon.xml +++ b/addon.xml @@ -1,7 +1,7 @@ From 494e326413d802ac38e91928589db92963108d14 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Thu, 18 Jun 2015 03:03:44 -0500 Subject: [PATCH 16/39] Season artwork update When changing artwork --- resources/lib/LibrarySync.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/resources/lib/LibrarySync.py b/resources/lib/LibrarySync.py index 5570cdf2..dd6c26c8 100644 --- a/resources/lib/LibrarySync.py +++ b/resources/lib/LibrarySync.py @@ -580,6 +580,17 @@ class LibrarySync(): #tv show doesn't exist #perform full tvshow sync instead so both the show and episodes get added self.TvShowsFullSync(connection,cursor,None) + + elif u"Season" in MBitem['Type']: + + #get the tv show + cursor.execute("SELECT kodi_id FROM emby WHERE media_type='tvshow' AND emby_id=?", (MBitem["SeriesId"],)) + result = cursor.fetchone() + if result: + kodi_show_id = result[0] + season = MBitem['IndexNumber'] + # update season + WriteKodiVideoDB().updateSeasons(MBitem["SeriesId"], kodi_show_id, connection, cursor) #### PROCESS BOXSETS ###### elif MBitem["Type"] == "BoxSet": From aa156a5a63d5ec28dbb26f394262ff7e16b12b97 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Thu, 18 Jun 2015 05:10:49 -0500 Subject: [PATCH 17/39] Add artwork to All-season Turns out All-season is -1. --- resources/lib/WriteKodiVideoDB.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/resources/lib/WriteKodiVideoDB.py b/resources/lib/WriteKodiVideoDB.py index b9816812..ce09d8c0 100644 --- a/resources/lib/WriteKodiVideoDB.py +++ b/resources/lib/WriteKodiVideoDB.py @@ -764,7 +764,22 @@ class WriteKodiVideoDB(): self.addOrUpdateArt(imageUrl, seasonid, "season", "poster", cursor) imageUrl = API().getArtwork(season, "Banner") - self.addOrUpdateArt(imageUrl, seasonid, "season", "banner", cursor) + self.addOrUpdateArt(imageUrl, seasonid, "season", "banner", cursor) + # Set All season poster + MBitem = ReadEmbyDB().getFullItem(embyTvShowId) + seasonNum = -1 + cursor.execute("SELECT idSeason as seasonid FROM seasons WHERE idShow = ? and season = ?", (kodiTvShowId, seasonNum)) + result = cursor.fetchone() + if result == None: + # Create the all-season + cursor.execute("select coalesce(max(idSeason),0) as seasonid from seasons") + seasonid = cursor.fetchone()[0] + seasonid = seasonid + 1 + cursor.execute("INSERT into seasons(idSeason, idShow, season) values(?, ?, ?)", (seasonid, kodiTvShowId, seasonNum)) + else: + seasonid = result[0] + imageUrl = API().getArtwork(MBitem, "Primary") + self.addOrUpdateArt(imageUrl, seasonid, "season", "poster", cursor) def addOrUpdateArt(self, imageUrl, kodiId, mediaType, imageType, cursor): updateDone = False From 83080815ba3aa6f704e36d3dd5ac79f5b05fc537 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Thu, 18 Jun 2015 05:42:57 -0500 Subject: [PATCH 18/39] Revert db change --- resources/lib/Utils.py | 54 ++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/resources/lib/Utils.py b/resources/lib/Utils.py index 4ed7b2c9..6ff4685b 100644 --- a/resources/lib/Utils.py +++ b/resources/lib/Utils.py @@ -63,37 +63,39 @@ def KodiSQL(type="video"): def getKodiVideoDBPath(): - dirs, files = xbmcvfs.listdir("special://database") - dbVersions = {} + kodibuild = xbmc.getInfoLabel("System.BuildVersion") - for database in files: - if "MyVideos" in database and database.endswith("db"): - version = database[len("MyVideos"):-len(".db")] - dbVersions[int(version)] = database - # Sort by highest version number - versions = sorted(dbVersions.keys(), reverse=True) + if kodibuild.startswith("13"): + # Gotham + dbVersion = "78" + elif kodibuild.startswith("14"): + # Helix + dbVersion = "90" + elif kodibuild.startswith("15"): + # Isengard + dbVersion = "93" + else: + # Not a compatible build + xbmc.log("This Kodi version is incompatible. Current version: %s" % kodibuild) - dbPath = xbmc.translatePath("special://database/%s" % dbVersions[versions[0]]) - logMsg("Utils", "Path to Video database: %s" % dbPath, 0) + dbPath = xbmc.translatePath("special://profile/Database/MyVideos" + dbVersion + ".db") - return dbPath + return dbPath def getKodiMusicDBPath(): - - dirs, files = xbmcvfs.listdir("special://database") - dbVersions = {} - - for database in files: - if "MyMusic" in database and database.endswith("db"): - version = database[len("MyMusic"):-len(".db")] - dbVersions[int(version)] = database - # Sort by highest version number - versions = sorted(dbVersions.keys(), reverse=True) - - dbPath = xbmc.translatePath("special://database/%s" % dbVersions[versions[0]]) - logMsg("Utils", "Path to Music database: %s" % dbPath, 0) - - return dbPath + if xbmc.getInfoLabel("System.BuildVersion").startswith("13"): + #gotham + dbVersion = "46" + elif xbmc.getInfoLabel("System.BuildVersion").startswith("15"): + #isengard + dbVersion = "52" + else: + #helix + dbVersion = "48" + + dbPath = xbmc.translatePath("special://profile/Database/MyMusic" + dbVersion + ".db") + + return dbPath def prettifyXml(elem): rough_string = etree.tostring(elem, "utf-8") From 678efedd30f874a39e0148a975bc85a277edaa94 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Thu, 18 Jun 2015 21:11:48 -0500 Subject: [PATCH 19/39] Change to theme music Apparently CleanName is not CleanFileName... Using Kodi's built in method instead. --- resources/lib/Entrypoint.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/lib/Entrypoint.py b/resources/lib/Entrypoint.py index b18fe2c7..9940d285 100644 --- a/resources/lib/Entrypoint.py +++ b/resources/lib/Entrypoint.py @@ -174,12 +174,12 @@ def getThemeMedia(): for item in result[u'Items']: itemId = item[u'Id'] folderName = item[u'Name'] - folderName = utils.CleanName(folderName) + folderName = xbmc.makeLegalFilename(folderName) itemIds[itemId] = folderName # Get paths for itemId in itemIds: - nfo_path = xbmc.translatePath("special://profile/addon_data/plugin.video.emby/library/%s/" % itemIds[itemId]) + nfo_path = xbmc.translatePath("special://profile/addon_data/plugin.video.emby/library/%s" % itemIds[itemId]) # Create folders for each content if not xbmcvfs.exists(nfo_path): xbmcvfs.mkdir(nfo_path) From ae07e1b4c67a32ad40a900475fbf151a6c7fd17f Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Fri, 19 Jun 2015 03:10:41 -0500 Subject: [PATCH 20/39] another attempt at Theme music For illegal characters - following the same pattern as TV Tunes to make sure we match 100% --- resources/lib/Entrypoint.py | 4 ++-- resources/lib/Utils.py | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/resources/lib/Entrypoint.py b/resources/lib/Entrypoint.py index 9940d285..1b9deec4 100644 --- a/resources/lib/Entrypoint.py +++ b/resources/lib/Entrypoint.py @@ -174,12 +174,12 @@ def getThemeMedia(): for item in result[u'Items']: itemId = item[u'Id'] folderName = item[u'Name'] - folderName = xbmc.makeLegalFilename(folderName) + folderName = utils.normalize_string(folderName) itemIds[itemId] = folderName # Get paths for itemId in itemIds: - nfo_path = xbmc.translatePath("special://profile/addon_data/plugin.video.emby/library/%s" % itemIds[itemId]) + nfo_path = xbmc.translatePath("special://profile/addon_data/plugin.video.emby/library/%s/" % itemIds[itemId]) # Create folders for each content if not xbmcvfs.exists(nfo_path): xbmcvfs.mkdir(nfo_path) diff --git a/resources/lib/Utils.py b/resources/lib/Utils.py index 6ff4685b..ff6b5506 100644 --- a/resources/lib/Utils.py +++ b/resources/lib/Utils.py @@ -159,6 +159,20 @@ def CleanName(filename): validFilenameChars = "-_.() %s%s" % (string.ascii_letters, string.digits) cleanedFilename = unicodedata.normalize('NFKD', filename).encode('ASCII', 'ignore') return ''.join(c for c in cleanedFilename if c in validFilenameChars) + +def normalize_string(text): + try: + text = text.replace(":", "") + text = text.replace("/", "-") + text = text.replace("\\", "-") + text = text.strip() + # Remove dots from the last character as windows can not have directories + # with dots at the end + text = text.rstrip('.') + text = unicodedata.normalize('NFKD', unicode(text, 'utf-8')).encode('ascii', 'ignore') + except: + pass + return text def reset(): From 142908d56d1250ab39a7af46452aba5a6046bc2e Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Fri, 19 Jun 2015 05:53:22 -0500 Subject: [PATCH 21/39] Force refresh fanart The only thing cached into texture13.db I believe fanart was the last thing that wasn't changing when modified in Emby. --- resources/lib/TextureCache.py | 12 ++++++++++++ resources/lib/Utils.py | 2 ++ resources/lib/WriteKodiVideoDB.py | 5 ++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/resources/lib/TextureCache.py b/resources/lib/TextureCache.py index e095cbec..df731dc5 100644 --- a/resources/lib/TextureCache.py +++ b/resources/lib/TextureCache.py @@ -73,6 +73,18 @@ class TextureCache(): except: #extreme short timeouts so we will have a exception, but we don't need the result so pass pass + + def refreshFanart(self,url): + connection = utils.KodiSQL("texture") + cursor = connection.cursor() + cursor.execute("SELECT cachedurl FROM texture WHERE url = ?", (url,)) + result = cursor.fetchone() + if result: + cursor.execute("DELETE FROM texture WHERE url = ?", (url,)) + connection.commit() + else: + self.CacheTexture(url) + cursor.close() def setKodiWebServerDetails(self): diff --git a/resources/lib/Utils.py b/resources/lib/Utils.py index ff6b5506..404109e7 100644 --- a/resources/lib/Utils.py +++ b/resources/lib/Utils.py @@ -54,6 +54,8 @@ def KodiSQL(type="video"): if type == "music": dbPath = getKodiMusicDBPath() + elif type == "texture": + dbPath = xbmc.translatePath("special://database/Textures13.db") else: dbPath = getKodiVideoDBPath() diff --git a/resources/lib/WriteKodiVideoDB.py b/resources/lib/WriteKodiVideoDB.py index ce09d8c0..a33ad204 100644 --- a/resources/lib/WriteKodiVideoDB.py +++ b/resources/lib/WriteKodiVideoDB.py @@ -796,7 +796,10 @@ class WriteKodiVideoDB(): cursor.execute("UPDATE art set url = ? WHERE media_id = ? AND media_type = ? AND type = ?", (imageUrl, kodiId, mediaType, imageType)) #cache fanart and poster in Kodi texture cache - if imageType == "fanart" or imageType == "poster": + if "fanart" in imageType: + utils.logMsg("ArtworkSync", "Adding or Updating Fanart: %s" % imageUrl) + self.textureCache.refreshFanart(imageUrl) + elif "poster" in imageType: self.textureCache.CacheTexture(imageUrl) def setKodiResumePoint(self, fileid, resume_seconds, total_seconds, cursor): From 3118434c4776224dd20fe6edd2f2c9d615bf9838 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Fri, 19 Jun 2015 07:20:31 -0500 Subject: [PATCH 22/39] Watched status Moved away from Json RPC for DB write instead. --- resources/lib/WriteKodiVideoDB.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/resources/lib/WriteKodiVideoDB.py b/resources/lib/WriteKodiVideoDB.py index a33ad204..68555491 100644 --- a/resources/lib/WriteKodiVideoDB.py +++ b/resources/lib/WriteKodiVideoDB.py @@ -39,18 +39,11 @@ class WriteKodiVideoDB(): cursor = connection.cursor() cursor.execute("SELECT emby_id FROM emby WHERE media_type=? AND kodi_id=?",(type,id)) - emby_id = cursor.fetchone()[0] - cursor.close + emby_id = cursor.fetchone() if(emby_id != None): + emby_id = emby_id[0] # Erase resume point when user marks watched/unwatched to follow Emby behavior - # Also force sets the playcount to instantly reflect the appropriate playstate. - if type == "episode": - resume = '{"jsonrpc": "2.0", "method": "VideoLibrary.SetEpisodeDetails", "params": {"episodeid": %d, "playcount": %d, "resume": {"position": 0}}, "id": "setResumePoint"}' % (id, playcount) - elif type == "movie": - resume = '{"jsonrpc": "2.0", "method": "VideoLibrary.SetMovieDetails", "params": {"movieid": %d, "playcount": %d, "resume": {"position": 0}}, "id": "setResumePoint"}' % (id, playcount) - xbmc.executeJSONRPC(resume) - addon = xbmcaddon.Addon(id='plugin.video.emby') downloadUtils = DownloadUtils() watchedurl = "{server}/mediabrowser/Users/{UserId}/PlayedItems/%s" % emby_id @@ -58,6 +51,9 @@ class WriteKodiVideoDB(): downloadUtils.downloadUrl(watchedurl, type="POST") else: downloadUtils.downloadUrl(watchedurl, type="DELETE") + + self.setKodiResumePoint(id, 0, 0, cursor) + cursor.close def addOrUpdateMovieToKodiLibrary( self, embyId ,connection, cursor, viewTag): From 2abee11c6bec17d238e6c22c368a072bba372e96 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Fri, 19 Jun 2015 09:02:29 -0500 Subject: [PATCH 23/39] Fix for unicode error The normalize_string method needs utf-8 encoding, not unicode. --- resources/lib/Entrypoint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lib/Entrypoint.py b/resources/lib/Entrypoint.py index 1b9deec4..d04405a0 100644 --- a/resources/lib/Entrypoint.py +++ b/resources/lib/Entrypoint.py @@ -174,7 +174,7 @@ def getThemeMedia(): for item in result[u'Items']: itemId = item[u'Id'] folderName = item[u'Name'] - folderName = utils.normalize_string(folderName) + folderName = utils.normalize_string(folderName.encode('utf-8')) itemIds[itemId] = folderName # Get paths From 3f1caa340c1767b53edf3da7b005d3f08dc99831 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Fri, 19 Jun 2015 09:11:01 -0500 Subject: [PATCH 24/39] Version bump 1.0.10 --- addon.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon.xml b/addon.xml index e0384a79..1931fe08 100644 --- a/addon.xml +++ b/addon.xml @@ -1,7 +1,7 @@ From 5e130bf6fddf50f8b870c2a53d4b4ced324e050e Mon Sep 17 00:00:00 2001 From: im85288 Date: Sat, 20 Jun 2015 15:59:00 +0100 Subject: [PATCH 25/39] added theme video support --- addon.xml | 2 +- resources/lib/Entrypoint.py | 48 ++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/addon.xml b/addon.xml index 1931fe08..9c123609 100644 --- a/addon.xml +++ b/addon.xml @@ -1,7 +1,7 @@ diff --git a/resources/lib/Entrypoint.py b/resources/lib/Entrypoint.py index d04405a0..4ef07560 100644 --- a/resources/lib/Entrypoint.py +++ b/resources/lib/Entrypoint.py @@ -165,6 +165,48 @@ def getThemeMedia(): userviewId = view[u'Id'] userViews.append(userviewId) + + # Get Ids with Theme Videos + itemIds = {} + for view in userViews: + url = "{server}/mediabrowser/Users/{UserId}/Items?HasThemeVideo=True&ParentId=%s&format=json" % view + result = doUtils.downloadUrl(url) + if result[u'TotalRecordCount'] != 0: + for item in result[u'Items']: + itemId = item[u'Id'] + folderName = item[u'Name'] + folderName = utils.normalize_string(folderName) + itemIds[itemId] = folderName + + # Get paths for theme videos + for itemId in itemIds: + nfo_path = xbmc.translatePath("special://profile/addon_data/plugin.video.emby/library/%s/" % itemIds[itemId]) + # Create folders for each content + if not xbmcvfs.exists(nfo_path): + xbmcvfs.mkdir(nfo_path) + # Where to put the nfos + nfo_path = "%s%s" % (nfo_path, "tvtunes.nfo") + + url = "{server}/mediabrowser/Items/%s/ThemeVideos?format=json" % itemId + result = doUtils.downloadUrl(url) + + # Create nfo and write themes to it + nfo_file = open(nfo_path, 'w') + pathstowrite = "" + # May be more than one theme + for theme in result[u'Items']: + if playback == "DirectPlay": + playurl = playUtils.directPlay(theme) + else: + playurl = playUtils.directStream(result, server, theme[u'Id']) + pathstowrite += ('%s' % playurl.encode('utf-8')) + + nfo_file.write( + '%s' % pathstowrite + ) + # Close nfo file + nfo_file.close() + # Get Ids with Theme songs itemIds = {} for view in userViews: @@ -174,7 +216,7 @@ def getThemeMedia(): for item in result[u'Items']: itemId = item[u'Id'] folderName = item[u'Name'] - folderName = utils.normalize_string(folderName.encode('utf-8')) + folderName = utils.normalize_string(folderName) itemIds[itemId] = folderName # Get paths @@ -185,6 +227,10 @@ def getThemeMedia(): xbmcvfs.mkdir(nfo_path) # Where to put the nfos nfo_path = "%s%s" % (nfo_path, "tvtunes.nfo") + + # if the nfo already exists assume a theme video was added so back out because if both are added it rotates between theme video and theme music + if xbmcvfs.exists(nfo_path): + continue url = "{server}/mediabrowser/Items/%s/ThemeSongs?format=json" % itemId result = doUtils.downloadUrl(url) From 5e53884030a6673ae058d11323b16e9ea0ebdb49 Mon Sep 17 00:00:00 2001 From: im85288 Date: Sat, 20 Jun 2015 16:28:52 +0100 Subject: [PATCH 26/39] re-added fix for unicodes --- addon.xml | 2 +- resources/lib/Entrypoint.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addon.xml b/addon.xml index 9c123609..7c9aeb6e 100644 --- a/addon.xml +++ b/addon.xml @@ -1,7 +1,7 @@ diff --git a/resources/lib/Entrypoint.py b/resources/lib/Entrypoint.py index 4ef07560..7f863fff 100644 --- a/resources/lib/Entrypoint.py +++ b/resources/lib/Entrypoint.py @@ -175,7 +175,7 @@ def getThemeMedia(): for item in result[u'Items']: itemId = item[u'Id'] folderName = item[u'Name'] - folderName = utils.normalize_string(folderName) + folderName = utils.normalize_string(folderName.encode('utf-8')) itemIds[itemId] = folderName # Get paths for theme videos @@ -216,7 +216,7 @@ def getThemeMedia(): for item in result[u'Items']: itemId = item[u'Id'] folderName = item[u'Name'] - folderName = utils.normalize_string(folderName) + folderName = utils.normalize_string(folderName.encode('utf-8')) itemIds[itemId] = folderName # Get paths From 6e56d259d430e80f80fd595ce27f16355eab7312 Mon Sep 17 00:00:00 2001 From: im85288 Date: Sat, 20 Jun 2015 18:05:54 +0100 Subject: [PATCH 27/39] merged normalize string changes from tvtunes addon --- addon.xml | 2 +- resources/lib/Utils.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/addon.xml b/addon.xml index 7c9aeb6e..c2153b58 100644 --- a/addon.xml +++ b/addon.xml @@ -1,7 +1,7 @@ diff --git a/resources/lib/Utils.py b/resources/lib/Utils.py index 404109e7..5ea5bcfa 100644 --- a/resources/lib/Utils.py +++ b/resources/lib/Utils.py @@ -167,6 +167,11 @@ def normalize_string(text): text = text.replace(":", "") text = text.replace("/", "-") text = text.replace("\\", "-") + text = text.replace("<", "") + text = text.replace(">", "") + text = text.replace("*", "") + text = text.replace("?", "") + text = text.replace('|', "") text = text.strip() # Remove dots from the last character as windows can not have directories # with dots at the end From f946f7ba6981a5a328d52c8dc1e12d1fdf971264 Mon Sep 17 00:00:00 2001 From: im85288 Date: Mon, 22 Jun 2015 20:18:00 +0100 Subject: [PATCH 28/39] tv tunes now accepts both music/video themes in the same nfo --- addon.xml | 2 +- resources/lib/Entrypoint.py | 29 +++++++++++++++++++++-------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/addon.xml b/addon.xml index c2153b58..fad2337b 100644 --- a/addon.xml +++ b/addon.xml @@ -1,7 +1,7 @@ diff --git a/resources/lib/Entrypoint.py b/resources/lib/Entrypoint.py index 7f863fff..75ef56ae 100644 --- a/resources/lib/Entrypoint.py +++ b/resources/lib/Entrypoint.py @@ -200,6 +200,18 @@ def getThemeMedia(): else: playurl = playUtils.directStream(result, server, theme[u'Id']) pathstowrite += ('%s' % playurl.encode('utf-8')) + + # Check if the item has theme songs and add them + url = "{server}/mediabrowser/Items/%s/ThemeSongs?format=json" % itemId + result = doUtils.downloadUrl(url) + + # May be more than one theme + for theme in result[u'Items']: + if playback == "DirectPlay": + playurl = playUtils.directPlay(theme) + else: + playurl = playUtils.directStream(result, server, theme[u'Id'], "Audio") + pathstowrite += ('%s' % playurl.encode('utf-8')) nfo_file.write( '%s' % pathstowrite @@ -208,7 +220,7 @@ def getThemeMedia(): nfo_file.close() # Get Ids with Theme songs - itemIds = {} + musicitemIds = {} for view in userViews: url = "{server}/mediabrowser/Users/{UserId}/Items?HasThemeSong=True&ParentId=%s&format=json" % view result = doUtils.downloadUrl(url) @@ -217,21 +229,22 @@ def getThemeMedia(): itemId = item[u'Id'] folderName = item[u'Name'] folderName = utils.normalize_string(folderName.encode('utf-8')) - itemIds[itemId] = folderName + musicitemIds[itemId] = folderName # Get paths - for itemId in itemIds: - nfo_path = xbmc.translatePath("special://profile/addon_data/plugin.video.emby/library/%s/" % itemIds[itemId]) + for itemId in musicitemIds: + + # if the item was already processed with video themes back out + if itemId in itemIds: + continue + + nfo_path = xbmc.translatePath("special://profile/addon_data/plugin.video.emby/library/%s/" % musicitemIds[itemId]) # Create folders for each content if not xbmcvfs.exists(nfo_path): xbmcvfs.mkdir(nfo_path) # Where to put the nfos nfo_path = "%s%s" % (nfo_path, "tvtunes.nfo") - # if the nfo already exists assume a theme video was added so back out because if both are added it rotates between theme video and theme music - if xbmcvfs.exists(nfo_path): - continue - url = "{server}/mediabrowser/Items/%s/ThemeSongs?format=json" % itemId result = doUtils.downloadUrl(url) From 0e7c8b5959ab78cde63c59894ff078f45dbff010 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Tue, 23 Jun 2015 19:43:51 -0500 Subject: [PATCH 29/39] Attempt at fixing database locked Hopefully, the close before cachetexture will fix the issue. --- resources/lib/TextureCache.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/lib/TextureCache.py b/resources/lib/TextureCache.py index df731dc5..9fa3868d 100644 --- a/resources/lib/TextureCache.py +++ b/resources/lib/TextureCache.py @@ -82,9 +82,10 @@ class TextureCache(): if result: cursor.execute("DELETE FROM texture WHERE url = ?", (url,)) connection.commit() + cursor.close() else: + cursor.close() self.CacheTexture(url) - cursor.close() def setKodiWebServerDetails(self): From 5f356b91479323dd918a2d21b68f9cd723ce40d3 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Tue, 23 Jun 2015 20:12:39 -0500 Subject: [PATCH 30/39] Revert "Attempt at fixing database locked" This reverts commit 0e7c8b5959ab78cde63c59894ff078f45dbff010. --- resources/lib/TextureCache.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/lib/TextureCache.py b/resources/lib/TextureCache.py index 9fa3868d..df731dc5 100644 --- a/resources/lib/TextureCache.py +++ b/resources/lib/TextureCache.py @@ -82,10 +82,9 @@ class TextureCache(): if result: cursor.execute("DELETE FROM texture WHERE url = ?", (url,)) connection.commit() - cursor.close() else: - cursor.close() self.CacheTexture(url) + cursor.close() def setKodiWebServerDetails(self): From b6f70fc5bf660c0ce758bf87665dde2ce9a4b51e Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Tue, 23 Jun 2015 20:14:38 -0500 Subject: [PATCH 31/39] Attempt at fixing database locked Hopefully close before cachetexture will fix the issue. --- resources/lib/TextureCache.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/lib/TextureCache.py b/resources/lib/TextureCache.py index df731dc5..09d0e9a4 100644 --- a/resources/lib/TextureCache.py +++ b/resources/lib/TextureCache.py @@ -80,11 +80,13 @@ class TextureCache(): cursor.execute("SELECT cachedurl FROM texture WHERE url = ?", (url,)) result = cursor.fetchone() if result: - cursor.execute("DELETE FROM texture WHERE url = ?", (url,)) + result = result[0] + cursor.execute("DELETE FROM texture WHERE cachedurl = ?", (result,)) connection.commit() + cursor.close() else: + cursor.close() self.CacheTexture(url) - cursor.close() def setKodiWebServerDetails(self): From d617aa13ac9a682d568d47b698acf71eb31745cb Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Wed, 24 Jun 2015 09:03:49 +0200 Subject: [PATCH 32/39] added window prop to force refresh widgets if content has changed --- resources/lib/LibrarySync.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/resources/lib/LibrarySync.py b/resources/lib/LibrarySync.py index dd6c26c8..df614161 100644 --- a/resources/lib/LibrarySync.py +++ b/resources/lib/LibrarySync.py @@ -115,6 +115,9 @@ class LibrarySync(): # set prop to show we have run for the first time WINDOW.setProperty("startup", "done") + # tell any widgets to refresh because the content has changed + WINDOW.setProperty("widgetreload", datetime.now().strftime('%Y-%m-%d %H:%M:%S')) + finally: WINDOW.setProperty("SyncDatabaseRunning", "false") utils.logMsg("Sync DB", "syncDatabase Exiting", 0) @@ -625,9 +628,10 @@ class LibrarySync(): cursor.close() finally: - xbmc.executebuiltin("UpdateLibrary(video)") WINDOW.setProperty("SyncDatabaseRunning", "false") + # tell any widgets to refresh because the content has changed + WINDOW.setProperty("widgetreload", datetime.now().strftime('%Y-%m-%d %H:%M:%S')) def ShouldStop(self): From feb6c73fc33e71c177324fa8e935ade4dc393efa Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Wed, 24 Jun 2015 10:02:34 +0200 Subject: [PATCH 33/39] fix texture cache stuff --- resources/lib/TextureCache.py | 45 ++++++++++++++++++------------- resources/lib/WriteKodiVideoDB.py | 4 +-- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/resources/lib/TextureCache.py b/resources/lib/TextureCache.py index 09d0e9a4..81762afb 100644 --- a/resources/lib/TextureCache.py +++ b/resources/lib/TextureCache.py @@ -3,11 +3,11 @@ ################################################################################################# -import xbmc -import xbmcaddon +import xbmc, xbmcaddon, xbmcvfs import json import requests import urllib +import os import Utils as utils @@ -42,15 +42,38 @@ class TextureCache(): def FullTextureCacheSync(self): #this method can be called from the plugin to sync all Kodi textures to the texture cache. #Warning: this means that every image will be cached locally, this takes diskspace! + + #remove all existing textures first + path = "special://thumbnails/" + if xbmcvfs.exists(path): + allDirs, allFiles = xbmcvfs.listdir(path) + for dir in allDirs: + allDirs, allFiles = xbmcvfs.listdir(path+dir) + for file in allFiles: + xbmcvfs.delete(os.path.join(path+dir,file)) + + textureconnection = utils.KodiSQL("texture") + texturecursor = textureconnection.cursor() + texturecursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"') + rows = texturecursor.fetchall() + for row in rows: + tableName = row[0] + if(tableName != "version"): + texturecursor.execute("DELETE FROM " + tableName) + textureconnection.commit() + texturecursor.close() + + + #cache all entries in video DB connection = utils.KodiSQL("video") cursor = connection.cursor() cursor.execute("SELECT url FROM art") result = cursor.fetchall() for url in result: self.CacheTexture(url[0]) - cursor.close() + #cache all entries in music DB connection = utils.KodiSQL("music") cursor = connection.cursor() cursor.execute("SELECT url FROM art") @@ -73,21 +96,7 @@ class TextureCache(): except: #extreme short timeouts so we will have a exception, but we don't need the result so pass pass - - def refreshFanart(self,url): - connection = utils.KodiSQL("texture") - cursor = connection.cursor() - cursor.execute("SELECT cachedurl FROM texture WHERE url = ?", (url,)) - result = cursor.fetchone() - if result: - result = result[0] - cursor.execute("DELETE FROM texture WHERE cachedurl = ?", (result,)) - connection.commit() - cursor.close() - else: - cursor.close() - self.CacheTexture(url) - + def setKodiWebServerDetails(self): # Get the Kodi webserver details - used to set the texture cache diff --git a/resources/lib/WriteKodiVideoDB.py b/resources/lib/WriteKodiVideoDB.py index 68555491..e6a9ef7e 100644 --- a/resources/lib/WriteKodiVideoDB.py +++ b/resources/lib/WriteKodiVideoDB.py @@ -792,10 +792,8 @@ class WriteKodiVideoDB(): cursor.execute("UPDATE art set url = ? WHERE media_id = ? AND media_type = ? AND type = ?", (imageUrl, kodiId, mediaType, imageType)) #cache fanart and poster in Kodi texture cache - if "fanart" in imageType: + if "fanart" in imageType or "poster" in imageType: utils.logMsg("ArtworkSync", "Adding or Updating Fanart: %s" % imageUrl) - self.textureCache.refreshFanart(imageUrl) - elif "poster" in imageType: self.textureCache.CacheTexture(imageUrl) def setKodiResumePoint(self, fileid, resume_seconds, total_seconds, cursor): From 42f8d91ace07b845cd102e495186c7e0837f4023 Mon Sep 17 00:00:00 2001 From: im85288 Date: Wed, 24 Jun 2015 18:05:52 +0100 Subject: [PATCH 34/39] added a warn on sync where tvtunes cannot set the settings file. --- resources/lib/Entrypoint.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/resources/lib/Entrypoint.py b/resources/lib/Entrypoint.py index 75ef56ae..8500748e 100644 --- a/resources/lib/Entrypoint.py +++ b/resources/lib/Entrypoint.py @@ -151,6 +151,12 @@ def getThemeMedia(): tvtunes.setSetting('custom_path_enable', "true") tvtunes.setSetting('custom_path', library) xbmc.log("TV Tunes custom path is enabled and set.") + else: + # if it does not exist this will not work so warn user, often they need to edit the settings first for it to be created. + dialog = xbmcgui.Dialog() + dialog.ok('Warning', 'The settings file does not exist in tvtunes. Go to the tvtunes addon and change a setting, then come back and re-run') + return + # Create library directory if not xbmcvfs.exists(library): From ff3041d1045adcdea8632805b9d7e7864d05bc88 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Wed, 24 Jun 2015 22:24:02 -0500 Subject: [PATCH 35/39] getdirectory error modified script listing by setting folder=false (do not resolve with listing). --- resources/lib/Entrypoint.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/resources/lib/Entrypoint.py b/resources/lib/Entrypoint.py index 8500748e..02556930 100644 --- a/resources/lib/Entrypoint.py +++ b/resources/lib/Entrypoint.py @@ -650,12 +650,12 @@ def doMainListing(): addDirectoryItem(label, path) # some extra entries for settings and stuff. TODO --> localize the labels - addDirectoryItem("Settings", "plugin://plugin.video.emby/?mode=settings") - addDirectoryItem("Perform manual sync", "plugin://plugin.video.emby/?mode=manualsync") - addDirectoryItem("Add user to session", "plugin://plugin.video.emby/?mode=adduser") - addDirectoryItem("Configure user preferences", "plugin://plugin.video.emby/?mode=userprefs") - addDirectoryItem("Perform local database reset (full resync)", "plugin://plugin.video.emby/?mode=reset") - addDirectoryItem("Cache all images to Kodi texture cache (advanced)", "plugin://plugin.video.emby/?mode=texturecache") - addDirectoryItem("Sync Emby Theme Media to Kodi", "plugin://plugin.video.emby/?mode=thememedia") + addDirectoryItem("Settings", "plugin://plugin.video.emby/?mode=settings", False) + addDirectoryItem("Perform manual sync", "plugin://plugin.video.emby/?mode=manualsync", False) + addDirectoryItem("Add user to session", "plugin://plugin.video.emby/?mode=adduser", False) + addDirectoryItem("Configure user preferences", "plugin://plugin.video.emby/?mode=userprefs", False) + addDirectoryItem("Perform local database reset (full resync)", "plugin://plugin.video.emby/?mode=reset", False) + addDirectoryItem("Cache all images to Kodi texture cache (advanced)", "plugin://plugin.video.emby/?mode=texturecache", False) + addDirectoryItem("Sync Emby Theme Media to Kodi", "plugin://plugin.video.emby/?mode=thememedia", False) xbmcplugin.endOfDirectory(int(sys.argv[1])) From 5717aa805392449e5ed23054cc79153131f3fc1d Mon Sep 17 00:00:00 2001 From: shaun Date: Sat, 27 Jun 2015 09:48:18 +1000 Subject: [PATCH 36/39] Fix the direct path handeling, if path has an issue dont add the item --- resources/lib/WriteKodiVideoDB.py | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/resources/lib/WriteKodiVideoDB.py b/resources/lib/WriteKodiVideoDB.py index e6a9ef7e..f14ff6d0 100644 --- a/resources/lib/WriteKodiVideoDB.py +++ b/resources/lib/WriteKodiVideoDB.py @@ -145,23 +145,19 @@ class WriteKodiVideoDB(): #### ADD OR UPDATE THE FILE AND PATH ########### #### NOTE THAT LASTPLAYED AND PLAYCOUNT ARE STORED AT THE FILE ENTRY - if addon.getSetting('useDirectPaths')=='true': - if PlayUtils().isDirectPlay(MBitem): - playurl = PlayUtils().directPlay(MBitem) - #use the direct file path - if "\\" in playurl: - filename = playurl.rsplit("\\",1)[-1] - path = playurl.replace(filename,"") - elif "/" in playurl: - filename = playurl.rsplit("/",1)[-1] - path = playurl.replace(filename,"") - else: - #for transcoding we just use the server's streaming path because I couldn't figure out how to set the plugin path in the music DB - path = server + "/Video/%s/" %MBitem["Id"] - filename = "stream.mp4" + if addon.getSetting('useDirectPaths') == 'true': + playurl = PlayUtils().directPlay(MBitem) + if playurl == False: + return + elif "\\" in playurl: + filename = playurl.rsplit("\\",1)[-1] + path = playurl.replace(filename, "") + elif "/" in playurl: + filename = playurl.rsplit("/",1)[-1] + path = playurl.replace(filename, "") else: - path = "plugin://plugin.video.emby/movies/%s/" % MBitem["Id"] - filename = "plugin://plugin.video.emby/movies/%s/?id=%s&mode=play" % (MBitem["Id"],MBitem["Id"]) + path = "plugin://plugin.video.emby/tvshows/" + MBitem["SeriesId"] + "/" + filename = "plugin://plugin.video.emby/tvshows/" + MBitem["SeriesId"] + "/?id=" + MBitem["Id"] + "&mode=play" #create the path cursor.execute("SELECT idPath as pathid FROM path WHERE strPath = ?",(path,)) From 44dc9c2ddaa3a58c02ac68418d76d4a1ad54fad3 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Fri, 26 Jun 2015 22:49:51 -0500 Subject: [PATCH 37/39] Version bump 1.0.15 --- addon.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon.xml b/addon.xml index fad2337b..ffe99310 100644 --- a/addon.xml +++ b/addon.xml @@ -1,7 +1,7 @@ From a1a2901e9313cb68d8eb8c10798548eb58a9a92c Mon Sep 17 00:00:00 2001 From: Shaun Date: Sat, 27 Jun 2015 14:23:27 +1000 Subject: [PATCH 38/39] fix the movie addon path --- resources/lib/WriteKodiVideoDB.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/lib/WriteKodiVideoDB.py b/resources/lib/WriteKodiVideoDB.py index f14ff6d0..5de8f6b6 100644 --- a/resources/lib/WriteKodiVideoDB.py +++ b/resources/lib/WriteKodiVideoDB.py @@ -156,9 +156,9 @@ class WriteKodiVideoDB(): filename = playurl.rsplit("/",1)[-1] path = playurl.replace(filename, "") else: - path = "plugin://plugin.video.emby/tvshows/" + MBitem["SeriesId"] + "/" - filename = "plugin://plugin.video.emby/tvshows/" + MBitem["SeriesId"] + "/?id=" + MBitem["Id"] + "&mode=play" - + path = "plugin://plugin.video.emby/movies/%s/" % MBitem["Id"] + filename = "plugin://plugin.video.emby/movies/%s/?id=%s&mode=play" % (MBitem["Id"],MBitem["Id"]) + #create the path cursor.execute("SELECT idPath as pathid FROM path WHERE strPath = ?",(path,)) result = cursor.fetchone() From 00bf5434dc5eb861f3d64875b0b20dc4aeb5b638 Mon Sep 17 00:00:00 2001 From: angelblue05 Date: Sat, 27 Jun 2015 01:07:49 -0500 Subject: [PATCH 39/39] Fix season poster update Caused incremental to freeze --- resources/lib/LibrarySync.py | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/lib/LibrarySync.py b/resources/lib/LibrarySync.py index df614161..b1612ee7 100644 --- a/resources/lib/LibrarySync.py +++ b/resources/lib/LibrarySync.py @@ -591,7 +591,6 @@ class LibrarySync(): result = cursor.fetchone() if result: kodi_show_id = result[0] - season = MBitem['IndexNumber'] # update season WriteKodiVideoDB().updateSeasons(MBitem["SeriesId"], kodi_show_id, connection, cursor)