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