mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2025-06-11 10:46:13 +00:00
Merge branch 'clean-up'
This commit is contained in:
commit
0e32e254e3
8 changed files with 321 additions and 214 deletions
|
@ -11,7 +11,6 @@ import json
|
|||
import Utils as utils
|
||||
from WriteKodiVideoDB import WriteKodiVideoDB
|
||||
from ReadKodiDB import ReadKodiDB
|
||||
from LibrarySync import LibrarySync
|
||||
from PlayUtils import PlayUtils
|
||||
from DownloadUtils import DownloadUtils
|
||||
from PlaybackUtils import PlaybackUtils
|
||||
|
@ -119,11 +118,7 @@ class Kodi_Monitor(xbmc.Monitor):
|
|||
|
||||
if method == "System.OnWake":
|
||||
xbmc.sleep(10000) #Allow network to wake up
|
||||
if WINDOW.getProperty("SyncDatabaseRunning") != "true":
|
||||
utils.logMsg("Doing_Db_Sync Post Resume: syncDatabase (Started)",0)
|
||||
libSync = LibrarySync().FullLibrarySync()
|
||||
utils.logMsg("Doing_Db_Sync Post Resume: syncDatabase (Finished) " + str(libSync),0)
|
||||
|
||||
WINDOW.setProperty("OnWakeSync", "true")
|
||||
|
||||
if method == "VideoLibrary.OnRemove":
|
||||
xbmc.log('Intercepted remove from sender: ' + sender + ' method: ' + method + ' data: ' + data)
|
||||
|
@ -139,7 +134,7 @@ class Kodi_Monitor(xbmc.Monitor):
|
|||
cursor.close
|
||||
|
||||
if jsondata:
|
||||
if jsondata.get("type") == "episode":
|
||||
if jsondata.get("type") == "episode" or "movie":
|
||||
url='{server}/mediabrowser/Items?Ids=' + id + '&format=json'
|
||||
#This is a check to see if the item exists on the server, if it doesn't it may have already been deleted by another client
|
||||
result = DownloadUtils().downloadUrl(url)
|
||||
|
|
|
@ -16,8 +16,10 @@ from itertools import chain
|
|||
import urllib2
|
||||
import os
|
||||
|
||||
import KodiMonitor
|
||||
from API import API
|
||||
import Utils as utils
|
||||
from ClientInformation import ClientInformation
|
||||
from DownloadUtils import DownloadUtils
|
||||
from ReadEmbyDB import ReadEmbyDB
|
||||
from ReadKodiDB import ReadKodiDB
|
||||
|
@ -32,7 +34,28 @@ tvLibrary = os.path.join(dataPath,'tvshows')
|
|||
|
||||
WINDOW = xbmcgui.Window( 10000 )
|
||||
|
||||
class LibrarySync():
|
||||
class LibrarySync(threading.Thread):
|
||||
|
||||
_shared_state = {}
|
||||
|
||||
KodiMonitor = KodiMonitor.Kodi_Monitor()
|
||||
clientInfo = ClientInformation()
|
||||
|
||||
addonName = clientInfo.getAddonName()
|
||||
|
||||
doIncrementalSync = False
|
||||
updateItems = []
|
||||
removeItems = []
|
||||
|
||||
def __init__(self, *args):
|
||||
|
||||
self.__dict__ = self._shared_state
|
||||
threading.Thread.__init__(self, *args)
|
||||
|
||||
def logMsg(self, msg, lvl=1):
|
||||
|
||||
className = self.__class__.__name__
|
||||
utils.logMsg("%s %s" % (self.addonName, className), msg, int(lvl))
|
||||
|
||||
def FullLibrarySync(self,manualRun=False):
|
||||
|
||||
|
@ -632,6 +655,103 @@ class LibrarySync():
|
|||
# tell any widgets to refresh because the content has changed
|
||||
WINDOW.setProperty("widgetreload", datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
|
||||
|
||||
def removefromDB(self, itemList, deleteEmbyItem = False):
|
||||
# Delete from Kodi before Emby
|
||||
# To be able to get mediaType
|
||||
doUtils = DownloadUtils()
|
||||
|
||||
video = []
|
||||
music = []
|
||||
|
||||
itemIds = ','.join(itemList)
|
||||
url = "{server}/mediabrowser/Users/{UserId}/Items?Ids=%s&format=json" % itemIds
|
||||
result = doUtils.downloadUrl(url)
|
||||
|
||||
if result is "":
|
||||
# Websocket feedback
|
||||
self.logMsg("Item %s is removed." % itemIds)
|
||||
return
|
||||
|
||||
for item in result[u'Items']:
|
||||
# Sort by type for database deletion
|
||||
itemId = item["Id"]
|
||||
mediaType = item["MediaType"]
|
||||
|
||||
if "Video" in mediaType:
|
||||
video.append(itemId)
|
||||
elif "Audio" in mediaType:
|
||||
music.append(itemId)
|
||||
|
||||
if len(video) > 0:
|
||||
#Process video library
|
||||
connection = utils.KodiSQL("video")
|
||||
cursor = connection.cursor()
|
||||
|
||||
for item in video:
|
||||
type = ReadKodiDB().getTypeByEmbyId(item, connection, cursor)
|
||||
self.logMsg("Type: %s" % type)
|
||||
self.logMsg("Message: Doing LibraryChanged: Items Removed: Calling deleteItemFromKodiLibrary: %s" % item, 0)
|
||||
if "episode" in type:
|
||||
# Get the TV Show Id for reference later
|
||||
showId = ReadKodiDB().getShowIdByEmbyId(item, connection, cursor)
|
||||
self.logMsg("ShowId: %s" % showId, 0)
|
||||
WriteKodiVideoDB().deleteItemFromKodiLibrary(item, connection, cursor)
|
||||
# Verification
|
||||
if "episode" in type:
|
||||
showTotalCount = ReadKodiDB().getShowTotalCount(showId, connection, cursor)
|
||||
self.logMsg("ShowTotalCount: %s" % showTotalCount, 0)
|
||||
# If there are no episodes left
|
||||
if showTotalCount == 0 or showTotalCount == None:
|
||||
# Delete show
|
||||
embyId = ReadKodiDB().getEmbyIdByKodiId(showId, "tvshow", connection, cursor)
|
||||
self.logMsg("Message: Doing LibraryChanged: Deleting show: %s" % embyId, 0)
|
||||
WriteKodiVideoDB().deleteItemFromKodiLibrary(embyId, connection, cursor)
|
||||
|
||||
connection.commit()
|
||||
cursor.close()
|
||||
|
||||
if len(music) > 0:
|
||||
#Process music library
|
||||
addon = xbmcaddon.Addon(id='plugin.video.emby')
|
||||
if addon.getSetting("enableMusicSync") is "true":
|
||||
connection = utils.KodiSQL("music")
|
||||
cursor = connection.cursor()
|
||||
|
||||
for item in music:
|
||||
self.logMsg("Message : Doing LibraryChanged : Items Removed : Calling deleteItemFromKodiLibrary (musiclibrary): " + item, 0)
|
||||
WriteKodiMusicDB().deleteItemFromKodiLibrary(item, connection, cursor)
|
||||
|
||||
connection.commit()
|
||||
cursor.close()
|
||||
|
||||
if deleteEmbyItem:
|
||||
for item in itemList:
|
||||
url = "{server}/mediabrowser/Items/%s" % item
|
||||
self.logMsg('Deleting via URL: %s' % url)
|
||||
doUtils.downloadUrl(url, type="DELETE")
|
||||
xbmc.executebuiltin("Container.Refresh")
|
||||
|
||||
def remove_items(self, itemsRemoved):
|
||||
|
||||
self.removeItems.extend(itemsRemoved)
|
||||
|
||||
def update_items(self, itemsToUpdate):
|
||||
# doing adds and updates
|
||||
if(len(itemsToUpdate) > 0):
|
||||
self.logMsg("Message : Doing LibraryChanged : Processing Added and Updated : " + str(itemsToUpdate), 0)
|
||||
self.updateItems.extend(itemsToUpdate)
|
||||
self.doIncrementalSync = True
|
||||
|
||||
def user_data_update(self, userDataList):
|
||||
# do full playcount update for now
|
||||
for userData in userDataList:
|
||||
itemId = userData.get("ItemId")
|
||||
if(itemId != None):
|
||||
self.updateItems.append(itemId)
|
||||
if(len(self.updateItems) > 0):
|
||||
self.logMsg("Message : Doing UserDataChanged : Processing Updated : " + str(self.updateItems), 0)
|
||||
self.doIncrementalSync = True
|
||||
|
||||
def ShouldStop(self):
|
||||
|
||||
if(xbmc.abortRequested):
|
||||
|
@ -642,6 +762,46 @@ class LibrarySync():
|
|||
|
||||
return False
|
||||
|
||||
|
||||
|
||||
|
||||
def run(self):
|
||||
|
||||
self.logMsg("--- Starting Library Sync Thread ---", 0)
|
||||
WINDOW = xbmcgui.Window(10000)
|
||||
startupComplete = False
|
||||
|
||||
while not self.KodiMonitor.abortRequested():
|
||||
|
||||
# Library sync
|
||||
if not startupComplete:
|
||||
# Run full sync
|
||||
self.logMsg("Doing_Db_Sync: syncDatabase (Started)", 1)
|
||||
libSync = self.FullLibrarySync()
|
||||
self.logMsg("Doing_Db_Sync: syncDatabase (Finished) %s" % libSync, 1)
|
||||
|
||||
if libSync:
|
||||
startupComplete = True
|
||||
|
||||
if WINDOW.getProperty("OnWakeSync") == "true":
|
||||
WINDOW.clearProperty("OnWakeSync")
|
||||
if WINDOW.getProperty("SyncDatabaseRunning") != "true":
|
||||
utils.logMsg("Doing_Db_Sync Post Resume: syncDatabase (Started)",0)
|
||||
libSync = self.FullLibrarySync()
|
||||
utils.logMsg("Doing_Db_Sync Post Resume: syncDatabase (Finished) " + str(libSync),0)
|
||||
|
||||
if self.doIncrementalSync:
|
||||
# Add or update item to Kodi library
|
||||
listItems = self.updateItems
|
||||
self.updateItems = []
|
||||
self.doIncrementalSync = False
|
||||
self.IncrementalSync(listItems)
|
||||
|
||||
if len(self.removeItems) > 0:
|
||||
# Remove item from Kodi library
|
||||
listItems = self.removeItems
|
||||
self.removeItems = []
|
||||
self.removefromDB(listItems)
|
||||
|
||||
if self.KodiMonitor.waitForAbort(1):
|
||||
# Abort was requested while waiting. We should exit
|
||||
break
|
||||
|
||||
self.logMsg("--- Library Sync Thread stopped ---", 0)
|
||||
|
|
|
@ -379,8 +379,10 @@ class PlaybackUtils():
|
|||
WINDOW.setProperty(playurl + "positionurl", positionurl)
|
||||
WINDOW.setProperty(playurl + "deleteurl", "")
|
||||
|
||||
if item.get("Type") == "Episode" and addon.getSetting("offerDelete")=="true":
|
||||
if item.get("Type") == "Episode" and addon.getSetting("offerDeleteTV")=="true":
|
||||
WINDOW.setProperty(playurl + "deleteurl", deleteurl)
|
||||
if item.get("Type") == "Movie" and addon.getSetting("offerDeleteMovies")=="true":
|
||||
WINDOW.setProperty(playurl + "deleteurl", deleteurl)
|
||||
|
||||
WINDOW.setProperty(playurl + "runtimeticks", str(item.get("RunTimeTicks")))
|
||||
WINDOW.setProperty(playurl+"type", item.get("Type"))
|
||||
|
|
|
@ -103,17 +103,18 @@ class Player( xbmc.Player ):
|
|||
|
||||
self.stopPlayback(data)
|
||||
|
||||
if percentComplete > .80 and data.get("Type") == "Episode" and addonSettings.getSetting("offerDelete")=="true":
|
||||
offerDelete=False
|
||||
if data.get("Type") == "Episode" and addonSettings.getSetting("offerDeleteTV")=="true":
|
||||
offerDelete = True
|
||||
elif data.get("Type") == "Movie" and addonSettings.getSetting("offerDeleteMovies")=="true":
|
||||
offerDelete = True
|
||||
|
||||
if percentComplete > .80 and offerDelete == True:
|
||||
return_value = xbmcgui.Dialog().yesno("Offer Delete", "Delete\n" + data.get("currentfile").split("/")[-1] + "\non Emby Server? ")
|
||||
if return_value:
|
||||
url='{server}/mediabrowser/Items/' + item_id
|
||||
xbmc.log('Deleting via URL: ' + url)
|
||||
self.doUtils.downloadUrl(url, type="DELETE")
|
||||
xbmc.sleep (15000)
|
||||
xbmc.executebuiltin( "Container.Refresh" )
|
||||
#if(refresh_id != None):
|
||||
#report updates playcount and resume status to Kodi and MB3
|
||||
#librarySync.updatePlayCount(item_id)
|
||||
# Delete Kodi entry before Emby
|
||||
listItem = [item_id]
|
||||
LibrarySync().removefromDB(listItem, True)
|
||||
|
||||
# Stop transcoding
|
||||
if self.WINDOW.getProperty("transcoding%s" % item_id) == "true":
|
||||
|
|
|
@ -156,7 +156,7 @@ class WebSocketThread(threading.Thread):
|
|||
userDataList = data.get("UserDataList")
|
||||
self.logMsg("Message : Doing UserDataChanged : UserDataList : " + str(userDataList), 0)
|
||||
if(userDataList != None):
|
||||
self.user_data_update(userDataList)
|
||||
LibrarySync().user_data_update(userDataList)
|
||||
|
||||
elif(messageType != None and messageType == "LibraryChanged"):
|
||||
foldersAddedTo = data.get("FoldersAddedTo")
|
||||
|
@ -171,8 +171,8 @@ class WebSocketThread(threading.Thread):
|
|||
self.logMsg("Message : WebSocket LibraryChanged : Items Updated : " + str(itemsUpdated), 0)
|
||||
self.logMsg("Message : WebSocket LibraryChanged : Items Removed : " + str(itemsRemoved), 0)
|
||||
|
||||
self.remove_items(itemsRemoved)
|
||||
self.update_items(itemsToUpdate)
|
||||
LibrarySync().remove_items(itemsRemoved)
|
||||
LibrarySync().update_items(itemsToUpdate)
|
||||
|
||||
elif messageType == "GeneralCommand":
|
||||
|
||||
|
@ -248,56 +248,6 @@ class WebSocketThread(threading.Thread):
|
|||
result = xbmc.executeJSONRPC(text)
|
||||
else:
|
||||
self.logMsg("Unknown command.", 1)
|
||||
|
||||
def remove_items(self, itemsRemoved):
|
||||
|
||||
#Process video library
|
||||
connection = utils.KodiSQL("video")
|
||||
cursor = connection.cursor()
|
||||
for item in itemsRemoved:
|
||||
type=ReadKodiDB().getTypeByEmbyId(item, connection, cursor)
|
||||
self.logMsg("Type: " + str(type))
|
||||
self.logMsg("Message : Doing LibraryChanged : Items Removed : Calling deleteItemFromKodiLibrary: " + item, 0)
|
||||
if type == "episode":
|
||||
showId=ReadKodiDB().getShowIdByEmbyId(item, connection, cursor) # Get the TV Show ID
|
||||
self.logMsg("ShowID: " + str(showId),0)
|
||||
WriteKodiVideoDB().deleteItemFromKodiLibrary(item, connection, cursor)
|
||||
if type == "episode":
|
||||
showTotalCount = ReadKodiDB().getShowTotalCount(showId, connection, cursor) # Check if there are no episodes left
|
||||
self.logMsg("ShowTotalCount: " + str(showTotalCount),0)
|
||||
if showTotalCount == 0 or showTotalCount == None: # Delete show if no episodes are left
|
||||
embyId=ReadKodiDB().getEmbyIdByKodiId(showId, "tvshow", connection, cursor)
|
||||
self.logMsg("Message : Doing LibraryChanged : Deleting show:" + embyId, 0)
|
||||
WriteKodiVideoDB().deleteItemFromKodiLibrary(embyId, connection, cursor)
|
||||
connection.commit()
|
||||
cursor.close()
|
||||
|
||||
#Process music library
|
||||
addon = xbmcaddon.Addon(id='plugin.video.emby')
|
||||
if addon.getSetting("enableMusicSync") == "true":
|
||||
connection = utils.KodiSQL("music")
|
||||
cursor = connection.cursor()
|
||||
for item in itemsRemoved:
|
||||
self.logMsg("Message : Doing LibraryChanged : Items Removed : Calling deleteItemFromKodiLibrary (musiclibrary): " + item, 0)
|
||||
WriteKodiMusicDB().deleteItemFromKodiLibrary(item, connection, cursor)
|
||||
connection.commit()
|
||||
cursor.close()
|
||||
|
||||
def update_items(self, itemsToUpdate):
|
||||
# doing adds and updates
|
||||
if(len(itemsToUpdate) > 0):
|
||||
self.logMsg("Message : Doing LibraryChanged : Processing Added and Updated : " + str(itemsToUpdate), 0)
|
||||
LibrarySync().IncrementalSync(itemsToUpdate)
|
||||
|
||||
def user_data_update(self, userDataList):
|
||||
itemsToUpdate = list()
|
||||
for userData in userDataList:
|
||||
itemId = userData.get("ItemId")
|
||||
if(itemId != None):
|
||||
itemsToUpdate.append(itemId)
|
||||
if(len(itemsToUpdate) > 0):
|
||||
self.logMsg("Message : Doing UserDataChanged : Processing Updated : " + str(itemsToUpdate), 0)
|
||||
LibrarySync().IncrementalSync(itemsToUpdate)
|
||||
|
||||
def on_error(self, ws, error):
|
||||
if "10061" in str(error):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue