This commit is contained in:
Marcel van der Veldt 2015-03-24 19:42:04 +01:00
commit 7e33194e84
7 changed files with 212 additions and 46 deletions

View file

@ -130,8 +130,10 @@ class DownloadUtils():
self.logMsg("Session Id : " + str(sessionId)) self.logMsg("Session Id : " + str(sessionId))
# post capability data # post capability data
playableMediaTypes = "Audio,Video,Photo" #playableMediaTypes = "Audio,Video,Photo"
supportedCommands = "Play,Playstate,DisplayContent,GoHome,SendString,GoToSettings,DisplayMessage,PlayNext" 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" url = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Sessions/Capabilities?Id=" + sessionId + "&PlayableMediaTypes=" + playableMediaTypes + "&SupportedCommands=" + supportedCommands + "&SupportsMediaControl=True"
postData = {} postData = {}

View file

@ -10,6 +10,7 @@ import json
import Utils as utils import Utils as utils
from WriteKodiDB import WriteKodiDB from WriteKodiDB import WriteKodiDB
from DownloadUtils import DownloadUtils
class Kodi_Monitor(xbmc.Monitor): class Kodi_Monitor(xbmc.Monitor):
def __init__(self, *args, **kwargs): 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 #this library monitor is used to detect a watchedstate change by the user through the library
def onNotification (self,sender,method,data): 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": if method == "VideoLibrary.OnUpdate":
jsondata = json.loads(data) jsondata = json.loads(data)
@ -33,4 +37,20 @@ class Kodi_Monitor(xbmc.Monitor):
if playcount != None: if playcount != None:
utils.logMsg("MB# Sync","Kodi_Monitor--> VideoLibrary.OnUpdate : " + str(data),2) utils.logMsg("MB# Sync","Kodi_Monitor--> VideoLibrary.OnUpdate : " + str(data),2)
WriteKodiDB().updatePlayCountFromKodi(item, type, playcount) 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(";;")
#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")

View file

