From 58ab6432f6ae126d3d89002371a70daf353fd12c Mon Sep 17 00:00:00 2001
From: im85288 <ianmalcolmmclaughlin@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 += ('<file>%s</file>' % playurl)
+            pathstowrite += ('<file>%s</file>' % playurl.encode('utf-8'))
 
         nfo_file.write(
             '<tvtunes>%s</tvtunes>' % pathstowrite

From 56c2c9aef2e235be98c4b04e8804f0cf0e194b2e Mon Sep 17 00:00:00 2001
From: angelblue05 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon  id="plugin.video.emby" 
         name="Emby" 
-        version="1.0.08"
+        version="1.0.09"
         provider-name="Emby.media">
   <requires>
     <import addon="xbmc.python" version="2.1.0"/>

From 494e326413d802ac38e91928589db92963108d14 Mon Sep 17 00:00:00 2001
From: angelblue05 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon  id="plugin.video.emby" 
         name="Emby" 
-        version="1.0.09"
+        version="1.0.10"
         provider-name="Emby.media">
   <requires>
     <import addon="xbmc.python" version="2.1.0"/>

From 5e130bf6fddf50f8b870c2a53d4b4ced324e050e Mon Sep 17 00:00:00 2001
From: im85288 <ianmalcolmmclaughlin@gmail.com>
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 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon  id="plugin.video.emby" 
         name="Emby" 
-        version="1.0.10"
+        version="1.0.11"
         provider-name="Emby.media">
   <requires>
     <import addon="xbmc.python" version="2.1.0"/>
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 += ('<file>%s</file>' % playurl.encode('utf-8'))
+
+        nfo_file.write(
+            '<tvtunes>%s</tvtunes>' % 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 <ianmalcolmmclaughlin@gmail.com>
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 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon  id="plugin.video.emby" 
         name="Emby" 
-        version="1.0.11"
+        version="1.0.12"
         provider-name="Emby.media">
   <requires>
     <import addon="xbmc.python" version="2.1.0"/>
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 <ianmalcolmmclaughlin@gmail.com>
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 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon  id="plugin.video.emby" 
         name="Emby" 
-        version="1.0.12"
+        version="1.0.13"
         provider-name="Emby.media">
   <requires>
     <import addon="xbmc.python" version="2.1.0"/>
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 <ianmalcolmmclaughlin@gmail.com>
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 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon  id="plugin.video.emby" 
         name="Emby" 
-        version="1.0.13"
+        version="1.0.14"
         provider-name="Emby.media">
   <requires>
     <import addon="xbmc.python" version="2.1.0"/>
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 += ('<file>%s</file>' % 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 += ('<file>%s</file>' % playurl.encode('utf-8'))
 
         nfo_file.write(
             '<tvtunes>%s</tvtunes>' % 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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <tamara.angel05@gmail.com>
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 <m.vanderveldt@outlook.com>
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 <m.vanderveldt@outlook.com>
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 <ianmalcolmmclaughlin@gmail.com>
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 <tamara.angel05@gmail.com>
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 <shaun@bluebit.com.au>
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 <tamara.angel05@gmail.com>
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 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon  id="plugin.video.emby" 
         name="Emby" 
-        version="1.0.14"
+        version="1.0.15"
         provider-name="Emby.media">
   <requires>
     <import addon="xbmc.python" version="2.1.0"/>

From a1a2901e9313cb68d8eb8c10798548eb58a9a92c Mon Sep 17 00:00:00 2001
From: Shaun <shaun@bluebit.com.au>
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 <tamara.angel05@gmail.com>
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)