From 944b04b89a82afffe282ceb20f16fd1ea8d008d5 Mon Sep 17 00:00:00 2001 From: shaun Date: Mon, 23 Mar 2015 19:44:16 +1100 Subject: [PATCH 1/6] we dont support DisplayContent in this addon --- resources/lib/DownloadUtils.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/lib/DownloadUtils.py b/resources/lib/DownloadUtils.py index 1a0ad5d0..fcddcda3 100644 --- a/resources/lib/DownloadUtils.py +++ b/resources/lib/DownloadUtils.py @@ -130,8 +130,10 @@ class DownloadUtils(): self.logMsg("Session Id : " + str(sessionId)) # post capability data - playableMediaTypes = "Audio,Video,Photo" - supportedCommands = "Play,Playstate,DisplayContent,GoHome,SendString,GoToSettings,DisplayMessage,PlayNext" + #playableMediaTypes = "Audio,Video,Photo" + playableMediaTypes = "Audio,Video" + #supportedCommands = "Play,Playstate,DisplayContent,GoHome,SendString,GoToSettings,DisplayMessage,PlayNext" + supportedCommands = "Play,Playstate,SendString,DisplayMessage,PlayNext" url = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Sessions/Capabilities?Id=" + sessionId + "&PlayableMediaTypes=" + playableMediaTypes + "&SupportedCommands=" + supportedCommands + "&SupportsMediaControl=True" postData = {} From cf03ca9f4f4cfd7d7f4cb541d8afc41775dc297c Mon Sep 17 00:00:00 2001 From: im85288 Date: Mon, 23 Mar 2015 11:30:03 +0000 Subject: [PATCH 2/6] Don't use hardcoded database version number --- resources/lib/Utils.py | 5 +++-- resources/lib/WriteKodiDB.py | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/resources/lib/Utils.py b/resources/lib/Utils.py index 5f92f3e4..fc2a9964 100644 --- a/resources/lib/Utils.py +++ b/resources/lib/Utils.py @@ -23,7 +23,8 @@ from PlayUtils import PlayUtils from DownloadUtils import DownloadUtils downloadUtils = DownloadUtils() addonSettings = xbmcaddon.Addon(id='plugin.video.mb3sync') -language = addonSettings.getLocalizedString +language = addonSettings.getLocalizedString +DATABASE_VERSION_HELIX = "90" def logMsg(title, msg, level = 1): logLevel = int(addonSettings.getSetting("logLevel")) @@ -88,7 +89,7 @@ def addKodiSource(name, path, type): #add new source to database, common way is to add it directly to the Kodi DB. Fallback to adding it to the sources.xml #return boolean wether a manual reboot is required. #todo: Do feature request with Kodi team to get support for adding a source by the json API - dbPath = xbmc.translatePath("special://userdata/Database/MyVideos90.db") + dbPath = xbmc.translatePath("special://userdata/Database/MyVideos%s.db" % DATABASE_VERSION_HELIX) error = False if xbmcvfs.exists(dbPath): diff --git a/resources/lib/WriteKodiDB.py b/resources/lib/WriteKodiDB.py index f03a161f..a59b8e85 100644 --- a/resources/lib/WriteKodiDB.py +++ b/resources/lib/WriteKodiDB.py @@ -791,7 +791,7 @@ class WriteKodiDB(): #if wanted this feature can be extended to also update the other artwork tvshowid = KodiItem["tvshowid"] - dbPath = xbmc.translatePath("special://userdata/Database/MyVideos90.db") + dbPath = xbmc.translatePath("special://userdata/Database/MyVideos%s.db" % utils.DATABASE_VERSION_HELIX) connection = sqlite3.connect(dbPath) cursor = connection.cursor( ) @@ -820,7 +820,7 @@ class WriteKodiDB(): utils.logMsg("MB3 Sync","setting resume point in kodi db..." + fileType + ": " + str(id)) xbmc.sleep(sleepVal) - dbPath = xbmc.translatePath("special://userdata/Database/MyVideos90.db") + dbPath = xbmc.translatePath("special://userdata/Database/MyVideos%s.db" % utils.DATABASE_VERSION_HELIX) connection = sqlite3.connect(dbPath) cursor = connection.cursor( ) @@ -874,7 +874,8 @@ class WriteKodiDB(): xbmc.sleep(sleepVal) - dbPath = xbmc.translatePath("special://userdata/Database/MyVideos90.db") + dbPath = xbmc.translatePath("special://userdata/Database/MyVideos%s.db" % utils.DATABASE_VERSION_HELIX) + connection = sqlite3.connect(dbPath) cursor = connection.cursor() From 0c92e86b393122fc454739f0e6c00b2488ca4201 Mon Sep 17 00:00:00 2001 From: faush01 Date: Tue, 24 Mar 2015 10:02:46 +1100 Subject: [PATCH 3/6] add some more notification options --- resources/lib/LibrarySync.py | 104 +++++++++++++++++++++++------------ resources/settings.xml | 4 +- 2 files changed, 70 insertions(+), 38 deletions(-) diff --git a/resources/lib/LibrarySync.py b/resources/lib/LibrarySync.py index 910f211e..6f7a0012 100644 --- a/resources/lib/LibrarySync.py +++ b/resources/lib/LibrarySync.py @@ -77,13 +77,14 @@ class LibrarySync(): addon = xbmcaddon.Addon(id='plugin.video.mb3sync') WINDOW = xbmcgui.Window( 10000 ) pDialog = None + startedSync = datetime.today() try: dbSyncIndication = addon.getSetting("dbSyncIndication") - if(addon.getSetting("SyncFirstMovieRunDone") != 'true'): + if(addon.getSetting("SyncFirstMovieRunDone") != "true" or dbSyncIndication == "Dialog Progress"): pDialog = xbmcgui.DialogProgress() - elif(dbSyncIndication == "Progress"): + elif(dbSyncIndication == "BG Progress"): pDialog = xbmcgui.DialogProgressBG() if(pDialog != None): @@ -217,18 +218,28 @@ class LibrarySync(): addon.setSetting("SyncFirstMovieRunDone", "true") - if(dbSyncIndication == "Notification"): - notificationString = "" - if(totalItemsAdded > 0): - notificationString += "Added:" + str(totalItemsAdded) + " " - if(totalItemsUpdated > 0): - notificationString += "Updated:" + str(totalItemsUpdated) + " " - if(totalItemsDeleted > 0): - notificationString += "Deleted:" + str(totalItemsDeleted) + " " + # display notification if set up + notificationString = "" + if(totalItemsAdded > 0): + notificationString += "Added:" + str(totalItemsAdded) + " " + if(totalItemsUpdated > 0): + notificationString += "Updated:" + str(totalItemsUpdated) + " " + if(totalItemsDeleted > 0): + notificationString += "Deleted:" + str(totalItemsDeleted) + " " + + timeTaken = datetime.today() - startedSync + timeTakenString = str(int(timeTaken.seconds / 60)) + ":" + str(timeTaken.seconds % 60) + utils.logMsg("Sync Movies", "Finished " + timeTakenString + " " + notificationString, 0) + + if(dbSyncIndication == "Notify OnChange" and notificationString != ""): + notificationString = "(" + timeTakenString + ") " + notificationString + xbmc.executebuiltin("XBMC.Notification(Movie Sync: " + notificationString + ",)") + elif(dbSyncIndication == "Notify OnFinish"): if(notificationString == ""): notificationString = "Done" + notificationString = "(" + timeTakenString + ") " + notificationString xbmc.executebuiltin("XBMC.Notification(Movie Sync: " + notificationString + ",)") - + finally: if(pDialog != None): pDialog.close() @@ -240,13 +251,14 @@ class LibrarySync(): addon = xbmcaddon.Addon(id='plugin.video.mb3sync') WINDOW = xbmcgui.Window( 10000 ) pDialog = None + startedSync = datetime.today() try: dbSyncIndication = addon.getSetting("dbSyncIndication") - if(addon.getSetting("SyncFirstTVRunDone") != 'true'): + if(addon.getSetting("SyncFirstTVRunDone") != "true" or dbSyncIndication == "Dialog Progress"): pDialog = xbmcgui.DialogProgress() - elif(dbSyncIndication == "Progress"): + elif(dbSyncIndication == "BG Progress"): pDialog = xbmcgui.DialogProgressBG() if(pDialog != None): @@ -562,19 +574,29 @@ class LibrarySync(): self.doKodiLibraryUpdate(True, pDialog) addon.setSetting("SyncFirstTVRunDone", "true") + + # display notification if set up + notificationString = "" + if(totalItemsAdded > 0): + notificationString += "Added:" + str(totalItemsAdded) + " " + if(totalItemsUpdated > 0): + notificationString += "Updated:" + str(totalItemsUpdated) + " " + if(totalItemsDeleted > 0): + notificationString += "Deleted:" + str(totalItemsDeleted) + " " + + timeTaken = datetime.today() - startedSync + timeTakenString = str(int(timeTaken.seconds / 60)) + ":" + str(timeTaken.seconds % 60) + utils.logMsg("Sync Episodes", "Finished " + timeTakenString + " " + notificationString, 0) - if(dbSyncIndication == "Notification"): - notificationString = "" - if(totalItemsAdded > 0): - notificationString += "Added:" + str(totalItemsAdded) + " " - if(totalItemsUpdated > 0): - notificationString += "Updated:" + str(totalItemsUpdated) + " " - if(totalItemsDeleted > 0): - notificationString += "Deleted:" + str(totalItemsDeleted) + " " + if(dbSyncIndication == "Notify OnChange" and notificationString != ""): + notificationString = "(" + timeTakenString + ") " + notificationString + xbmc.executebuiltin("XBMC.Notification(Episode Sync: " + notificationString + ",)") + elif(dbSyncIndication == "Notify OnFinish"): if(notificationString == ""): notificationString = "Done" - xbmc.executebuiltin("XBMC.Notification(TV Sync: " + notificationString + ",)") - + notificationString = "(" + timeTakenString + ") " + notificationString + xbmc.executebuiltin("XBMC.Notification(Episode Sync: " + notificationString + ",)") + finally: if(pDialog != None): pDialog.close() @@ -590,9 +612,9 @@ class LibrarySync(): try: dbSyncIndication = addon.getSetting("dbSyncIndication") - if(addon.getSetting("SyncFirstMusicVideoRunDone") != 'true'): + if(addon.getSetting("SyncFirstMusicVideoRunDone") != "true" or dbSyncIndication == "Dialog Progress"): pDialog = xbmcgui.DialogProgress() - elif(dbSyncIndication == "Progress"): + elif(dbSyncIndication == "BG Progress"): pDialog = xbmcgui.DialogProgressBG() if(pDialog != None): @@ -732,16 +754,16 @@ class LibrarySync(): addon = xbmcaddon.Addon(id='plugin.video.mb3sync') WINDOW = xbmcgui.Window( 10000 ) pDialog = None - + startedSync = datetime.today() processMovies = True processTvShows = True try: playCountSyncIndication = addon.getSetting("playCountSyncIndication") - if(addon.getSetting("SyncFirstCountsRunDone") != 'true'): + if(addon.getSetting("SyncFirstCountsRunDone") != "true" or playCountSyncIndication == "Dialog Progress"): pDialog = xbmcgui.DialogProgress() - elif(playCountSyncIndication == "Progress"): + elif(playCountSyncIndication == "BG Progress"): pDialog = xbmcgui.DialogProgressBG() if(pDialog != None): @@ -869,17 +891,27 @@ class LibrarySync(): showCurrent += 1 addon.setSetting("SyncFirstCountsRunDone", "true") + + # display notification if set up + notificationString = "" + if(totalPositionsUpdated > 0): + notificationString += "Pos:" + str(totalPositionsUpdated) + " " + if(totalCountsUpdated > 0): + notificationString += "Counts:" + str(totalCountsUpdated) + " " + + timeTaken = datetime.today() - startedSync + timeTakenString = str(int(timeTaken.seconds / 60)) + ":" + str(timeTaken.seconds % 60) + utils.logMsg("Sync PlayCount", "Finished " + timeTakenString + " " + notificationString, 0) - if(playCountSyncIndication == "Notification"): - notificationString = "" - if(totalPositionsUpdated > 0): - notificationString += "Pos:" + str(totalPositionsUpdated) + " " - if(totalCountsUpdated > 0): - notificationString += "Counts:" + str(totalCountsUpdated) + " " + if(playCountSyncIndication == "Notify OnChange" and notificationString != ""): + notificationString = "(" + timeTakenString + ") " + notificationString + xbmc.executebuiltin("XBMC.Notification(PlayCount Sync: " + notificationString + ",)") + elif(playCountSyncIndication == "Notify OnFinish"): if(notificationString == ""): notificationString = "Done" - xbmc.executebuiltin("XBMC.Notification(Play Sync: " + notificationString + ",)") - + notificationString = "(" + timeTakenString + ") " + notificationString + xbmc.executebuiltin("XBMC.Notification(PlayCount Sync: " + notificationString + ",)") + finally: if(pDialog != None): pDialog.close() diff --git a/resources/settings.xml b/resources/settings.xml index 4545166b..122e49d3 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -11,8 +11,8 @@ - - + + From c90ae07a5363d866819c2c9216424d452c23adbf Mon Sep 17 00:00:00 2001 From: xnappo Date: Mon, 23 Mar 2015 19:35:00 -0500 Subject: [PATCH 4/6] Episode delete test --- resources/lib/KodiMonitor.py | 11 +++++++++++ resources/lib/LibrarySync.py | 2 ++ 2 files changed, 13 insertions(+) diff --git a/resources/lib/KodiMonitor.py b/resources/lib/KodiMonitor.py index 66810370..ac963764 100644 --- a/resources/lib/KodiMonitor.py +++ b/resources/lib/KodiMonitor.py @@ -33,4 +33,15 @@ class Kodi_Monitor(xbmc.Monitor): if playcount != None: utils.logMsg("MB# Sync","Kodi_Monitor--> VideoLibrary.OnUpdate : " + str(data),2) WriteKodiDB().updatePlayCountFromKodi(item, type, playcount) + if method == "VideoLibrary.OnRemove": + + jsondata = json.loads(data) + if jsondata != None: + if jsondata.get("type") == "episode": + episodeid = jsondata.get("id") + WINDOW = xbmcgui.Window( 10000 ) + MBlist = WINDOW.getProperty("episodeid" + str(episodeid)).split(";;") + return_value = xbmcgui.Dialog().yesno("Confirm Delete", "Not really going to, but if I were I would delete: Title - "+ MBlist[0] + " MBID: " + MBlist[1]) + + diff --git a/resources/lib/LibrarySync.py b/resources/lib/LibrarySync.py index 6f7a0012..04d6b3b2 100644 --- a/resources/lib/LibrarySync.py +++ b/resources/lib/LibrarySync.py @@ -868,6 +868,8 @@ class LibrarySync(): userData=API().getUserData(episode) timeInfo = API().getTimeInfo(episode) if kodiItem != None: + WINDOW = xbmcgui.Window( 10000 ) + WINDOW.setProperty("episodeid" + str(kodiItem['episodeid']), episode.get('Name') + ";;" + episode.get('Id')) if kodiItem['playcount'] != int(userData.get("PlayCount")): updated = WriteKodiDB().updateProperty(kodiItem,"playcount",int(userData.get("PlayCount")),"episode") if(updated): From c9fb82cf3c489bdb0918e21a5f67cd98d85e81f4 Mon Sep 17 00:00:00 2001 From: xnappo Date: Mon, 23 Mar 2015 22:54:11 -0500 Subject: [PATCH 5/6] Back out delete Need to add check if item is already deleted on Emby server --- resources/lib/KodiMonitor.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/resources/lib/KodiMonitor.py b/resources/lib/KodiMonitor.py index ac963764..e653e8c0 100644 --- a/resources/lib/KodiMonitor.py +++ b/resources/lib/KodiMonitor.py @@ -10,6 +10,7 @@ import json import Utils as utils from WriteKodiDB import WriteKodiDB +from DownloadUtils import DownloadUtils class Kodi_Monitor(xbmc.Monitor): def __init__(self, *args, **kwargs): @@ -20,7 +21,10 @@ class Kodi_Monitor(xbmc.Monitor): #this library monitor is used to detect a watchedstate change by the user through the library def onNotification (self,sender,method,data): - + addon = xbmcaddon.Addon(id='plugin.video.mb3sync') + port = addon.getSetting('port') + host = addon.getSetting('ipaddress') + server = host + ":" + port if method == "VideoLibrary.OnUpdate": jsondata = json.loads(data) @@ -34,14 +38,19 @@ class Kodi_Monitor(xbmc.Monitor): utils.logMsg("MB# Sync","Kodi_Monitor--> VideoLibrary.OnUpdate : " + str(data),2) WriteKodiDB().updatePlayCountFromKodi(item, type, playcount) if method == "VideoLibrary.OnRemove": - + xbmc.log('Intercepted remove from sender: ' + sender + ' method: ' + method + ' data: ' + data) jsondata = json.loads(data) if jsondata != None: if jsondata.get("type") == "episode": episodeid = jsondata.get("id") WINDOW = xbmcgui.Window( 10000 ) MBlist = WINDOW.getProperty("episodeid" + str(episodeid)).split(";;") - return_value = xbmcgui.Dialog().yesno("Confirm Delete", "Not really going to, but if I were I would delete: Title - "+ MBlist[0] + " MBID: " + MBlist[1]) + #NEED TO CHECK IF ITEM STILL EXISTS ON EMBY SERVER + #return_value = xbmcgui.Dialog().yesno("Confirm Delete", "Delete: "+ MBlist[0] + "\n on Emby Server?\nEmbyID: " + MBlist[1]) + #if return_value: + # url='http://' + server + '/mediabrowser/Items/' + MBlist[1] + # xbmc.log('Deleting via URL: ' + url) + # DownloadUtils().downloadUrl(url, type="DELETE") From ccf77f3be26943d92438782173ffbdcddb65413d Mon Sep 17 00:00:00 2001 From: im85288 Date: Tue, 24 Mar 2015 16:47:26 +0000 Subject: [PATCH 6/6] add support for box sets --- resources/lib/LibrarySync.py | 8 +++++ resources/lib/ReadEmbyDB.py | 42 ++++++++++++++++++++++++++ resources/lib/WriteKodiDB.py | 58 ++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) diff --git a/resources/lib/LibrarySync.py b/resources/lib/LibrarySync.py index 04d6b3b2..79318d02 100644 --- a/resources/lib/LibrarySync.py +++ b/resources/lib/LibrarySync.py @@ -164,6 +164,14 @@ class LibrarySync(): total = len(allMB3Movies) + 1 count = 1 + # process box sets - TODO cope with movies removed from a set + boxsets = ReadEmbyDB().getBoxSets() + for boxset in boxsets: + boxsetMovies = ReadEmbyDB().getMoviesInBoxSet(boxset["Id"]) + WriteKodiDB().addBoxsetToKodiLibrary(boxset) + for boxsetMovie in boxsetMovies: + WriteKodiDB().updateBoxsetToKodiLibrary(boxsetMovie,boxset) + #process updates allKodiMovies = ReadKodiDB().getKodiMovies(True) for item in allMB3Movies: diff --git a/resources/lib/ReadEmbyDB.py b/resources/lib/ReadEmbyDB.py index 74b65216..134f22d2 100644 --- a/resources/lib/ReadEmbyDB.py +++ b/resources/lib/ReadEmbyDB.py @@ -273,4 +273,46 @@ class ReadEmbyDB(): 'type' : type, 'id' : view.get("Id")}) return collections + + def getBoxSets(self): + result = None + + addon = xbmcaddon.Addon(id='plugin.video.mb3sync') + port = addon.getSetting('port') + host = addon.getSetting('ipaddress') + server = host + ":" + port + + downloadUtils = DownloadUtils() + userid = downloadUtils.getUserId() + + url = server + '/mediabrowser/Users/' + userid + '/Items?SortBy=SortName&IsVirtualUnaired=false&IsMissing=False&Fields=Name,SortName,CumulativeRunTimeTicks&Recursive=true&SortOrder=Ascending&IncludeItemTypes=BoxSet&format=json&ImageTypeLimit=1' + + jsonData = downloadUtils.downloadUrl(url, suppress=True, popup=0) + + if jsonData != None and jsonData != "": + result = json.loads(jsonData) + if(result.has_key('Items')): + result = result['Items'] + return result + + def getMoviesInBoxSet(self,boxsetId): + result = None + + addon = xbmcaddon.Addon(id='plugin.video.mb3sync') + port = addon.getSetting('port') + host = addon.getSetting('ipaddress') + server = host + ":" + port + + downloadUtils = DownloadUtils() + userid = downloadUtils.getUserId() + + url = server + '/mediabrowser/Users/' + userid + '/Items?ParentId=' + boxsetId + '&Fields=ItemCounts&format=json&ImageTypeLimit=1' + + jsonData = downloadUtils.downloadUrl(url, suppress=True, popup=0) + + if jsonData != None and jsonData != "": + result = json.loads(jsonData) + if(result.has_key('Items')): + result = result['Items'] + return result diff --git a/resources/lib/WriteKodiDB.py b/resources/lib/WriteKodiDB.py index a59b8e85..2e1754c5 100644 --- a/resources/lib/WriteKodiDB.py +++ b/resources/lib/WriteKodiDB.py @@ -911,3 +911,61 @@ class WriteKodiDB(): cursor.close() return True + + def addBoxsetToKodiLibrary(self, boxset): + #use sqlite to set add the set + dbPath = xbmc.translatePath("special://userdata/Database/MyVideos%s.db" % utils.DATABASE_VERSION_HELIX) + + connection = sqlite3.connect(dbPath) + cursor = connection.cursor() + + strSet = boxset["Name"] + # check if exists + cursor.execute("SELECT idSet FROM sets WHERE strSet = ?", (strSet,)) + result = cursor.fetchone() + setid = None + if result != None: + setid = result[0] + currentsetartsql = "SELECT type, url FROM art where media_type = ? and media_id = ? and url != ''" + cursor.execute(currentsetartsql, ("set", setid)) + existing_type_map = {} + rows = cursor.fetchall() + for row in rows: + existing_type_map[row[0] ] = row[1] + + artwork = {} + artwork["poster"] = API().getArtwork(boxset, "Primary") + artwork["banner"] = API().getArtwork(boxset, "Banner") + artwork["clearlogo"] = API().getArtwork(boxset, "Logo") + artwork["clearart"] = API().getArtwork(boxset, "Art") + artwork["landscape"] = API().getArtwork(boxset, "Thumb") + artwork["discart"] = API().getArtwork(boxset, "Disc") + artwork["fanart"] = API().getArtwork(boxset, "Backdrop") + + art_types = {'poster','fanart','landscape','clearlogo','clearart','banner','discart'} + for update_type in art_types: + if ( update_type in existing_type_map ): + if ( existing_type_map[update_type] != artwork[update_type] ) and artwork[update_type] != '': + setupdateartsql = "UPDATE art SET url = ? where media_type = ? and media_id = ? and type = ?" + cursor.execute(setupdateartsql,(artwork[update_type],"set",setid,update_type)) + elif artwork[update_type] != '': + setartsql = "INSERT INTO art(media_id, media_type, type, url) VALUES(?,?,?,?)" + cursor.execute(setartsql,(setid,"set",update_type,artwork[update_type])) + + if setid == None: + # insert not exists + setssql="INSERT INTO sets (idSet, strSet) values(?, ?)" + cursor.execute(setssql, (None,strSet)) + #if OK: + result = cursor.fetchone() + if result != None: + setid = result[0] + connection.commit() + cursor.close() + + return True + + def updateBoxsetToKodiLibrary(self, boxsetmovie, boxset): + strSet = boxset["Name"] + kodiMovie = ReadKodiDB().getKodiMovie(boxsetmovie["Id"]) + WriteKodiDB().updateProperty(kodiMovie,"set",strSet,"movie",True) \ No newline at end of file