@ -77,13 +77,14 @@ class LibrarySync():
addon = xbmcaddon.Addon(id='plugin.video.mb3sync') addon = xbmcaddon.Addon(id='plugin.video.mb3sync')
WINDOW = xbmcgui.Window( 10000 ) WINDOW = xbmcgui.Window( 10000 )
pDialog = None pDialog = None
startedSync = datetime.today()
try: try:
dbSyncIndication = addon.getSetting("dbSyncIndication") dbSyncIndication = addon.getSetting("dbSyncIndication")
if(addon.getSetting("SyncFirstMovieRunDone") != 'true'): if(addon.getSetting("SyncFirstMovieRunDone") != "true" or dbSyncIndication == "Dialog Progress"):
pDialog = xbmcgui.DialogProgress() pDialog = xbmcgui.DialogProgress()
elif(dbSyncIndication == "Progress"): elif(dbSyncIndication == "BG Progress"):
pDialog = xbmcgui.DialogProgressBG() pDialog = xbmcgui.DialogProgressBG()
if(pDialog != None): if(pDialog != None):
@ -163,6 +164,14 @@ class LibrarySync():
total = len(allMB3Movies) + 1 total = len(allMB3Movies) + 1
count = 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 #process updates
allKodiMovies = ReadKodiDB().getKodiMovies(True) allKodiMovies = ReadKodiDB().getKodiMovies(True)
for item in allMB3Movies: for item in allMB3Movies:
@ -217,18 +226,28 @@ class LibrarySync():
addon.setSetting("SyncFirstMovieRunDone", "true") addon.setSetting("SyncFirstMovieRunDone", "true")
if(dbSyncIndication == "Notification"): # display notification if set up
notificationString = "" notificationString = ""
if(totalItemsAdded > 0): if(totalItemsAdded > 0):
notificationString += "Added:" + str(totalItemsAdded) + " " notificationString += "Added:" + str(totalItemsAdded) + " "
if(totalItemsUpdated > 0): if(totalItemsUpdated > 0):
notificationString += "Updated:" + str(totalItemsUpdated) + " " notificationString += "Updated:" + str(totalItemsUpdated) + " "
if(totalItemsDeleted > 0): if(totalItemsDeleted > 0):
notificationString += "Deleted:" + str(totalItemsDeleted) + " " 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 == ""): if(notificationString == ""):
notificationString = "Done" notificationString = "Done"
notificationString = "(" + timeTakenString + ") " + notificationString
xbmc.executebuiltin("XBMC.Notification(Movie Sync: " + notificationString + ",)") xbmc.executebuiltin("XBMC.Notification(Movie Sync: " + notificationString + ",)")
finally: finally:
if(pDialog != None): if(pDialog != None):
pDialog.close() pDialog.close()
@ -240,13 +259,14 @@ class LibrarySync():
addon = xbmcaddon.Addon(id='plugin.video.mb3sync') addon = xbmcaddon.Addon(id='plugin.video.mb3sync')
WINDOW = xbmcgui.Window( 10000 ) WINDOW = xbmcgui.Window( 10000 )
pDialog = None pDialog = None
startedSync = datetime.today()
try: try:
dbSyncIndication = addon.getSetting("dbSyncIndication") dbSyncIndication = addon.getSetting("dbSyncIndication")
if(addon.getSetting("SyncFirstTVRunDone") != 'true'): if(addon.getSetting("SyncFirstTVRunDone") != "true" or dbSyncIndication == "Dialog Progress"):
pDialog = xbmcgui.DialogProgress() pDialog = xbmcgui.DialogProgress()
elif(dbSyncIndication == "Progress"): elif(dbSyncIndication == "BG Progress"):
pDialog = xbmcgui.DialogProgressBG() pDialog = xbmcgui.DialogProgressBG()
if(pDialog != None): if(pDialog != None):
@ -562,19 +582,29 @@ class LibrarySync():
self.doKodiLibraryUpdate(True, pDialog) self.doKodiLibraryUpdate(True, pDialog)
addon.setSetting("SyncFirstTVRunDone", "true") 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"): if(dbSyncIndication == "Notify OnChange" and notificationString != ""):
notificationString = "" notificationString = "(" + timeTakenString + ") " + notificationString
if(totalItemsAdded > 0): xbmc.executebuiltin("XBMC.Notification(Episode Sync: " + notificationString + ",)")
notificationString += "Added:" + str(totalItemsAdded) + " " elif(dbSyncIndication == "Notify OnFinish"):
if(totalItemsUpdated > 0):
notificationString += "Updated:" + str(totalItemsUpdated) + " "
if(totalItemsDeleted > 0):
notificationString += "Deleted:" + str(totalItemsDeleted) + " "
if(notificationString == ""): if(notificationString == ""):
notificationString = "Done" notificationString = "Done"
xbmc.executebuiltin("XBMC.Notification(TV Sync: " + notificationString + ",)") notificationString = "(" + timeTakenString + ") " + notificationString
xbmc.executebuiltin("XBMC.Notification(Episode Sync: " + notificationString + ",)")
finally: finally:
if(pDialog != None): if(pDialog != None):
pDialog.close() pDialog.close()
@ -590,9 +620,9 @@ class LibrarySync():
try: try:
dbSyncIndication = addon.getSetting("dbSyncIndication") dbSyncIndication = addon.getSetting("dbSyncIndication")
if(addon.getSetting("SyncFirstMusicVideoRunDone") != 'true'): if(addon.getSetting("SyncFirstMusicVideoRunDone") != "true" or dbSyncIndication == "Dialog Progress"):
pDialog = xbmcgui.DialogProgress() pDialog = xbmcgui.DialogProgress()
elif(dbSyncIndication == "Progress"): elif(dbSyncIndication == "BG Progress"):
pDialog = xbmcgui.DialogProgressBG() pDialog = xbmcgui.DialogProgressBG()
if(pDialog != None): if(pDialog != None):
@ -732,16 +762,16 @@ class LibrarySync():
addon = xbmcaddon.Addon(id='plugin.video.mb3sync') addon = xbmcaddon.Addon(id='plugin.video.mb3sync')
WINDOW = xbmcgui.Window( 10000 ) WINDOW = xbmcgui.Window( 10000 )
pDialog = None pDialog = None
startedSync = datetime.today()
processMovies = True processMovies = True
processTvShows = True processTvShows = True
try: try:
playCountSyncIndication = addon.getSetting("playCountSyncIndication") playCountSyncIndication = addon.getSetting("playCountSyncIndication")
if(addon.getSetting("SyncFirstCountsRunDone") != 'true'): if(addon.getSetting("SyncFirstCountsRunDone") != "true" or playCountSyncIndication == "Dialog Progress"):
pDialog = xbmcgui.DialogProgress() pDialog = xbmcgui.DialogProgress()
elif(playCountSyncIndication == "Progress"): elif(playCountSyncIndication == "BG Progress"):
pDialog = xbmcgui.DialogProgressBG() pDialog = xbmcgui.DialogProgressBG()
if(pDialog != None): if(pDialog != None):
@ -846,6 +876,8 @@ class LibrarySync():
userData=API().getUserData(episode) userData=API().getUserData(episode)
timeInfo = API().getTimeInfo(episode) timeInfo = API().getTimeInfo(episode)
if kodiItem != None: 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")): if kodiItem['playcount'] != int(userData.get("PlayCount")):
updated = WriteKodiDB().updateProperty(kodiItem,"playcount",int(userData.get("PlayCount")),"episode") updated = WriteKodiDB().updateProperty(kodiItem,"playcount",int(userData.get("PlayCount")),"episode")
if(updated): if(updated):
@ -869,17 +901,27 @@ class LibrarySync():
showCurrent += 1 showCurrent += 1
addon.setSetting("SyncFirstCountsRunDone", "true") 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"): if(playCountSyncIndication == "Notify OnChange" and notificationString != ""):
notificationString = "" notificationString = "(" + timeTakenString + ") " + notificationString
if(totalPositionsUpdated > 0): xbmc.executebuiltin("XBMC.Notification(PlayCount Sync: " + notificationString + ",)")
notificationString += "Pos:" + str(totalPositionsUpdated) + " " elif(playCountSyncIndication == "Notify OnFinish"):
if(totalCountsUpdated > 0):
notificationString += "Counts:" + str(totalCountsUpdated) + " "
if(notificationString == ""): if(notificationString == ""):
notificationString = "Done" notificationString = "Done"
xbmc.executebuiltin("XBMC.Notification(Play Sync: " + notificationString + ",)") notificationString = "(" + timeTakenString + ") " + notificationString
xbmc.executebuiltin("XBMC.Notification(PlayCount Sync: " + notificationString + ",)")
finally: finally:
if(pDialog != None): if(pDialog != None):
pDialog.close() pDialog.close()

View file

@ -273,4 +273,46 @@ class ReadEmbyDB():
'type' : type, 'type' : type,
'id' : view.get("Id")}) 'id' : view.get("Id")})
return collections 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

View file

@ -23,7 +23,8 @@ from PlayUtils import PlayUtils
from DownloadUtils import DownloadUtils from DownloadUtils import DownloadUtils
downloadUtils = DownloadUtils() downloadUtils = DownloadUtils()
addonSettings = xbmcaddon.Addon(id='plugin.video.mb3sync') addonSettings = xbmcaddon.Addon(id='plugin.video.mb3sync')
language = addonSettings.getLocalizedString language = addonSettings.getLocalizedString
DATABASE_VERSION_HELIX = "90"
def logMsg(title, msg, level = 1): def logMsg(title, msg, level = 1):
logLevel = int(addonSettings.getSetting("logLevel")) 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 #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. #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 #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 error = False
if xbmcvfs.exists(dbPath): if xbmcvfs.exists(dbPath):

View file

@ -791,7 +791,7 @@ class WriteKodiDB():
#if wanted this feature can be extended to also update the other artwork #if wanted this feature can be extended to also update the other artwork
tvshowid = KodiItem["tvshowid"] 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) connection = sqlite3.connect(dbPath)
cursor = connection.cursor( ) cursor = connection.cursor( )
@ -820,7 +820,7 @@ class WriteKodiDB():
utils.logMsg("MB3 Sync","setting resume point in kodi db..." + fileType + ": " + str(id)) utils.logMsg("MB3 Sync","setting resume point in kodi db..." + fileType + ": " + str(id))
xbmc.sleep(sleepVal) 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) connection = sqlite3.connect(dbPath)
cursor = connection.cursor( ) cursor = connection.cursor( )
@ -874,7 +874,8 @@ class WriteKodiDB():
xbmc.sleep(sleepVal) 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) connection = sqlite3.connect(dbPath)
cursor = connection.cursor() cursor = connection.cursor()
@ -910,3 +911,61 @@ class WriteKodiDB():
cursor.close() cursor.close()
return True 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)

View file

@ -11,8 +11,8 @@
<setting id="enablePlayCountSync" type="bool" label="Enable watched/resume status sync" default="true" visible="true" enable="true" /> <setting id="enablePlayCountSync" type="bool" label="Enable watched/resume status sync" default="true" visible="true" enable="true" />
<setting id="syncSettingStartup" type="labelenum" label="Startup Sync:" values="Full Sync|Incremental Sync|None" default="Full Sync" /> <setting id="syncSettingStartup" type="labelenum" label="Startup Sync:" values="Full Sync|Incremental Sync|None" default="Full Sync" />
<setting id="syncSettingBackground" type="labelenum" label="Scheduled Sync:" values="Full Sync|Incremental Sync|None" default="Full Sync" visible="true" enable="true" /> <setting id="syncSettingBackground" type="labelenum" label="Scheduled Sync:" values="Full Sync|Incremental Sync|None" default="Full Sync" visible="true" enable="true" />
<setting id="dbSyncIndication" type="labelenum" label="DB Sync Indication:" values="None|Notification|Progress" default="None" /> <setting id="dbSyncIndication" type="labelenum" label="DB Sync Indication:" values="None|Notify OnChange|Notify OnFinish|BG Progress|Dialog Progress" default="None" />
<setting id="playCountSyncIndication" type="labelenum" label="Play Count Sync Indication:" values="None|Notification|Progress" default="None" /> <setting id="playCountSyncIndication" type="labelenum" label="Play Count Sync Indication:" values="None|Notify OnChange|Notify OnFinish|BG Progress|Dialog Progress" default="None" />
</category> </category>
<category label="30014"> <!-- MediaBrowser --> <category label="30014"> <!-- MediaBrowser -->