2015-03-13 21:24:59 +00:00
#################################################################################################
# LibrarySync
#################################################################################################
import xbmc
import xbmcgui
import xbmcaddon
import xbmcvfs
import json
2015-03-14 00:46:54 +00:00
import sqlite3
2015-03-16 17:51:49 +00:00
import inspect
2015-03-13 21:24:59 +00:00
import threading
import urllib
from datetime import datetime , timedelta , time
2015-05-01 11:30:21 +00:00
from itertools import chain
2015-03-13 21:24:59 +00:00
import urllib2
import os
2015-03-13 22:39:35 +00:00
2015-06-16 05:53:01 +00:00
import KodiMonitor
2015-03-13 21:24:59 +00:00
from API import API
import Utils as utils
2015-06-16 05:53:01 +00:00
from ClientInformation import ClientInformation
2015-03-13 21:24:59 +00:00
from DownloadUtils import DownloadUtils
2015-03-17 17:51:45 +00:00
from ReadEmbyDB import ReadEmbyDB
2015-03-17 18:41:26 +00:00
from ReadKodiDB import ReadKodiDB
2015-05-07 09:45:24 +00:00
from WriteKodiVideoDB import WriteKodiVideoDB
2015-05-07 22:04:40 +00:00
from WriteKodiMusicDB import WriteKodiMusicDB
2015-05-06 21:24:13 +00:00
from VideoNodes import VideoNodes
2015-03-13 21:24:59 +00:00
2015-03-25 17:37:21 +00:00
addondir = xbmc . translatePath ( xbmcaddon . Addon ( id = ' plugin.video.emby ' ) . getAddonInfo ( ' profile ' ) )
2015-03-13 21:24:59 +00:00
dataPath = os . path . join ( addondir , " library " )
2015-03-14 22:33:16 +00:00
movieLibrary = os . path . join ( dataPath , ' movies ' )
tvLibrary = os . path . join ( dataPath , ' tvshows ' )
2015-03-13 21:24:59 +00:00
2015-05-02 09:56:31 +00:00
WINDOW = xbmcgui . Window ( 10000 )
2015-06-16 05:53:01 +00:00
class LibrarySync ( threading . Thread ) :
2015-06-28 12:08:06 +00:00
_shared_state = { }
2015-06-16 05:53:01 +00:00
KodiMonitor = KodiMonitor . Kodi_Monitor ( )
clientInfo = ClientInformation ( )
addonName = clientInfo . getAddonName ( )
2015-06-28 12:08:06 +00:00
updateItems = [ ]
2015-08-14 09:03:12 +00:00
userdataItems = [ ]
2015-06-28 12:08:06 +00:00
removeItems = [ ]
2015-06-16 05:53:01 +00:00
def __init__ ( self , * args ) :
2015-06-28 12:08:06 +00:00
self . __dict__ = self . _shared_state
2015-06-16 05:53:01 +00:00
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 ) )
2015-03-13 21:24:59 +00:00
2015-05-07 09:36:34 +00:00
def FullLibrarySync ( self , manualRun = False ) :
2015-05-02 09:56:31 +00:00
2015-08-02 09:16:55 +00:00
startupDone = WINDOW . getProperty ( " startup " ) == " done "
2015-08-14 09:03:12 +00:00
syncInstallRunDone = utils . settings ( " SyncInstallRunDone " ) == " true "
performMusicSync = utils . settings ( " enableMusicSync " ) == " true "
dbSyncIndication = utils . settings ( " dbSyncIndication " ) == " true "
2015-08-02 08:59:41 +00:00
2015-08-02 06:24:15 +00:00
### BUILD VIDEO NODES LISTING ###
VideoNodes ( ) . buildVideoNodesListing ( )
### CREATE SOURCES ###
2015-08-14 09:03:12 +00:00
if utils . settings ( " Sources " ) != " true " :
2015-08-02 06:24:15 +00:00
# Only create sources once
self . logMsg ( " Sources.xml created. " , 0 )
utils . createSources ( )
2015-08-14 09:03:12 +00:00
utils . settings ( " Sources " , " true " )
2015-05-02 09:56:31 +00:00
2015-08-01 00:26:22 +00:00
# just do a incremental sync if that is what is required
2015-08-14 09:03:12 +00:00
if ( utils . settings ( " useIncSync " ) == " true " and utils . settings ( " SyncInstallRunDone " ) == " true " ) and manualRun == False :
2015-08-01 00:26:22 +00:00
utils . logMsg ( " Sync Database " , " Using incremental sync instead of full sync useIncSync=True) " , 0 )
du = DownloadUtils ( )
2015-08-14 09:03:12 +00:00
lastSync = utils . settings ( " LastIncrenetalSync " )
2015-08-01 02:21:01 +00:00
if ( lastSync == None or len ( lastSync ) == 0 ) :
lastSync = " 2010-01-01T00:00:00Z "
utils . logMsg ( " Sync Database " , " Incremental Sync Setting Last Run Time Loaded : " + lastSync , 0 )
2015-08-03 08:36:35 +00:00
lastSync = urllib2 . quote ( lastSync )
2015-08-05 09:44:07 +00:00
url = " {server} /Emby.Kodi.SyncQueue/ {UserId} /GetItems?LastUpdateDT= " + lastSync + " &format=json "
2015-08-01 02:21:01 +00:00
utils . logMsg ( " Sync Database " , " Incremental Sync Get Items URL : " + url , 0 )
2015-08-01 00:26:22 +00:00
2015-09-05 06:58:39 +00:00
try :
results = du . downloadUrl ( url )
2015-09-05 08:35:46 +00:00
changedItems = results [ " ItemsUpdated " ] + results [ " ItemsAdded " ]
removedItems = results [ " ItemsRemoved " ]
userChanges = results [ " UserDataChanged " ]
2015-09-05 06:58:39 +00:00
except :
utils . logMsg ( " Sync Database " , " Incremental Sync Get Changes Failed " , 0 )
pass
else :
2015-09-06 05:44:23 +00:00
maxItems = int ( utils . settings ( " incSyncMaxItems " ) )
2015-09-05 06:58:39 +00:00
utils . logMsg ( " Sync Database " , " Incremental Sync Changes : " + str ( results ) , 0 )
2015-09-06 05:44:23 +00:00
if ( len ( changedItems ) < maxItems and len ( removedItems ) < maxItems and len ( userChanges ) < maxItems ) :
2015-09-05 06:58:39 +00:00
WINDOW . setProperty ( " startup " , " done " )
LibrarySync ( ) . remove_items ( removedItems )
LibrarySync ( ) . update_items ( changedItems )
LibrarySync ( ) . user_data_update ( userChanges )
self . SaveLastSync ( )
return True
else :
2015-09-06 05:44:23 +00:00
utils . logMsg ( " Sync Database " , " Too Many For Incremental Sync ( " + str ( maxItems ) + " ), changedItems " + str ( len ( changedItems ) ) + " removedItems: " + str ( len ( removedItems ) ) + " userChanges: " + str ( len ( userChanges ) ) , 0 )
2015-08-14 09:03:12 +00:00
2015-08-01 00:26:22 +00:00
#set some variable to check if this is the first run
WINDOW . setProperty ( " SyncDatabaseRunning " , " true " )
2015-05-02 17:49:39 +00:00
#show the progress dialog
pDialog = None
2015-05-07 09:36:34 +00:00
if ( syncInstallRunDone == False or dbSyncIndication or manualRun ) :
2015-05-02 17:49:39 +00:00
pDialog = xbmcgui . DialogProgressBG ( )
pDialog . create ( ' Emby for Kodi ' , ' Performing full sync ' )
2015-04-03 08:39:16 +00:00
if ( WINDOW . getProperty ( " SyncDatabaseShouldStop " ) == " true " ) :
utils . logMsg ( " Sync Database " , " Can not start SyncDatabaseShouldStop=True " , 0 )
return True
try :
completed = True
2015-08-02 06:24:15 +00:00
2015-05-07 22:04:40 +00:00
### PROCESS VIDEO LIBRARY ###
#create the sql connection to video db
connection = utils . KodiSQL ( " video " )
2015-04-04 17:20:48 +00:00
cursor = connection . cursor ( )
2015-05-01 11:30:21 +00:00
2015-05-02 01:47:05 +00:00
#Add the special emby table
2015-09-27 21:06:22 +00:00
cursor . execute ( " CREATE TABLE IF NOT EXISTS emby(emby_id TEXT, kodi_id INTEGER, media_type TEXT, checksum TEXT, parent_id INTEGER, kodi_file_id INTEGER) " )
2015-08-14 09:03:12 +00:00
try :
cursor . execute ( " ALTER TABLE emby ADD COLUMN kodi_file_id INTEGER " )
except : pass
2015-05-12 19:27:27 +00:00
connection . commit ( )
2015-05-01 11:30:21 +00:00
2015-04-03 08:39:16 +00:00
# sync movies
2015-05-02 09:56:31 +00:00
self . MoviesFullSync ( connection , cursor , pDialog )
2015-05-02 17:49:39 +00:00
if ( self . ShouldStop ( ) ) :
2015-05-02 20:02:06 +00:00
return False
2015-05-02 17:49:39 +00:00
2015-05-01 11:30:21 +00:00
#sync Tvshows and episodes
2015-05-02 09:56:31 +00:00
self . TvShowsFullSync ( connection , cursor , pDialog )
2015-05-02 20:02:06 +00:00
if ( self . ShouldStop ( ) ) :
return False
# sync musicvideos
self . MusicVideosFullSync ( connection , cursor , pDialog )
2015-05-07 22:04:40 +00:00
#close sql connection
cursor . close ( )
### PROCESS MUSIC LIBRARY ###
if performMusicSync :
#create the sql connection to music db
connection = utils . KodiSQL ( " music " )
cursor = connection . cursor ( )
#Add the special emby table
2015-08-14 09:03:12 +00:00
cursor . execute ( " CREATE TABLE IF NOT EXISTS emby(emby_id TEXT, kodi_id INTEGER, media_type TEXT, checksum TEXT, parent_id INTEGER, kodi_file_id INTEGER) " )
try :
cursor . execute ( " ALTER TABLE emby ADD COLUMN kodi_file_id INTEGER " )
except : pass
2015-05-12 19:27:27 +00:00
connection . commit ( )
2015-05-07 22:04:40 +00:00
self . MusicFullSync ( connection , cursor , pDialog )
cursor . close ( )
2015-04-03 08:39:16 +00:00
# set the install done setting
if ( syncInstallRunDone == False and completed ) :
2015-09-05 06:58:39 +00:00
utils . settings ( " SyncInstallRunDone " , " true " )
2015-09-06 17:32:07 +00:00
utils . settings ( " dbCreatedWithVersion " , self . clientInfo . getVersion ( ) )
2015-04-03 08:39:16 +00:00
2015-05-02 20:46:12 +00:00
# Commit all DB changes at once and Force refresh the library
2015-05-02 09:56:31 +00:00
xbmc . executebuiltin ( " UpdateLibrary(video) " )
2015-08-14 09:03:12 +00:00
#xbmc.executebuiltin("UpdateLibrary(music)")
2015-05-02 09:56:31 +00:00
2015-04-03 08:39:16 +00:00
# set prop to show we have run for the first time
WINDOW . setProperty ( " startup " , " done " )
2015-06-24 07:03:49 +00:00
# tell any widgets to refresh because the content has changed
WINDOW . setProperty ( " widgetreload " , datetime . now ( ) . strftime ( ' % Y- % m- %d % H: % M: % S ' ) )
2015-09-05 06:58:39 +00:00
self . SaveLastSync ( )
2015-04-03 08:39:16 +00:00
finally :
WINDOW . setProperty ( " SyncDatabaseRunning " , " false " )
2015-04-04 23:59:15 +00:00
utils . logMsg ( " Sync DB " , " syncDatabase Exiting " , 0 )
2015-05-02 09:56:31 +00:00
if ( pDialog != None ) :
pDialog . close ( )
2015-08-02 06:24:15 +00:00
return True
2015-08-01 15:49:28 +00:00
def SaveLastSync ( self ) :
# save last sync time
2015-09-06 05:44:23 +00:00
du = DownloadUtils ( )
url = " {server} /Emby.Kodi.SyncQueue/GetServerDateTime?format=json "
try :
results = du . downloadUrl ( url )
lastSync = results [ " ServerDateTime " ]
self . logMsg ( " Sync Database, Incremental Sync Using Server Time: %s " % lastSync , 0 )
lastSync = datetime . strptime ( lastSync , " % Y- % m- %d T % H: % M: % SZ " )
lastSync = ( lastSync - timedelta ( minutes = 5 ) ) . strftime ( ' % Y- % m- %d T % H: % M: % SZ ' )
self . logMsg ( " Sync Database, Incremental Sync Using Server Time -5 min: %s " % lastSync , 0 )
except :
lastSync = ( datetime . utcnow ( ) - timedelta ( minutes = 5 ) ) . strftime ( ' % Y- % m- %d T % H: % M: % SZ ' )
self . logMsg ( " Sync Database, Incremental Sync Using Client Time -5 min: %s " % lastSync , 0 )
self . logMsg ( " Sync Database, Incremental Sync Setting Last Run Time Saved: %s " % lastSync , 0 )
2015-08-14 09:03:12 +00:00
utils . settings ( " LastIncrenetalSync " , lastSync )
2015-08-01 15:49:28 +00:00
2015-09-01 13:01:52 +00:00
def MoviesFullSync ( self , connection , cursor , pDialog ) :
2015-05-02 09:56:31 +00:00
2015-05-01 11:30:21 +00:00
views = ReadEmbyDB ( ) . getCollections ( " movies " )
allKodiMovieIds = list ( )
allEmbyMovieIds = list ( )
for view in views :
2015-03-18 15:47:55 +00:00
2015-05-02 09:56:31 +00:00
allEmbyMovies = ReadEmbyDB ( ) . getMovies ( view . get ( ' id ' ) )
2015-05-01 11:30:21 +00:00
allKodiMovies = ReadKodiDB ( ) . getKodiMovies ( connection , cursor )
2015-05-02 01:47:05 +00:00
2015-09-08 18:36:49 +00:00
for kodimovie in allKodiMovies :
allKodiMovieIds . append ( kodimovie [ 1 ] )
title = view . get ( ' title ' )
content = view . get ( ' content ' )
if content == " mixed " :
title = " %s - Movies " % title
2015-05-02 01:47:05 +00:00
for kodimovie in allKodiMovies :
allKodiMovieIds . append ( kodimovie [ 1 ] )
2015-05-02 09:56:31 +00:00
total = len ( allEmbyMovies ) + 1
count = 1
2015-05-01 11:30:21 +00:00
#### PROCESS ADDS AND UPDATES ###
2015-05-02 09:56:31 +00:00
for item in allEmbyMovies :
2015-05-02 17:49:39 +00:00
if ( self . ShouldStop ( ) ) :
return False
2015-05-01 11:30:21 +00:00
if not item . get ( ' IsFolder ' ) :
allEmbyMovieIds . append ( item [ " Id " ] )
2015-03-18 15:47:55 +00:00
2015-05-02 09:56:31 +00:00
if ( pDialog != None ) :
progressTitle = " Processing " + view . get ( ' title ' ) + " ( " + str ( count ) + " of " + str ( total ) + " ) "
2015-05-08 10:05:15 +00:00
percentage = int ( ( ( float ( count ) / float ( total ) ) * 100 ) )
pDialog . update ( percentage , " Emby for Kodi - Running Sync " , progressTitle )
2015-05-02 10:51:46 +00:00
count + = 1
2015-05-02 09:56:31 +00:00
2015-05-01 11:30:21 +00:00
kodiMovie = None
for kodimovie in allKodiMovies :
if kodimovie [ 1 ] == item [ " Id " ] :
kodiMovie = kodimovie
if kodiMovie == None :
2015-09-08 18:36:49 +00:00
WriteKodiVideoDB ( ) . addOrUpdateMovieToKodiLibrary ( item [ " Id " ] , connection , cursor , title )
2015-05-01 11:30:21 +00:00
else :
2015-05-02 09:56:31 +00:00
if kodiMovie [ 2 ] != API ( ) . getChecksum ( item ) :
2015-09-08 18:36:49 +00:00
WriteKodiVideoDB ( ) . addOrUpdateMovieToKodiLibrary ( item [ " Id " ] , connection , cursor , title )
2015-05-03 12:44:23 +00:00
#### PROCESS BOX SETS #####
2015-09-05 06:58:39 +00:00
utils . logMsg ( " Sync Movies " , " BoxSet Sync Started " , 1 )
2015-09-01 13:01:52 +00:00
boxsets = ReadEmbyDB ( ) . getBoxSets ( )
2015-05-03 12:44:23 +00:00
2015-09-01 13:01:52 +00:00
total = len ( boxsets ) + 1
count = 1
for boxset in boxsets :
2015-09-05 06:58:39 +00:00
if ( pDialog != None ) :
progressTitle = " Processing BoxSets " + " ( " + str ( count ) + " of " + str ( total - 1 ) + " ) "
percentage = int ( ( ( float ( count ) / float ( total ) ) * 100 ) )
pDialog . update ( percentage , " Emby for Kodi - Running Sync " , progressTitle )
count + = 1
2015-09-01 13:01:52 +00:00
if ( self . ShouldStop ( ) ) :
return False
boxsetMovies = ReadEmbyDB ( ) . getMoviesInBoxSet ( boxset [ " Id " ] )
WriteKodiVideoDB ( ) . addBoxsetToKodiLibrary ( boxset , connection , cursor )
WriteKodiVideoDB ( ) . removeMoviesFromBoxset ( boxset , connection , cursor )
for boxsetMovie in boxsetMovies :
2015-05-03 12:44:23 +00:00
if ( self . ShouldStop ( ) ) :
2015-09-01 13:01:52 +00:00
return False
WriteKodiVideoDB ( ) . updateBoxsetToKodiLibrary ( boxsetMovie , boxset , connection , cursor )
2015-05-03 12:44:23 +00:00
2015-09-01 13:01:52 +00:00
utils . logMsg ( " Sync Movies " , " BoxSet Sync Finished " , 1 )
2015-05-01 11:30:21 +00:00
2015-05-02 10:51:46 +00:00
#### PROCESS DELETES #####
allEmbyMovieIds = set ( allEmbyMovieIds )
for kodiId in allKodiMovieIds :
if not kodiId in allEmbyMovieIds :
WINDOW . setProperty ( kodiId , " deleted " )
2015-05-07 09:45:24 +00:00
WriteKodiVideoDB ( ) . deleteItemFromKodiLibrary ( kodiId , connection , cursor )
2015-05-02 20:46:12 +00:00
### commit all changes to database ###
connection . commit ( )
2015-05-01 11:30:21 +00:00
2015-05-02 20:02:06 +00:00
def MusicVideosFullSync ( self , connection , cursor , pDialog ) :
allKodiMusicvideoIds = list ( )
allEmbyMusicvideoIds = list ( )
allEmbyMusicvideos = ReadEmbyDB ( ) . getMusicVideos ( )
allKodiMusicvideos = ReadKodiDB ( ) . getKodiMusicVideos ( connection , cursor )
for kodivideo in allKodiMusicvideos :
allKodiMusicvideoIds . append ( kodivideo [ 1 ] )
total = len ( allEmbyMusicvideos ) + 1
count = 1
#### PROCESS ADDS AND UPDATES ###
for item in allEmbyMusicvideos :
if ( self . ShouldStop ( ) ) :
return False
if not item . get ( ' IsFolder ' ) :
allEmbyMusicvideoIds . append ( item [ " Id " ] )
if ( pDialog != None ) :
progressTitle = " Processing MusicVideos ( " + str ( count ) + " of " + str ( total ) + " ) "
2015-05-08 10:05:15 +00:00
percentage = int ( ( ( float ( count ) / float ( total ) ) * 100 ) )
pDialog . update ( percentage , " Emby for Kodi - Running Sync " , progressTitle )
2015-05-02 20:02:06 +00:00
count + = 1
kodiVideo = None
for kodivideo in allKodiMusicvideos :
if kodivideo [ 1 ] == item [ " Id " ] :
kodiVideo = kodivideo
if kodiVideo == None :
2015-05-07 09:45:24 +00:00
WriteKodiVideoDB ( ) . addOrUpdateMusicVideoToKodiLibrary ( item [ " Id " ] , connection , cursor )
2015-05-02 20:02:06 +00:00
else :
if kodiVideo [ 2 ] != API ( ) . getChecksum ( item ) :
2015-05-07 09:45:24 +00:00
WriteKodiVideoDB ( ) . addOrUpdateMusicVideoToKodiLibrary ( item [ " Id " ] , connection , cursor )
2015-05-02 20:02:06 +00:00
#### PROCESS DELETES #####
allEmbyMusicvideoIds = set ( allEmbyMusicvideoIds )
for kodiId in allKodiMusicvideoIds :
if not kodiId in allEmbyMusicvideoIds :
WINDOW . setProperty ( kodiId , " deleted " )
2015-05-07 09:45:24 +00:00
WriteKodiVideoDB ( ) . deleteItemFromKodiLibrary ( kodiId , connection , cursor )
2015-05-02 20:46:12 +00:00
### commit all changes to database ###
connection . commit ( )
2015-05-02 20:02:06 +00:00
2015-05-02 09:56:31 +00:00
def TvShowsFullSync ( self , connection , cursor , pDialog ) :
2015-05-01 11:30:21 +00:00
views = ReadEmbyDB ( ) . getCollections ( " tvshows " )
2015-03-18 17:00:38 +00:00
2015-05-01 11:30:21 +00:00
allKodiTvShowIds = list ( )
allEmbyTvShowIds = list ( )
2015-05-02 01:47:05 +00:00
2015-05-01 11:30:21 +00:00
for view in views :
2015-03-20 08:15:06 +00:00
2015-05-01 11:30:21 +00:00
allEmbyTvShows = ReadEmbyDB ( ) . getTvShows ( view . get ( ' id ' ) )
allKodiTvShows = ReadKodiDB ( ) . getKodiTvShows ( connection , cursor )
2015-05-02 01:47:05 +00:00
2015-09-08 18:36:49 +00:00
title = view . get ( ' title ' )
content = view . get ( ' content ' )
if content == " mixed " :
title = " %s - TV Shows " % title
2015-05-02 09:56:31 +00:00
total = len ( allEmbyTvShows ) + 1
count = 1
2015-05-02 01:47:05 +00:00
for kodishow in allKodiTvShows :
allKodiTvShowIds . append ( kodishow [ 1 ] )
2015-05-01 11:30:21 +00:00
#### TVSHOW: PROCESS ADDS AND UPDATES ###
for item in allEmbyTvShows :
2015-05-02 17:49:39 +00:00
if ( self . ShouldStop ( ) ) :
return False
2015-05-02 20:34:55 +00:00
if ( pDialog != None ) :
progressTitle = " Processing " + view . get ( ' title ' ) + " ( " + str ( count ) + " of " + str ( total ) + " ) "
2015-05-08 10:05:15 +00:00
percentage = int ( ( ( float ( count ) / float ( total ) ) * 100 ) )
pDialog . update ( percentage , " Emby for Kodi - Running Sync " , progressTitle )
2015-05-02 20:34:55 +00:00
count + = 1
2015-08-26 03:21:31 +00:00
if utils . settings ( ' syncEmptyShows ' ) == " true " or ( item . get ( ' IsFolder ' ) and item . get ( ' RecursiveItemCount ' ) != 0 ) :
2015-05-01 11:30:21 +00:00
allEmbyTvShowIds . append ( item [ " Id " ] )
2015-03-18 21:38:02 +00:00
2015-05-01 11:30:21 +00:00
#build a list with all Id's and get the existing entry (if exists) in Kodi DB
kodiShow = None
for kodishow in allKodiTvShows :
if kodishow [ 1 ] == item [ " Id " ] :
kodiShow = kodishow
if kodiShow == None :
# Tv show doesn't exist in Kodi yet so proceed and add it
2015-09-08 18:36:49 +00:00
WriteKodiVideoDB ( ) . addOrUpdateTvShowToKodiLibrary ( item [ " Id " ] , connection , cursor , title )
2015-05-01 11:30:21 +00:00
else :
# If there are changes to the item, perform a full sync of the item
2015-05-02 09:56:31 +00:00
if kodiShow [ 2 ] != API ( ) . getChecksum ( item ) :
2015-09-08 18:36:49 +00:00
WriteKodiVideoDB ( ) . addOrUpdateTvShowToKodiLibrary ( item [ " Id " ] , connection , cursor , title )
2015-04-04 21:48:02 +00:00
2015-05-01 11:30:21 +00:00
#### PROCESS EPISODES ######
2015-05-02 12:57:43 +00:00
self . EpisodesFullSync ( connection , cursor , item [ " Id " ] )
2015-05-01 11:30:21 +00:00
2015-05-02 10:51:46 +00:00
#### TVSHOW: PROCESS DELETES #####
allEmbyTvShowIds = set ( allEmbyTvShowIds )
for kodiId in allKodiTvShowIds :
if not kodiId in allEmbyTvShowIds :
WINDOW . setProperty ( kodiId , " deleted " )
2015-05-07 09:45:24 +00:00
WriteKodiVideoDB ( ) . deleteItemFromKodiLibrary ( kodiId , connection , cursor )
2015-05-02 20:46:12 +00:00
### commit all changes to database ###
connection . commit ( )
2015-05-02 09:56:31 +00:00
2015-05-02 12:57:43 +00:00
def EpisodesFullSync ( self , connection , cursor , showId ) :
2015-05-01 11:30:21 +00:00
WINDOW = xbmcgui . Window ( 10000 )
allKodiEpisodeIds = list ( )
allEmbyEpisodeIds = list ( )
2015-03-18 17:00:38 +00:00
2015-10-04 11:40:39 +00:00
# Get the kodi parent id
2015-05-02 12:57:43 +00:00
cursor . execute ( " SELECT kodi_id FROM emby WHERE emby_id=? " , ( showId , ) )
2015-10-04 11:40:39 +00:00
try :
kodiShowId = cursor . fetchone ( ) [ 0 ]
except :
self . logMsg ( " Unable to find show itemId: %s " % showId , 1 )
return
2015-05-02 12:57:43 +00:00
allEmbyEpisodes = ReadEmbyDB ( ) . getEpisodes ( showId )
2015-05-01 11:30:21 +00:00
allKodiEpisodes = ReadKodiDB ( ) . getKodiEpisodes ( connection , cursor , kodiShowId )
2015-05-02 01:47:05 +00:00
for kodiepisode in allKodiEpisodes :
allKodiEpisodeIds . append ( kodiepisode [ 1 ] )
2015-05-01 11:30:21 +00:00
#### EPISODES: PROCESS ADDS AND UPDATES ###
for item in allEmbyEpisodes :
2015-05-02 17:49:39 +00:00
if ( self . ShouldStop ( ) ) :
return False
2015-05-01 11:30:21 +00:00
allEmbyEpisodeIds . append ( item [ " Id " ] )
2015-05-02 01:47:05 +00:00
#get the existing entry (if exists) in Kodi DB
2015-05-01 11:30:21 +00:00
kodiEpisode = None
for kodiepisode in allKodiEpisodes :
if kodiepisode [ 1 ] == item [ " Id " ] :
kodiEpisode = kodiepisode
if kodiEpisode == None :
# Episode doesn't exist in Kodi yet so proceed and add it
2015-05-07 09:45:24 +00:00
WriteKodiVideoDB ( ) . addOrUpdateEpisodeToKodiLibrary ( item [ " Id " ] , kodiShowId , connection , cursor )
2015-05-01 11:30:21 +00:00
else :
# If there are changes to the item, perform a full sync of the item
2015-05-02 09:56:31 +00:00
if kodiEpisode [ 2 ] != API ( ) . getChecksum ( item ) :
2015-05-07 09:45:24 +00:00
WriteKodiVideoDB ( ) . addOrUpdateEpisodeToKodiLibrary ( item [ " Id " ] , kodiShowId , connection , cursor )
2015-05-01 11:30:21 +00:00
#### EPISODES: PROCESS DELETES #####
allEmbyEpisodeIds = set ( allEmbyEpisodeIds )
for kodiId in allKodiEpisodeIds :
2015-05-02 01:47:05 +00:00
if ( not kodiId in allEmbyEpisodeIds ) :
2015-05-01 11:30:21 +00:00
WINDOW . setProperty ( kodiId , " deleted " )
2015-05-07 09:45:24 +00:00
WriteKodiVideoDB ( ) . deleteItemFromKodiLibrary ( kodiId , connection , cursor )
2015-05-02 20:46:12 +00:00
2015-05-07 22:04:40 +00:00
def MusicFullSync ( self , connection , cursor , pDialog ) :
self . ProcessMusicArtists ( connection , cursor , pDialog )
2015-07-30 19:23:50 +00:00
connection . commit ( )
2015-05-07 22:04:40 +00:00
self . ProcessMusicAlbums ( connection , cursor , pDialog )
2015-07-30 19:23:50 +00:00
connection . commit ( )
2015-05-07 22:04:40 +00:00
self . ProcessMusicSongs ( connection , cursor , pDialog )
### commit all changes to database ###
connection . commit ( )
def ProcessMusicSongs ( self , connection , cursor , pDialog ) :
allKodiSongIds = list ( )
allEmbySongIds = list ( )
2015-08-04 06:07:39 +00:00
allEmbySongs = ReadEmbyDB ( ) . getMusicSongsTotal ( )
2015-05-07 22:04:40 +00:00
allKodiSongs = ReadKodiDB ( ) . getKodiMusicSongs ( connection , cursor )
for kodisong in allKodiSongs :
allKodiSongIds . append ( kodisong [ 1 ] )
total = len ( allEmbySongs ) + 1
count = 1
#### PROCESS SONGS ADDS AND UPDATES ###
for item in allEmbySongs :
if ( self . ShouldStop ( ) ) :
return False
allEmbySongIds . append ( item [ " Id " ] )
if ( pDialog != None ) :
progressTitle = " Processing Music Songs ( " + str ( count ) + " of " + str ( total ) + " ) "
2015-05-08 10:05:15 +00:00
percentage = int ( ( ( float ( count ) / float ( total ) ) * 100 ) )
pDialog . update ( percentage , " Emby for Kodi - Running Sync " , progressTitle )
2015-05-07 22:04:40 +00:00
count + = 1
kodiSong = None
for kodisong in allKodiSongs :
if kodisong [ 1 ] == item [ " Id " ] :
kodiSong = kodisong
if kodiSong == None :
2015-07-30 19:23:50 +00:00
WriteKodiMusicDB ( ) . addOrUpdateSongToKodiLibrary ( item , connection , cursor )
2015-05-07 22:04:40 +00:00
else :
if kodiSong [ 2 ] != API ( ) . getChecksum ( item ) :
2015-07-30 19:23:50 +00:00
WriteKodiMusicDB ( ) . addOrUpdateSongToKodiLibrary ( item , connection , cursor )
2015-05-07 22:04:40 +00:00
#### PROCESS DELETES #####
allEmbySongIds = set ( allEmbySongIds )
for kodiId in allKodiSongIds :
if not kodiId in allEmbySongIds :
WINDOW . setProperty ( kodiId , " deleted " )
WriteKodiMusicDB ( ) . deleteItemFromKodiLibrary ( kodiId , connection , cursor )
def ProcessMusicArtists ( self , connection , cursor , pDialog ) :
allKodiArtistIds = list ( )
allEmbyArtistIds = list ( )
2015-08-04 07:12:58 +00:00
allEmbyArtists = ReadEmbyDB ( ) . getMusicArtistsTotal ( )
2015-05-07 22:04:40 +00:00
allKodiArtists = ReadKodiDB ( ) . getKodiMusicArtists ( connection , cursor )
for kodiartist in allKodiArtists :
allKodiArtistIds . append ( kodiartist [ 1 ] )
total = len ( allEmbyArtists ) + 1
count = 1
2015-07-30 19:23:50 +00:00
#### PROCESS ARTIST ADDS AND UPDATES ###
2015-05-07 22:04:40 +00:00
for item in allEmbyArtists :
if ( self . ShouldStop ( ) ) :
return False
allEmbyArtistIds . append ( item [ " Id " ] )
if ( pDialog != None ) :
progressTitle = " Processing Music Artists ( " + str ( count ) + " of " + str ( total ) + " ) "
2015-05-08 10:05:15 +00:00
percentage = int ( ( ( float ( count ) / float ( total ) ) * 100 ) )
pDialog . update ( percentage , " Emby for Kodi - Running Sync " , progressTitle )
2015-05-07 22:04:40 +00:00
count + = 1
kodiArtist = None
for kodiartist in allKodiArtists :
if kodiartist [ 1 ] == item [ " Id " ] :
kodiArtist = kodiartist
if kodiArtist == None :
2015-07-30 19:23:50 +00:00
WriteKodiMusicDB ( ) . addOrUpdateArtistToKodiLibrary ( item , connection , cursor )
2015-05-07 22:04:40 +00:00
else :
if kodiArtist [ 2 ] != API ( ) . getChecksum ( item ) :
2015-07-30 19:23:50 +00:00
WriteKodiMusicDB ( ) . addOrUpdateArtistToKodiLibrary ( item , connection , cursor )
2015-05-07 22:04:40 +00:00
#### PROCESS DELETES #####
allEmbyArtistIds = set ( allEmbyArtistIds )
for kodiId in allKodiArtistIds :
if not kodiId in allEmbyArtistIds :
WINDOW . setProperty ( kodiId , " deleted " )
WriteKodiMusicDB ( ) . deleteItemFromKodiLibrary ( kodiId , connection , cursor )
def ProcessMusicAlbums ( self , connection , cursor , pDialog ) :
allKodiAlbumIds = list ( )
allEmbyAlbumIds = list ( )
2015-08-04 07:12:58 +00:00
allEmbyAlbums = ReadEmbyDB ( ) . getMusicAlbumsTotal ( )
2015-05-07 22:04:40 +00:00
allKodiAlbums = ReadKodiDB ( ) . getKodiMusicAlbums ( connection , cursor )
for kodialbum in allKodiAlbums :
allKodiAlbumIds . append ( kodialbum [ 1 ] )
total = len ( allEmbyAlbums ) + 1
count = 1
#### PROCESS SONGS ADDS AND UPDATES ###
for item in allEmbyAlbums :
if ( self . ShouldStop ( ) ) :
return False
allEmbyAlbumIds . append ( item [ " Id " ] )
if ( pDialog != None ) :
progressTitle = " Processing Music Albums ( " + str ( count ) + " of " + str ( total ) + " ) "
2015-05-08 10:05:15 +00:00
percentage = int ( ( ( float ( count ) / float ( total ) ) * 100 ) )
pDialog . update ( percentage , " Emby for Kodi - Running Sync " , progressTitle )
2015-05-07 22:04:40 +00:00
count + = 1
kodiAlbum = None
for kodialbum in allKodiAlbums :
if kodialbum [ 1 ] == item [ " Id " ] :
kodiAlbum = kodialbum
if kodiAlbum == None :
2015-07-30 19:23:50 +00:00
WriteKodiMusicDB ( ) . addOrUpdateAlbumToKodiLibrary ( item , connection , cursor )
2015-05-07 22:04:40 +00:00
else :
if kodiAlbum [ 2 ] != API ( ) . getChecksum ( item ) :
2015-07-30 19:23:50 +00:00
WriteKodiMusicDB ( ) . addOrUpdateAlbumToKodiLibrary ( item , connection , cursor )
2015-05-07 22:04:40 +00:00
#### PROCESS DELETES #####
allEmbyAlbumIds = set ( allEmbyAlbumIds )
for kodiId in allKodiAlbumIds :
if not kodiId in allEmbyAlbumIds :
WINDOW . setProperty ( kodiId , " deleted " )
WriteKodiMusicDB ( ) . deleteItemFromKodiLibrary ( kodiId , connection , cursor )
2015-03-18 17:00:38 +00:00
2015-05-02 09:56:31 +00:00
def IncrementalSync ( self , itemList ) :
2015-03-21 13:31:30 +00:00
2015-05-07 22:06:49 +00:00
startupDone = WINDOW . getProperty ( " startup " ) == " done "
2015-03-21 13:31:30 +00:00
2015-05-07 22:06:49 +00:00
#only perform incremental scan when full scan is completed
if startupDone :
2015-03-21 13:31:30 +00:00
2015-05-07 22:06:49 +00:00
#this will only perform sync for items received by the websocket
2015-08-14 09:03:12 +00:00
dbSyncIndication = utils . settings ( " dbSyncIndication " ) == " true "
performMusicSync = utils . settings ( " enableMusicSync " ) == " true "
2015-05-07 22:06:49 +00:00
WINDOW . setProperty ( " SyncDatabaseRunning " , " true " )
2015-08-15 02:00:21 +00:00
#show the progress dialog
pDialog = None
2015-05-31 00:47:44 +00:00
if ( dbSyncIndication and xbmc . Player ( ) . isPlaying ( ) == False ) :
2015-08-15 02:00:21 +00:00
pDialog = xbmcgui . DialogProgressBG ( )
pDialog . create ( ' Emby for Kodi ' , ' Incremental Sync ' )
self . logMsg ( " Doing LibraryChanged : Show Progress IncrementalSync() " , 0 ) ;
2015-05-07 22:06:49 +00:00
connection = utils . KodiSQL ( " video " )
cursor = connection . cursor ( )
try :
#### PROCESS MOVIES ####
views = ReadEmbyDB ( ) . getCollections ( " movies " )
for view in views :
allEmbyMovies = ReadEmbyDB ( ) . getMovies ( view . get ( ' id ' ) , itemList )
2015-08-15 02:00:21 +00:00
count = 1
total = len ( allEmbyMovies ) + 1
2015-05-07 22:06:49 +00:00
for item in allEmbyMovies :
2015-08-15 02:00:21 +00:00
if ( pDialog != None ) :
progressTitle = " Incremental Sync " + " ( " + str ( count ) + " of " + str ( total ) + " ) "
percentage = int ( ( ( float ( count ) / float ( total ) ) * 100 ) )
pDialog . update ( percentage , " Emby for Kodi - Incremental Sync Movies " , progressTitle )
count = count + 1
if not item . get ( ' IsFolder ' ) :
2015-05-07 22:06:49 +00:00
WriteKodiVideoDB ( ) . addOrUpdateMovieToKodiLibrary ( item [ " Id " ] , connection , cursor , view . get ( ' title ' ) )
2015-08-15 02:00:21 +00:00
2015-05-07 22:06:49 +00:00
#### PROCESS BOX SETS #####
boxsets = ReadEmbyDB ( ) . getBoxSets ( )
2015-08-15 02:00:21 +00:00
count = 1
total = len ( boxsets ) + 1
2015-05-07 22:06:49 +00:00
for boxset in boxsets :
2015-09-01 13:01:52 +00:00
if ( boxset [ " Id " ] in itemList ) :
utils . logMsg ( " IncrementalSync " , " Updating box Set : " + str ( boxset [ " Name " ] ) , 1 )
boxsetMovies = ReadEmbyDB ( ) . getMoviesInBoxSet ( boxset [ " Id " ] )
WriteKodiVideoDB ( ) . addBoxsetToKodiLibrary ( boxset , connection , cursor )
if ( pDialog != None ) :
progressTitle = " Incremental Sync " + " ( " + str ( count ) + " of " + str ( total ) + " ) "
percentage = int ( ( ( float ( count ) / float ( total ) ) * 100 ) )
pDialog . update ( percentage , " Emby for Kodi - Incremental Sync BoxSet " , progressTitle )
count = count + 1
WriteKodiVideoDB ( ) . removeMoviesFromBoxset ( boxset , connection , cursor )
for boxsetMovie in boxsetMovies :
WriteKodiVideoDB ( ) . updateBoxsetToKodiLibrary ( boxsetMovie , boxset , connection , cursor )
else :
utils . logMsg ( " IncrementalSync " , " Skipping Box Set : " + boxset [ " Name " ] , 1 )
2015-05-07 22:06:49 +00:00
#### PROCESS TV SHOWS ####
views = ReadEmbyDB ( ) . getCollections ( " tvshows " )
for view in views :
allEmbyTvShows = ReadEmbyDB ( ) . getTvShows ( view . get ( ' id ' ) , itemList )
2015-08-15 02:00:21 +00:00
count = 1
total = len ( allEmbyTvShows ) + 1
2015-05-07 22:06:49 +00:00
for item in allEmbyTvShows :
2015-08-15 02:00:21 +00:00
if ( pDialog != None ) :
progressTitle = " Incremental Sync " + " ( " + str ( count ) + " of " + str ( total ) + " ) "
percentage = int ( ( ( float ( count ) / float ( total ) ) * 100 ) )
pDialog . update ( percentage , " Emby for Kodi - Incremental Sync Tv " , progressTitle )
count = count + 1
2015-08-26 03:21:31 +00:00
if utils . settings ( ' syncEmptyShows ' ) == " true " or ( item . get ( ' IsFolder ' ) and item . get ( ' RecursiveItemCount ' ) != 0 ) :
2015-05-07 22:06:49 +00:00
kodiId = WriteKodiVideoDB ( ) . addOrUpdateTvShowToKodiLibrary ( item [ " Id " ] , connection , cursor , view . get ( ' title ' ) )
2015-05-08 10:05:15 +00:00
2015-05-12 19:40:58 +00:00
#### PROCESS OTHERS BY THE ITEMLIST ######
2015-08-15 02:00:21 +00:00
count = 1
total = len ( itemList ) + 1
2015-05-07 22:06:49 +00:00
for item in itemList :
2015-05-02 10:51:46 +00:00
2015-08-15 02:00:21 +00:00
if ( pDialog != None ) :
progressTitle = " Incremental Sync " + " ( " + str ( count ) + " of " + str ( total ) + " ) "
percentage = int ( ( ( float ( count ) / float ( total ) ) * 100 ) )
pDialog . update ( percentage , " Emby for Kodi - Incremental Sync Items " , progressTitle )
count = count + 1
2015-05-07 22:06:49 +00:00
MBitem = ReadEmbyDB ( ) . getItem ( item )
2015-08-03 09:59:39 +00:00
itemType = MBitem . get ( ' Type ' , " " )
2015-05-12 19:40:58 +00:00
#### PROCESS EPISODES ######
2015-07-29 01:03:05 +00:00
if " Episode " in itemType :
2015-05-02 11:47:04 +00:00
2015-05-07 22:06:49 +00:00
#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 ]
else :
kodi_show_id = None
2015-05-02 11:47:04 +00:00
2015-05-07 22:06:49 +00:00
if kodi_show_id :
WriteKodiVideoDB ( ) . addOrUpdateEpisodeToKodiLibrary ( MBitem [ " Id " ] , kodi_show_id , connection , cursor )
2015-05-12 19:27:27 +00:00
else :
#tv show doesn't exist
#perform full tvshow sync instead so both the show and episodes get added
self . TvShowsFullSync ( connection , cursor , None )
2015-06-18 08:03:44 +00:00
2015-07-29 01:03:05 +00:00
elif " Season " in itemType :
2015-06-18 08:03:44 +00:00
#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 ]
# update season
WriteKodiVideoDB ( ) . updateSeasons ( MBitem [ " SeriesId " ] , kodi_show_id , connection , cursor )
2015-05-12 19:40:58 +00:00
#### PROCESS BOXSETS ######
2015-07-29 01:03:05 +00:00
elif " BoxSet " in itemType :
2015-05-12 19:40:58 +00:00
boxsetMovies = ReadEmbyDB ( ) . getMoviesInBoxSet ( boxset [ " Id " ] )
WriteKodiVideoDB ( ) . addBoxsetToKodiLibrary ( boxset , connection , cursor )
for boxsetMovie in boxsetMovies :
WriteKodiVideoDB ( ) . updateBoxsetToKodiLibrary ( boxsetMovie , boxset , connection , cursor )
#### PROCESS MUSICVIDEOS ####
2015-07-29 01:03:05 +00:00
elif " MusicVideo " in itemType :
2015-05-12 19:40:58 +00:00
if not MBitem . get ( ' IsFolder ' ) :
WriteKodiVideoDB ( ) . addOrUpdateMusicVideoToKodiLibrary ( MBitem [ " Id " ] , connection , cursor )
2015-05-07 22:06:49 +00:00
### commit all changes to database ###
2015-05-07 22:04:40 +00:00
connection . commit ( )
cursor . close ( )
2015-05-07 22:06:49 +00:00
### PROCESS MUSIC LIBRARY ###
if performMusicSync :
connection = utils . KodiSQL ( " music " )
cursor = connection . cursor ( )
for item in itemList :
MBitem = ReadEmbyDB ( ) . getItem ( item )
2015-08-03 09:59:39 +00:00
itemType = MBitem . get ( ' Type ' , " " )
2015-07-29 01:03:05 +00:00
if " MusicArtist " in itemType :
2015-08-14 09:03:12 +00:00
WriteKodiMusicDB ( ) . addOrUpdateArtistToKodiLibrary ( MBitem , connection , cursor )
2015-07-29 01:03:05 +00:00
if " MusicAlbum " in itemType :
2015-08-14 09:03:12 +00:00
WriteKodiMusicDB ( ) . addOrUpdateAlbumToKodiLibrary ( MBitem , connection , cursor )
2015-07-29 01:03:05 +00:00
if " Audio " in itemType :
2015-08-14 09:03:12 +00:00
WriteKodiMusicDB ( ) . addOrUpdateSongToKodiLibrary ( MBitem , connection , cursor )
2015-05-07 22:06:49 +00:00
connection . commit ( )
cursor . close ( )
finally :
2015-08-15 02:00:21 +00:00
if ( pDialog != None ) :
pDialog . close ( )
self . SaveLastSync ( )
2015-05-07 22:06:49 +00:00
xbmc . executebuiltin ( " UpdateLibrary(video) " )
WINDOW . setProperty ( " SyncDatabaseRunning " , " false " )
2015-06-24 07:03:49 +00:00
# tell any widgets to refresh because the content has changed
WINDOW . setProperty ( " widgetreload " , datetime . now ( ) . strftime ( ' % Y- % m- %d % H: % M: % S ' ) )
2015-05-08 13:46:07 +00:00
2015-06-28 12:08:06 +00:00
def removefromDB ( self , itemList , deleteEmbyItem = False ) :
2015-08-15 02:00:21 +00:00
dbSyncIndication = utils . settings ( " dbSyncIndication " ) == " true "
#show the progress dialog
pDialog = None
if ( dbSyncIndication and xbmc . Player ( ) . isPlaying ( ) == False ) :
pDialog = xbmcgui . DialogProgressBG ( )
pDialog . create ( ' Emby for Kodi ' , ' Incremental Sync ' )
self . logMsg ( " Doing LibraryChanged : Show Progress removefromDB() " , 0 ) ;
2015-06-28 12:08:06 +00:00
# Delete from Kodi before Emby
# To be able to get mediaType
doUtils = DownloadUtils ( )
2015-07-18 08:08:05 +00:00
video = { }
2015-06-28 12:08:06 +00:00
music = [ ]
2015-07-18 08:08:05 +00:00
# Database connection to myVideosXX.db
connectionvideo = utils . KodiSQL ( )
cursorvideo = connectionvideo . cursor ( )
# Database connection to myMusicXX.db
connectionmusic = utils . KodiSQL ( " music " )
cursormusic = connectionmusic . cursor ( )
2015-06-28 12:08:06 +00:00
2015-08-15 02:00:21 +00:00
count = 1
total = len ( itemList ) + 1
2015-07-18 08:08:05 +00:00
for item in itemList :
2015-08-15 02:00:21 +00:00
if ( pDialog != None ) :
progressTitle = " Incremental Sync " + " ( " + str ( count ) + " of " + str ( total ) + " ) "
percentage = int ( ( ( float ( count ) / float ( total ) ) * 100 ) )
pDialog . update ( percentage , " Emby for Kodi - Incremental Sync Delete " , progressTitle )
count = count + 1
2015-07-18 08:08:05 +00:00
# Sort by type for database deletion
try : # Search video database
self . logMsg ( " Check video database. " , 1 )
cursorvideo . execute ( " SELECT media_type FROM emby WHERE emby_id = ? " , ( item , ) )
mediatype = cursorvideo . fetchone ( ) [ 0 ]
video [ item ] = mediatype
#video.append(itemtype)
except :
self . logMsg ( " Check music database. " , 1 )
try : # Search music database
cursormusic . execute ( " SELECT media_type FROM emby WHERE emby_id = ? " , ( item , ) )
cursormusic . fetchone ( ) [ 0 ]
music . append ( item )
except : self . logMsg ( " Item %s is not found in Kodi database. " % item , 1 )
2015-06-28 12:08:06 +00:00
if len ( video ) > 0 :
2015-07-18 08:08:05 +00:00
connection = connectionvideo
cursor = cursorvideo
# Process video library
2015-08-15 02:00:21 +00:00
count = 1
total = len ( video ) + 1
2015-06-28 12:08:06 +00:00
for item in video :
2015-07-18 08:08:05 +00:00
2015-08-15 02:00:21 +00:00
if ( pDialog != None ) :
progressTitle = " Incremental Sync " + " ( " + str ( count ) + " of " + str ( total ) + " ) "
percentage = int ( ( ( float ( count ) / float ( total ) ) * 100 ) )
pDialog . update ( percentage , " Emby for Kodi - Incremental Sync Delete " , progressTitle )
count = count + 1
2015-07-18 08:08:05 +00:00
type = video [ item ]
self . logMsg ( " Doing LibraryChanged: Items Removed: Calling deleteItemFromKodiLibrary: %s " % item , 1 )
2015-06-28 12:08:06 +00:00
if " episode " in type :
# Get the TV Show Id for reference later
showId = ReadKodiDB ( ) . getShowIdByEmbyId ( item , connection , cursor )
2015-07-18 08:08:05 +00:00
self . logMsg ( " ShowId: %s " % showId , 1 )
2015-06-28 12:08:06 +00:00
WriteKodiVideoDB ( ) . deleteItemFromKodiLibrary ( item , connection , cursor )
# Verification
if " episode " in type :
showTotalCount = ReadKodiDB ( ) . getShowTotalCount ( showId , connection , cursor )
2015-07-18 08:08:05 +00:00
self . logMsg ( " ShowTotalCount: %s " % showTotalCount , 1 )
2015-06-28 12:08:06 +00:00
# If there are no episodes left
2015-06-28 13:36:44 +00:00
if showTotalCount == 0 or showTotalCount == None :
2015-06-28 12:08:06 +00:00
# Delete show
embyId = ReadKodiDB ( ) . getEmbyIdByKodiId ( showId , " tvshow " , connection , cursor )
2015-07-18 08:08:05 +00:00
self . logMsg ( " Message: Doing LibraryChanged: Deleting show: %s " % embyId , 1 )
2015-06-28 12:08:06 +00:00
WriteKodiVideoDB ( ) . deleteItemFromKodiLibrary ( embyId , connection , cursor )
connection . commit ( )
2015-07-18 08:08:05 +00:00
# Close connection
cursorvideo . close ( )
2015-06-28 12:08:06 +00:00
if len ( music ) > 0 :
2015-07-18 08:08:05 +00:00
connection = connectionmusic
cursor = cursormusic
2015-06-28 12:08:06 +00:00
#Process music library
2015-08-14 09:03:12 +00:00
if utils . settings ( ' enableMusicSync ' ) == " true " :
2015-06-28 12:08:06 +00:00
for item in music :
self . logMsg ( " Message : Doing LibraryChanged : Items Removed : Calling deleteItemFromKodiLibrary (musiclibrary): " + item , 0 )
WriteKodiMusicDB ( ) . deleteItemFromKodiLibrary ( item , connection , cursor )
connection . commit ( )
2015-07-18 08:08:05 +00:00
# Close connection
cursormusic . close ( )
2015-06-28 12:08:06 +00:00
if deleteEmbyItem :
for item in itemList :
url = " {server} /mediabrowser/Items/ %s " % item
self . logMsg ( ' Deleting via URL: %s ' % url )
2015-07-18 08:08:05 +00:00
doUtils . downloadUrl ( url , type = " DELETE " )
2015-06-28 12:08:06 +00:00
xbmc . executebuiltin ( " Container.Refresh " )
2015-08-15 02:00:21 +00:00
if ( pDialog != None ) :
pDialog . close ( )
self . SaveLastSync ( )
2015-08-14 09:03:12 +00:00
def setUserdata ( self , listItems ) :
2015-08-15 02:00:21 +00:00
dbSyncIndication = utils . settings ( " dbSyncIndication " ) == " true "
2015-08-17 23:24:07 +00:00
musicenabled = utils . settings ( ' enableMusicSync ' ) == " true "
2015-08-15 02:00:21 +00:00
#show the progress dialog
pDialog = None
if ( dbSyncIndication and xbmc . Player ( ) . isPlaying ( ) == False ) :
pDialog = xbmcgui . DialogProgressBG ( )
pDialog . create ( ' Emby for Kodi ' , ' Incremental Sync ' )
self . logMsg ( " Doing LibraryChanged : Show Progress setUserdata() " , 0 ) ;
2015-08-14 09:03:12 +00:00
# We need to sort between video and music database
video = [ ]
music = [ ]
# Database connection to myVideosXX.db
connectionvideo = utils . KodiSQL ( )
cursorvideo = connectionvideo . cursor ( )
# Database connection to myMusicXX.db
2015-08-15 03:16:38 +00:00
connectionmusic = utils . KodiSQL ( ' music ' )
cursormusic = connectionmusic . cursor ( )
2015-08-14 09:03:12 +00:00
2015-08-15 02:00:21 +00:00
count = 1
total = len ( listItems ) + 1
2015-08-14 09:03:12 +00:00
for userdata in listItems :
2015-08-15 03:16:38 +00:00
# Sort between video and music
2015-08-14 09:03:12 +00:00
itemId = userdata [ ' ItemId ' ]
2015-08-15 02:00:21 +00:00
if ( pDialog != None ) :
progressTitle = " Incremental Sync " + " ( " + str ( count ) + " of " + str ( total ) + " ) "
percentage = int ( ( ( float ( count ) / float ( total ) ) * 100 ) )
pDialog . update ( percentage , " Emby for Kodi - Incremental Sync User Data " , progressTitle )
count = count + 1
2015-08-14 09:03:12 +00:00
cursorvideo . execute ( " SELECT media_type FROM emby WHERE emby_id = ? " , ( itemId , ) )
try : # Search video database
2015-08-28 08:13:06 +00:00
self . logMsg ( " Check video database. " , 2 )
2015-08-14 09:03:12 +00:00
mediatype = cursorvideo . fetchone ( ) [ 0 ]
video . append ( userdata )
2015-08-14 10:32:11 +00:00
except :
2015-08-17 23:24:07 +00:00
if musicenabled :
cursormusic . execute ( " SELECT media_type FROM emby WHERE emby_id = ? " , ( itemId , ) )
try : # Search music database
2015-08-28 08:13:06 +00:00
self . logMsg ( " Check the music database. " , 2 )
2015-08-17 23:24:07 +00:00
mediatype = cursormusic . fetchone ( ) [ 0 ]
music . append ( userdata )
2015-08-28 08:13:06 +00:00
except : self . logMsg ( " Item %s is not found in Kodi database. " % itemId , 1 )
2015-08-17 23:24:07 +00:00
else :
2015-08-28 08:13:06 +00:00
self . logMsg ( " Item %s is not found in Kodi database. " % itemId , 1 )
2015-08-14 09:03:12 +00:00
if len ( video ) > 0 :
connection = connectionvideo
cursor = cursorvideo
# Process the userdata update for video library
2015-08-15 02:00:21 +00:00
count = 1
total = len ( video ) + 1
2015-08-14 09:03:12 +00:00
for userdata in video :
2015-08-15 02:00:21 +00:00
if ( pDialog != None ) :
progressTitle = " Incremental Sync " + " ( " + str ( count ) + " of " + str ( total ) + " ) "
percentage = int ( ( ( float ( count ) / float ( total ) ) * 100 ) )
pDialog . update ( percentage , " Emby for Kodi - Incremental Sync User Data " , progressTitle )
2015-08-15 03:16:38 +00:00
count = count + 1
2015-08-14 09:03:12 +00:00
WriteKodiVideoDB ( ) . updateUserdata ( userdata , connection , cursor )
connection . commit ( )
xbmc . executebuiltin ( " UpdateLibrary(video) " )
# Close connection
cursorvideo . close ( )
2015-08-15 03:16:38 +00:00
if len ( music ) > 0 :
2015-08-14 09:03:12 +00:00
connection = connectionmusic
cursor = cursormusic
#Process music library
2015-08-15 03:16:38 +00:00
count = 1
total = len ( video ) + 1
2015-08-14 09:03:12 +00:00
# Process the userdata update for music library
if musicenabled :
for userdata in music :
2015-08-15 03:16:38 +00:00
if ( pDialog != None ) :
progressTitle = " Incremental Sync " + " ( " + str ( count ) + " of " + str ( total ) + " ) "
percentage = int ( ( ( float ( count ) / float ( total ) ) * 100 ) )
pDialog . update ( percentage , " Emby for Kodi - Incremental Sync User Data " , progressTitle )
count = count + 1
2015-08-14 09:03:12 +00:00
WriteKodiMusicDB ( ) . updateUserdata ( userdata , connection , cursor )
connection . commit ( )
2015-08-15 03:16:38 +00:00
#xbmc.executebuiltin("UpdateLibrary(music)")
2015-08-14 09:03:12 +00:00
# Close connection
2015-08-15 03:16:38 +00:00
cursormusic . close ( )
2015-08-15 02:00:21 +00:00
if ( pDialog != None ) :
pDialog . close ( )
2015-08-14 09:03:12 +00:00
self . SaveLastSync ( )
2015-08-15 02:00:21 +00:00
2015-08-14 09:03:12 +00:00
2015-06-28 12:08:06 +00:00
def remove_items ( self , itemsRemoved ) :
2015-07-18 08:08:05 +00:00
# websocket client
2015-08-15 02:00:21 +00:00
if ( len ( itemsRemoved ) > 0 ) :
self . logMsg ( " Doing LibraryChanged : Processing Deleted : " + str ( itemsRemoved ) , 0 )
self . removeItems . extend ( itemsRemoved )
2015-06-28 12:08:06 +00:00
def update_items ( self , itemsToUpdate ) :
2015-07-18 08:08:05 +00:00
# websocket client
2015-06-28 12:08:06 +00:00
if ( len ( itemsToUpdate ) > 0 ) :
2015-07-18 08:08:05 +00:00
self . logMsg ( " Doing LibraryChanged : Processing Added and Updated : " + str ( itemsToUpdate ) , 0 )
2015-06-28 12:08:06 +00:00
self . updateItems . extend ( itemsToUpdate )
2015-08-01 00:26:22 +00:00
2015-06-28 12:08:06 +00:00
def user_data_update ( self , userDataList ) :
2015-07-18 08:08:05 +00:00
# websocket client
2015-08-15 02:00:21 +00:00
if ( len ( userDataList ) > 0 ) :
self . logMsg ( " Doing LibraryChanged : Processing User Data Changed : " + str ( userDataList ) , 0 )
self . userdataItems . extend ( userDataList )
2015-06-28 12:08:06 +00:00
2015-05-02 17:49:39 +00:00
def ShouldStop ( self ) :
if ( xbmc . abortRequested ) :
2015-03-16 03:10:41 +00:00
return True
2015-04-03 08:39:16 +00:00
if ( WINDOW . getProperty ( " SyncDatabaseShouldStop " ) == " true " ) :
return True
return False
2015-09-11 02:27:36 +00:00
def checkDBVersion ( self , currVersion , minVersion ) :
currMajor , currMinor , currPatch = currVersion . split ( " . " )
minMajor , minMinor , minPatch = minVersion . split ( " . " )
if currMajor > minMajor :
return True
elif currMajor == minMajor and currMinor > minMinor :
return True
elif currMajor == minMajor and currMinor == minMinor and currPatch > = minPatch :
return True
else :
return False
2015-06-16 05:53:01 +00:00
def run ( self ) :
2015-09-24 11:59:26 +00:00
2015-09-24 11:48:43 +00:00
startupComplete = False
2015-09-24 11:59:26 +00:00
kodiProfile = xbmc . translatePath ( " special://profile " )
self . logMsg ( " --- Starting Library Sync Thread --- " , 0 )
2015-06-16 05:53:01 +00:00
while not self . KodiMonitor . abortRequested ( ) :
2015-07-18 08:08:05 +00:00
# In the event the server goes offline after
# the thread has already been started.
while self . suspendClient == True :
# The service.py will change self.suspendClient to False
if self . KodiMonitor . waitForAbort ( 5 ) :
# Abort was requested while waiting. We should exit
break
2015-09-06 17:28:00 +00:00
# Check if the version of Emby for Kodi the DB was created with is recent enough - controled by Window property set at top of service _INIT_
# START TEMPORARY CODE
# Only get in here for a while, can be removed later
if utils . settings ( " dbCreatedWithVersion " ) == " " and utils . settings ( " SyncInstallRunDone " ) == " true " :
2015-09-11 02:27:36 +00:00
self . logMsg ( " Unknown DB version " , 0 )
2015-09-24 11:59:26 +00:00
return_value = xbmcgui . Dialog ( ) . yesno ( " DB Version " , " Can ' t detect version of Emby for Kodi the DB was created with. \n Was it at least version " + utils . window ( ' minDBVersion ' ) + " ? " )
2015-09-06 17:28:00 +00:00
if return_value == 0 :
utils . settings ( " dbCreatedWithVersion " , " 0.0.0 " )
2015-09-11 02:27:36 +00:00
self . logMsg ( " DB version out of date according to user " , 0 )
2015-09-06 17:28:00 +00:00
else :
2015-09-24 11:59:26 +00:00
utils . settings ( " dbCreatedWithVersion " , utils . window ( ' minDBVersion ' ) )
2015-09-11 02:27:36 +00:00
self . logMsg ( " DB version okay according to user " , 0 )
2015-09-06 17:28:00 +00:00
# END TEMPORARY CODE
2015-09-15 16:26:32 +00:00
2015-09-24 11:59:26 +00:00
if ( utils . settings ( " SyncInstallRunDone " ) == " true " and self . checkDBVersion ( utils . settings ( " dbCreatedWithVersion " ) , utils . window ( ' minDBVersion ' ) ) == False and utils . window ( ' minDBVersionCheck ' ) != " true " ) :
2015-09-11 02:27:36 +00:00
self . logMsg ( " DB version out of date according to check " , 0 )
2015-09-06 17:28:00 +00:00
return_value = xbmcgui . Dialog ( ) . yesno ( " DB Version " , " Detected the DB needs to be recreated for \n this version of Emby for Kodi. \n Proceed? " )
if return_value == 0 :
2015-09-11 02:27:36 +00:00
self . logMsg ( " DB version out of date !!! USER IGNORED !!! " , 0 )
2015-09-06 17:28:00 +00:00
xbmcgui . Dialog ( ) . ok ( " Emby for Kodi " , " Emby for Kodi may not work \n correctly until the database is reset. \n " )
2015-09-24 11:59:26 +00:00
utils . window ( ' minDBVersionCheck ' , value = " true " )
2015-09-06 17:28:00 +00:00
else :
utils . reset ( )
2015-06-16 05:53:01 +00:00
# Library sync
if not startupComplete :
# Run full sync
2015-09-15 16:26:32 +00:00
self . logMsg ( " DB Version: " + utils . settings ( " dbCreatedWithVersion " ) , 0 )
2015-06-16 05:53:01 +00:00
self . logMsg ( " Doing_Db_Sync: syncDatabase (Started) " , 1 )
2015-07-18 08:08:05 +00:00
startTime = datetime . now ( )
2015-06-16 05:53:01 +00:00
libSync = self . FullLibrarySync ( )
2015-07-18 08:08:05 +00:00
elapsedTime = datetime . now ( ) - startTime
self . logMsg ( " Doing_Db_Sync: syncDatabase (Finished in: %s ) %s " % ( str ( elapsedTime ) . split ( ' . ' ) [ 0 ] , libSync ) , 1 )
2015-06-16 05:53:01 +00:00
if libSync :
startupComplete = True
2015-07-18 08:08:05 +00:00
# Set via Kodi Monitor event
2015-09-24 11:59:26 +00:00
if utils . window ( ' OnWakeSync ' ) == " true " and utils . window ( ' Server_online ' ) == " true " :
utils . window ( " OnWakeSync " , clear = True )
if utils . window ( " SyncDatabaseRunning " ) != " true " :
2015-07-18 08:08:05 +00:00
self . logMsg ( " Doing_Db_Sync Post Resume: syncDatabase (Started) " , 0 )
2015-06-16 05:53:01 +00:00
libSync = self . FullLibrarySync ( )
2015-07-18 08:08:05 +00:00
self . logMsg ( " Doing_Db_Sync Post Resume: syncDatabase (Finished) " + str ( libSync ) , 0 )
2015-06-16 05:53:01 +00:00
2015-08-14 09:03:12 +00:00
2015-07-18 08:08:05 +00:00
if len ( self . updateItems ) > 0 :
# Add or update items
self . logMsg ( " Processing items: %s " % ( str ( self . updateItems ) ) , 1 )
2015-06-28 12:08:06 +00:00
listItems = self . updateItems
self . updateItems = [ ]
self . IncrementalSync ( listItems )
2015-08-14 09:03:12 +00:00
if len ( self . userdataItems ) > 0 :
# Process userdata changes only
self . logMsg ( " Processing items: %s " % ( str ( self . userdataItems ) ) , 1 )
listItems = self . userdataItems
self . userdataItems = [ ]
self . setUserdata ( listItems )
2015-06-28 12:08:06 +00:00
if len ( self . removeItems ) > 0 :
# Remove item from Kodi library
2015-07-18 08:08:05 +00:00
self . logMsg ( " Removing items: %s " % self . removeItems , 1 )
2015-06-28 12:08:06 +00:00
listItems = self . removeItems
self . removeItems = [ ]
self . removefromDB ( listItems )
2015-09-24 11:59:26 +00:00
if utils . window ( " kodiProfile_emby " ) != kodiProfile :
# Profile change happened, terminate this thread
self . logMsg ( " Kodi profile was: %s and changed to: %s . Terminating Library thread. " % ( kodiProfile , utils . window ( " kodiProfile_emby " ) ) , 1 )
break
2015-06-16 05:53:01 +00:00
if self . KodiMonitor . waitForAbort ( 1 ) :
# Abort was requested while waiting. We should exit
break
2015-06-28 04:37:40 +00:00
self . logMsg ( " --- Library Sync Thread stopped --- " , 0 )
2015-07-18 08:08:05 +00:00
def suspendClient ( self ) :
self . suspendClient = True
self . logMsg ( " --- Library Sync Thread paused --- " , 0 )
def resumeClient ( self ) :
self . suspendClient = False
2015-08-26 03:21:31 +00:00
self . logMsg ( " --- Library Sync Thread resumed --- " , 0 )