Merge remote-tracking branch 'MediaBrowser/master' into develop

This commit is contained in:
tomkat83 2016-01-23 11:55:31 +01:00
commit c98e7ad60c
7 changed files with 526 additions and 170 deletions

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.video.plexkodiconnect" <addon id="plugin.video.plexkodiconnect"
name="PlexKodiConnect" name="PlexKodiConnect"
version="1.1.79" version="1.1.80"
provider-name="croneter"> provider-name="croneter">
<requires> <requires>
<import addon="xbmc.python" version="2.1.0"/> <import addon="xbmc.python" version="2.1.0"/>

View file

@ -1,3 +1,8 @@
version 1.1.80
- Add refresh for video nodes
- Fix for home videos (being unable to back out of the menu). Running refresh playlists/nodes will fix this.
- Fix to music, causing sync to crash
version 1.1.76 version 1.1.76
- Add music rating system - Add music rating system
- Add home videos as a dynamic plugin entry (requires a reset) - Add home videos as a dynamic plugin entry (requires a reset)

View file

@ -106,7 +106,7 @@ class Main:
import librarysync import librarysync
lib = librarysync.LibrarySync() lib = librarysync.LibrarySync()
if mode == "manualsync": if mode == "manualsync":
lib.fullSync(manualrun=True) librarysync.ManualSync()
else: else:
lib.fullSync(repair=True) lib.fullSync(repair=True)
else: else:

View file

@ -112,15 +112,15 @@ def doMainListing():
addDirectoryItem("Live Tv Recordings (experimental)", "plugin://plugin.video.plexkodiconnect/?mode=browsecontent&type=recordings&folderid=root") addDirectoryItem("Live Tv Recordings (experimental)", "plugin://plugin.video.plexkodiconnect/?mode=browsecontent&type=recordings&folderid=root")
# some extra entries for settings and stuff. TODO --> localize the labels # some extra entries for settings and stuff. TODO --> localize the labels
addDirectoryItem("Network credentials", "plugin://plugin.video.plexkodiconnect/?mode=passwords") addDirectoryItem("Network credentials", "plugin://plugin.video.emby/?mode=passwords")
addDirectoryItem("Settings", "plugin://plugin.video.plexkodiconnect/?mode=settings") addDirectoryItem("Settings", "plugin://plugin.video.emby/?mode=settings")
addDirectoryItem("Add user to session", "plugin://plugin.video.plexkodiconnect/?mode=adduser") addDirectoryItem("Add user to session", "plugin://plugin.video.emby/?mode=adduser")
addDirectoryItem("Refresh Emby playlists", "plugin://plugin.video.plexkodiconnect/?mode=refreshplaylist") addDirectoryItem("Refresh Emby playlists/nodes", "plugin://plugin.video.emby/?mode=refreshplaylist")
addDirectoryItem("Perform manual sync", "plugin://plugin.video.plexkodiconnect/?mode=manualsync") addDirectoryItem("Perform manual sync", "plugin://plugin.video.emby/?mode=manualsync")
addDirectoryItem("Repair local database (force update all content)", "plugin://plugin.video.plexkodiconnect/?mode=repair") addDirectoryItem("Repair local database (force update all content)", "plugin://plugin.video.emby/?mode=repair")
addDirectoryItem("Perform local database reset (full resync)", "plugin://plugin.video.plexkodiconnect/?mode=reset") addDirectoryItem("Perform local database reset (full resync)", "plugin://plugin.video.emby/?mode=reset")
addDirectoryItem("Cache all images to Kodi texture cache", "plugin://plugin.video.plexkodiconnect/?mode=texturecache") addDirectoryItem("Cache all images to Kodi texture cache", "plugin://plugin.video.emby/?mode=texturecache")
addDirectoryItem("Sync Emby Theme Media to Kodi", "plugin://plugin.video.plexkodiconnect/?mode=thememedia") addDirectoryItem("Sync Emby Theme Media to Kodi", "plugin://plugin.video.emby/?mode=thememedia")
xbmcplugin.endOfDirectory(int(sys.argv[1])) xbmcplugin.endOfDirectory(int(sys.argv[1]))
@ -412,19 +412,22 @@ def refreshPlaylist():
try: try:
# First remove playlists # First remove playlists
utils.deletePlaylists() utils.deletePlaylists()
# Remove video nodes
utils.deleteNodes()
# Refresh views # Refresh views
lib.refreshViews() lib.refreshViews()
dialog.notification( dialog.notification(
heading="Emby for Kodi", heading="Emby for Kodi",
message="Emby playlist refreshed", message="Emby playlists/nodes refreshed",
icon="special://home/addons/plugin.video.plexkodiconnect/icon.png", icon="special://home/addons/plugin.video.plexkodiconnect/icon.png",
time=1000, time=1000,
sound=False) sound=False)
except Exception as e: except Exception as e:
utils.logMsg("EMBY", "Refresh playlist failed: %s" % e, 1) utils.logMsg("EMBY", "Refresh playlists/nodes failed: %s" % e, 1)
dialog.notification( dialog.notification(
heading="Emby for Kodi", heading="Emby for Kodi",
message="Emby playlist refresh failed", message="Emby playlists/nodes refresh failed",
icon=xbmcgui.NOTIFICATION_ERROR, icon=xbmcgui.NOTIFICATION_ERROR,
time=1000, time=1000,
sound=False) sound=False)

View file

@ -1833,6 +1833,7 @@ class Music(Items):
track = disc*2**16 + tracknumber track = disc*2**16 + tracknumber
year = item.get('ProductionYear') year = item.get('ProductionYear')
duration = API.getRuntime() duration = API.getRuntime()
rating = userdata['UserRating']
#if enabled, try to get the rating from file and/or emby #if enabled, try to get the rating from file and/or emby
if not self.directstream: if not self.directstream:
@ -1840,7 +1841,6 @@ class Music(Items):
else: else:
hasEmbeddedCover = False hasEmbeddedCover = False
comment = API.getOverview() comment = API.getOverview()
rating = userdata['UserRating']
##### GET THE FILE AND PATH ##### ##### GET THE FILE AND PATH #####

View file

@ -403,9 +403,9 @@ class LibrarySync(threading.Thread):
# musicconn = utils.kodiSQL('music') # musicconn = utils.kodiSQL('music')
# musiccursor = musicconn.cursor() # musiccursor = musicconn.cursor()
# startTime = datetime.now() # startTime = datetime.now()
# completed = self.music(embycursor, musiccursor, pDialog, compare=manualrun) # completed = self.music(embycursor, musiccursor, pDialog)
# if not completed: # if not completed:
# utils.window('emby_dbScan', clear=True) # utils.window('emby_dbScan', clear=True)
@ -428,6 +428,7 @@ class LibrarySync(threading.Thread):
elapsedtotal = datetime.now() - starttotal elapsedtotal = datetime.now() - starttotal
utils.window('emby_dbScan', clear=True) utils.window('emby_dbScan', clear=True)
utils.window('emby_initialScan', clear=True)
xbmcgui.Dialog().notification( xbmcgui.Dialog().notification(
heading=self.addonName, heading=self.addonName,
message="%s completed in: %s" % message="%s completed in: %s" %
@ -778,7 +779,6 @@ class LibrarySync(threading.Thread):
""" """
Updates ALL plex elements' view status ('watched' or 'unwatched') and Updates ALL plex elements' view status ('watched' or 'unwatched') and
also updates resume times. also updates resume times.
This is done by downloading one XML for ALL elements with viewId This is done by downloading one XML for ALL elements with viewId
""" """
starttotal = datetime.now() starttotal = datetime.now()
@ -795,7 +795,7 @@ class LibrarySync(threading.Thread):
self.logMsg("Syncing userdata for itemtype %s and viewid %s took " self.logMsg("Syncing userdata for itemtype %s and viewid %s took "
"%s seconds" % (itemType, viewId, elapsedtotal), 0) "%s seconds" % (itemType, viewId, elapsedtotal), 0)
def musicvideos(self, embycursor, kodicursor, pdialog, compare=False): def musicvideos(self, embycursor, kodicursor, pdialog):
# Get musicvideos from emby # Get musicvideos from emby
emby = self.emby emby = self.emby
emby_db = embydb.Embydb_Functions(embycursor) emby_db = embydb.Embydb_Functions(embycursor)
@ -804,16 +804,6 @@ class LibrarySync(threading.Thread):
views = emby_db.getView_byType('musicvideos') views = emby_db.getView_byType('musicvideos')
self.logMsg("Media folders: %s" % views, 1) self.logMsg("Media folders: %s" % views, 1)
if compare:
# Pull the list of musicvideos in Kodi
try:
all_kodimvideos = dict(emby_db.getChecksum('MusicVideo'))
except ValueError:
all_kodimvideos = {}
all_embymvideosIds = set()
updatelist = []
for view in views: for view in views:
if self.shouldStop(): if self.shouldStop():
@ -828,38 +818,10 @@ class LibrarySync(threading.Thread):
heading="Emby for Kodi", heading="Emby for Kodi",
message="Gathering musicvideos from view: %s..." % viewName) message="Gathering musicvideos from view: %s..." % viewName)
if compare: # Initial or repair sync
# Manual sync all_embymvideos = emby.getMusicVideos(viewId, dialog=pdialog)
if pdialog: total = all_embymvideos['TotalRecordCount']
pdialog.update( embymvideos = all_embymvideos['Items']
heading="Emby for Kodi",
message="Comparing musicvideos from view: %s..." % viewName)
all_embymvideos = emby.getMusicVideos(viewId, basic=True, dialog=pdialog)
for embymvideo in all_embymvideos['Items']:
if self.shouldStop():
return False
API = api.API(embymvideo)
itemid = embymvideo['Id']
all_embymvideosIds.add(itemid)
if all_kodimvideos.get(itemid) != API.getChecksum():
# Only update if musicvideo is not in Kodi or checksum is different
updatelist.append(itemid)
self.logMsg("MusicVideos to update for %s: %s" % (viewName, updatelist), 1)
embymvideos = emby.getFullItems(updatelist)
total = len(updatelist)
del updatelist[:]
else:
# Initial or repair sync
all_embymvideos = emby.getMusicVideos(viewId, dialog=pdialog)
total = all_embymvideos['TotalRecordCount']
embymvideos = all_embymvideos['Items']
if pdialog: if pdialog:
pdialog.update(heading="Processing %s / %s items" % (viewName, total)) pdialog.update(heading="Processing %s / %s items" % (viewName, total))
@ -878,15 +840,6 @@ class LibrarySync(threading.Thread):
mvideos.add_update(embymvideo, viewName, viewId) mvideos.add_update(embymvideo, viewName, viewId)
else: else:
self.logMsg("MusicVideos finished.", 2) self.logMsg("MusicVideos finished.", 2)
##### PROCESS DELETES #####
if compare:
# Manual sync, process deletes
for kodimvideo in all_kodimvideos:
if kodimvideo not in all_embymvideosIds:
mvideos.remove(kodimvideo)
else:
self.logMsg("MusicVideos compare finished.", 1)
return True return True
@ -993,7 +946,6 @@ class LibrarySync(threading.Thread):
for view in views: for view in views:
self.PlexUpdateWatched(view['id'], itemType) self.PlexUpdateWatched(view['id'], itemType)
##### PROCESS DELETES #####
if self.compare: if self.compare:
# Manual sync, process deletes # Manual sync, process deletes
with itemtypes.TVShows() as TVShow: with itemtypes.TVShows() as TVShow:
@ -1003,34 +955,12 @@ class LibrarySync(threading.Thread):
self.logMsg("%s sync is finished." % itemType, 1) self.logMsg("%s sync is finished." % itemType, 1)
return True return True
def music(self, embycursor, kodicursor, pdialog, compare=False): def music(self, embycursor, kodicursor, pdialog):
# Get music from emby # Get music from emby
emby = self.emby emby = self.emby
emby_db = embydb.Embydb_Functions(embycursor) emby_db = embydb.Embydb_Functions(embycursor)
music = itemtypes.Music(embycursor, kodicursor) music = itemtypes.Music(embycursor, kodicursor)
if compare:
# Pull the list of movies and boxsets in Kodi
try:
all_kodiartists = dict(emby_db.getChecksum('MusicArtist'))
except ValueError:
all_kodiartists = {}
try:
all_kodialbums = dict(emby_db.getChecksum('MusicAlbum'))
except ValueError:
all_kodialbums = {}
try:
all_kodisongs = dict(emby_db.getChecksum('Audio'))
except ValueError:
all_kodisongs = {}
all_embyartistsIds = set()
all_embyalbumsIds = set()
all_embysongsIds = set()
updatelist = []
process = { process = {
'artists': [emby.getArtists, music.add_updateArtist], 'artists': [emby.getArtists, music.add_updateArtist],
@ -1041,47 +971,9 @@ class LibrarySync(threading.Thread):
for type in types: for type in types:
if pdialog: if pdialog:
pass all_embyitems = process[type][0](dialog=pdialog)
if compare: total = all_embyitems['TotalRecordCount']
# Manual Sync embyitems = all_embyitems['Items']
if pdialog:
pass
if type != "artists":
all_embyitems = process[type][0](basic=True, dialog=pdialog)
else:
all_embyitems = process[type][0](dialog=pdialog)
for embyitem in all_embyitems['Items']:
if self.shouldStop():
return False
API = api.API(embyitem)
itemid = embyitem['Id']
if type == "artists":
all_embyartistsIds.add(itemid)
if all_kodiartists.get(itemid) != API.getChecksum():
# Only update if artist is not in Kodi or checksum is different
updatelist.append(itemid)
elif type == "albums":
all_embyalbumsIds.add(itemid)
if all_kodialbums.get(itemid) != API.getChecksum():
# Only update if album is not in Kodi or checksum is different
updatelist.append(itemid)
else:
all_embysongsIds.add(itemid)
if all_kodisongs.get(itemid) != API.getChecksum():
# Only update if songs is not in Kodi or checksum is different
updatelist.append(itemid)
self.logMsg("%s to update: %s" % (type, updatelist), 1)
embyitems = emby.getFullItems(updatelist)
total = len(updatelist)
del updatelist[:]
else:
all_embyitems = process[type][0](dialog=pdialog)
total = all_embyitems['TotalRecordCount']
embyitems = all_embyitems['Items']
if pdialog: if pdialog:
pass pass
@ -1102,27 +994,6 @@ class LibrarySync(threading.Thread):
else: else:
self.logMsg("%s finished." % type, 2) self.logMsg("%s finished." % type, 2)
##### PROCESS DELETES #####
if compare:
# Manual sync, process deletes
for kodiartist in all_kodiartists:
if kodiartist not in all_embyartistsIds and all_kodiartists[kodiartist] is not None:
music.remove(kodiartist)
else:
self.logMsg("Artist compare finished.", 1)
for kodialbum in all_kodialbums:
if kodialbum not in all_embyalbumsIds:
music.remove(kodialbum)
else:
self.logMsg("Albums compare finished.", 1)
for kodisong in all_kodisongs:
if kodisong not in all_embysongsIds:
music.remove(kodisong)
else:
self.logMsg("Songs compare finished.", 1)
return True return True
# Reserved for websocket_client.py and fast start # Reserved for websocket_client.py and fast start
@ -1368,3 +1239,475 @@ class LibrarySync(threading.Thread):
def resumeThread(self): def resumeThread(self):
self.suspend_thread = False self.suspend_thread = False
self.logMsg("Resuming thread...", 0) self.logMsg("Resuming thread...", 0)
class ManualSync(LibrarySync):
def __init__(self):
LibrarySync.__init__(self)
self.fullSync(manualrun=True)
def movies(self, embycursor, kodicursor, pdialog):
# Get movies from emby
emby = self.emby
emby_db = embydb.Embydb_Functions(embycursor)
movies = itemtypes.Movies(embycursor, kodicursor)
views = emby_db.getView_byType('movies')
views += emby_db.getView_byType('mixed')
self.logMsg("Media folders: %s" % views, 1)
# Pull the list of movies and boxsets in Kodi
try:
all_kodimovies = dict(emby_db.getChecksum('Movie'))
except ValueError:
all_kodimovies = {}
try:
all_kodisets = dict(emby_db.getChecksum('BoxSet'))
except ValueError:
all_kodisets = {}
all_embymoviesIds = set()
all_embyboxsetsIds = set()
updatelist = []
##### PROCESS MOVIES #####
for view in views:
if self.shouldStop():
return False
# Get items per view
viewId = view['id']
viewName = view['name']
if pdialog:
pdialog.update(
heading="Emby for Kodi",
message="Comparing movies from view: %s..." % viewName)
all_embymovies = emby.getMovies(viewId, basic=True, dialog=pdialog)
for embymovie in all_embymovies['Items']:
if self.shouldStop():
return False
API = api.API(embymovie)
itemid = embymovie['Id']
all_embymoviesIds.add(itemid)
if all_kodimovies.get(itemid) != API.getChecksum():
# Only update if movie is not in Kodi or checksum is different
updatelist.append(itemid)
self.logMsg("Movies to update for %s: %s" % (viewName, updatelist), 1)
embymovies = emby.getFullItems(updatelist)
total = len(updatelist)
del updatelist[:]
if pdialog:
pdialog.update(heading="Processing %s / %s items" % (viewName, total))
count = 0
for embymovie in embymovies:
# Process individual movies
if self.shouldStop():
return False
title = embymovie['Name']
if pdialog:
percentage = int((float(count) / float(total))*100)
pdialog.update(percentage, message=title)
count += 1
movies.add_update(embymovie, viewName, viewId)
##### PROCESS BOXSETS #####
boxsets = emby.getBoxset(dialog=pdialog)
embyboxsets = []
if pdialog:
pdialog.update(
heading="Emby for Kodi",
message="Comparing boxsets...")
for boxset in boxsets['Items']:
if self.shouldStop():
return False
# Boxset has no real userdata, so using etag to compare
checksum = boxset['Etag']
itemid = boxset['Id']
all_embyboxsetsIds.add(itemid)
if all_kodisets.get(itemid) != checksum:
# Only update if boxset is not in Kodi or checksum is different
updatelist.append(itemid)
embyboxsets.append(boxset)
self.logMsg("Boxsets to update: %s" % updatelist, 1)
total = len(updatelist)
if pdialog:
pdialog.update(heading="Processing Boxsets / %s items" % total)
count = 0
for boxset in embyboxsets:
# Process individual boxset
if self.shouldStop():
return False
title = boxset['Name']
if pdialog:
percentage = int((float(count) / float(total))*100)
pdialog.update(percentage, message=title)
count += 1
movies.add_updateBoxset(boxset)
##### PROCESS DELETES #####
for kodimovie in all_kodimovies:
if kodimovie not in all_embymoviesIds:
movies.remove(kodimovie)
else:
self.logMsg("Movies compare finished.", 1)
for boxset in all_kodisets:
if boxset not in all_embyboxsetsIds:
movies.remove(boxset)
else:
self.logMsg("Boxsets compare finished.", 1)
return True
def musicvideos(self, embycursor, kodicursor, pdialog):
# Get musicvideos from emby
emby = self.emby
emby_db = embydb.Embydb_Functions(embycursor)
mvideos = itemtypes.MusicVideos(embycursor, kodicursor)
views = emby_db.getView_byType('musicvideos')
self.logMsg("Media folders: %s" % views, 1)
# Pull the list of musicvideos in Kodi
try:
all_kodimvideos = dict(emby_db.getChecksum('MusicVideo'))
except ValueError:
all_kodimvideos = {}
all_embymvideosIds = set()
updatelist = []
for view in views:
if self.shouldStop():
return False
# Get items per view
viewId = view['id']
viewName = view['name']
if pdialog:
pdialog.update(
heading="Emby for Kodi",
message="Comparing musicvideos from view: %s..." % viewName)
all_embymvideos = emby.getMusicVideos(viewId, basic=True, dialog=pdialog)
for embymvideo in all_embymvideos['Items']:
if self.shouldStop():
return False
API = api.API(embymvideo)
itemid = embymvideo['Id']
all_embymvideosIds.add(itemid)
if all_kodimvideos.get(itemid) != API.getChecksum():
# Only update if musicvideo is not in Kodi or checksum is different
updatelist.append(itemid)
self.logMsg("MusicVideos to update for %s: %s" % (viewName, updatelist), 1)
embymvideos = emby.getFullItems(updatelist)
total = len(updatelist)
del updatelist[:]
if pdialog:
pdialog.update(heading="Processing %s / %s items" % (viewName, total))
count = 0
for embymvideo in embymvideos:
# Process individual musicvideo
if self.shouldStop():
return False
title = embymvideo['Name']
if pdialog:
percentage = int((float(count) / float(total))*100)
pdialog.update(percentage, message=title)
count += 1
mvideos.add_update(embymvideo, viewName, viewId)
##### PROCESS DELETES #####
for kodimvideo in all_kodimvideos:
if kodimvideo not in all_embymvideosIds:
mvideos.remove(kodimvideo)
else:
self.logMsg("MusicVideos compare finished.", 1)
return True
def tvshows(self, embycursor, kodicursor, pdialog):
# Get shows from emby
emby = self.emby
emby_db = embydb.Embydb_Functions(embycursor)
tvshows = itemtypes.TVShows(embycursor, kodicursor)
views = emby_db.getView_byType('tvshows')
views += emby_db.getView_byType('mixed')
self.logMsg("Media folders: %s" % views, 1)
# Pull the list of tvshows and episodes in Kodi
try:
all_koditvshows = dict(emby_db.getChecksum('Series'))
except ValueError:
all_koditvshows = {}
try:
all_kodiepisodes = dict(emby_db.getChecksum('Episode'))
except ValueError:
all_kodiepisodes = {}
all_embytvshowsIds = set()
all_embyepisodesIds = set()
updatelist = []
for view in views:
if self.shouldStop():
return False
# Get items per view
viewId = view['id']
viewName = view['name']
if pdialog:
pdialog.update(
heading="Emby for Kodi",
message="Comparing tvshows from view: %s..." % viewName)
all_embytvshows = emby.getShows(viewId, basic=True, dialog=pdialog)
for embytvshow in all_embytvshows['Items']:
if self.shouldStop():
return False
API = api.API(embytvshow)
itemid = embytvshow['Id']
all_embytvshowsIds.add(itemid)
if all_koditvshows.get(itemid) != API.getChecksum():
# Only update if movie is not in Kodi or checksum is different
updatelist.append(itemid)
self.logMsg("TVShows to update for %s: %s" % (viewName, updatelist), 1)
embytvshows = emby.getFullItems(updatelist)
total = len(updatelist)
del updatelist[:]
if pdialog:
pdialog.update(heading="Processing %s / %s items" % (viewName, total))
count = 0
for embytvshow in embytvshows:
# Process individual show
if self.shouldStop():
return False
itemid = embytvshow['Id']
title = embytvshow['Name']
if pdialog:
percentage = int((float(count) / float(total))*100)
pdialog.update(percentage, message=title)
count += 1
tvshows.add_update(embytvshow, viewName, viewId)
else:
# Get all episodes in view
if pdialog:
pdialog.update(
heading="Emby for Kodi",
message="Comparing episodes from view: %s..." % viewName)
all_embyepisodes = emby.getEpisodes(viewId, basic=True, dialog=pdialog)
for embyepisode in all_embyepisodes['Items']:
if self.shouldStop():
return False
API = api.API(embyepisode)
itemid = embyepisode['Id']
all_embyepisodesIds.add(itemid)
if all_kodiepisodes.get(itemid) != API.getChecksum():
# Only update if movie is not in Kodi or checksum is different
updatelist.append(itemid)
self.logMsg("Episodes to update for %s: %s" % (viewName, updatelist), 1)
embyepisodes = emby.getFullItems(updatelist)
total = len(updatelist)
del updatelist[:]
count = 0
for episode in embyepisodes:
# Process individual episode
if self.shouldStop():
return False
title = episode['SeriesName']
episodetitle = episode['Name']
if pdialog:
percentage = int((float(count) / float(total))*100)
pdialog.update(percentage, message="%s - %s" % (title, episodetitle))
count += 1
tvshows.add_updateEpisode(episode)
##### PROCESS DELETES #####
for koditvshow in all_koditvshows:
if koditvshow not in all_embytvshowsIds:
tvshows.remove(koditvshow)
else:
self.logMsg("TVShows compare finished.", 1)
for kodiepisode in all_kodiepisodes:
if kodiepisode not in all_embyepisodesIds:
tvshows.remove(kodiepisode)
else:
self.logMsg("Episodes compare finished.", 1)
return True
def music(self, embycursor, kodicursor, pdialog):
# Get music from emby
emby = self.emby
emby_db = embydb.Embydb_Functions(embycursor)
music = itemtypes.Music(embycursor, kodicursor)
# Pull the list of artists, albums, songs
try:
all_kodiartists = dict(emby_db.getChecksum('MusicArtist'))
except ValueError:
all_kodiartists = {}
try:
all_kodialbums = dict(emby_db.getChecksum('MusicAlbum'))
except ValueError:
all_kodialbums = {}
try:
all_kodisongs = dict(emby_db.getChecksum('Audio'))
except ValueError:
all_kodisongs = {}
all_embyartistsIds = set()
all_embyalbumsIds = set()
all_embysongsIds = set()
updatelist = []
process = {
'artists': [emby.getArtists, music.add_updateArtist],
'albums': [emby.getAlbums, music.add_updateAlbum],
'songs': [emby.getSongs, music.add_updateSong]
}
types = ['artists', 'albums', 'songs']
for type in types:
if pdialog:
pdialog.update(
heading="Emby for Kodi",
message="Comparing %s..." % type)
if type != "artists":
all_embyitems = process[type][0](basic=True, dialog=pdialog)
else:
all_embyitems = process[type][0](dialog=pdialog)
for embyitem in all_embyitems['Items']:
if self.shouldStop():
return False
API = api.API(embyitem)
itemid = embyitem['Id']
if type == "artists":
all_embyartistsIds.add(itemid)
if all_kodiartists.get(itemid) != API.getChecksum():
# Only update if artist is not in Kodi or checksum is different
updatelist.append(itemid)
elif type == "albums":
all_embyalbumsIds.add(itemid)
if all_kodialbums.get(itemid) != API.getChecksum():
# Only update if album is not in Kodi or checksum is different
updatelist.append(itemid)
else:
all_embysongsIds.add(itemid)
if all_kodisongs.get(itemid) != API.getChecksum():
# Only update if songs is not in Kodi or checksum is different
updatelist.append(itemid)
self.logMsg("%s to update: %s" % (type, updatelist), 1)
embyitems = emby.getFullItems(updatelist)
total = len(updatelist)
del updatelist[:]
if pdialog:
pdialog.update(heading="Processing %s / %s items" % (type, total))
count = 0
for embyitem in embyitems:
# Process individual item
if self.shouldStop():
return False
title = embyitem['Name']
if pdialog:
percentage = int((float(count) / float(total))*100)
pdialog.update(percentage, message=title)
count += 1
process[type][1](embyitem)
##### PROCESS DELETES #####
for kodiartist in all_kodiartists:
if kodiartist not in all_embyartistsIds and all_kodiartists[kodiartist] is not None:
music.remove(kodiartist)
else:
self.logMsg("Artist compare finished.", 1)
for kodialbum in all_kodialbums:
if kodialbum not in all_embyalbumsIds:
music.remove(kodialbum)
else:
self.logMsg("Albums compare finished.", 1)
for kodisong in all_kodisongs:
if kodisong not in all_embysongsIds:
music.remove(kodisong)
else:
self.logMsg("Songs compare finished.", 1)
return True

View file

@ -74,17 +74,17 @@ def window(property, value=None, clear=False, windowid=10000):
WINDOW = xbmcgui.Window(windowid) WINDOW = xbmcgui.Window(windowid)
#setproperty accepts both string and unicode but utf-8 strings are adviced by kodi devs because some unicode can give issues #setproperty accepts both string and unicode but utf-8 strings are adviced by kodi devs because some unicode can give issues
if isinstance(property, unicode): '''if isinstance(property, unicode):
property = property.encode("utf-8") property = property.encode("utf-8")
if isinstance(value, unicode): if isinstance(value, unicode):
value = value.encode("utf-8") value = value.encode("utf-8")'''
if clear: if clear:
WINDOW.clearProperty(property) WINDOW.clearProperty(property)
elif value is not None: elif value is not None:
WINDOW.setProperty(property, value) WINDOW.setProperty(property, value)
else: #getproperty returns string so convert to unicode else: #getproperty returns string so convert to unicode
return WINDOW.getProperty(property).decode("utf-8") return WINDOW.getProperty(property)#.decode("utf-8")
def settings(setting, value=None): def settings(setting, value=None):
# Get or add addon setting # Get or add addon setting
@ -170,15 +170,7 @@ def reset():
deletePlaylists() deletePlaylists()
# Clean up the video nodes # Clean up the video nodes
import shutil deleteNodes()
path = xbmc.translatePath("special://profile/library/video/").decode('utf-8')
dirs, files = xbmcvfs.listdir(path)
for dir in dirs:
if dir.decode('utf-8').startswith('Emby'):
shutil.rmtree("%s%s" % (path, dir.decode('utf-8')))
for file in files:
if file.decode('utf-8').startswith('emby'):
xbmcvfs.delete("%s%s" % (path, file.decode('utf-8')))
# Wipe the kodi databases # Wipe the kodi databases
logMsg("EMBY", "Resetting the Kodi video database.") logMsg("EMBY", "Resetting the Kodi video database.")
@ -532,4 +524,17 @@ def deletePlaylists():
dirs, files = xbmcvfs.listdir(path) dirs, files = xbmcvfs.listdir(path)
for file in files: for file in files:
if file.decode('utf-8').startswith('Emby'): if file.decode('utf-8').startswith('Emby'):
xbmcvfs.delete("%s%s" % (path, file)) xbmcvfs.delete("%s%s" % (path, file))
def deleteNodes():
# Clean up video nodes
import shutil
path = xbmc.translatePath("special://profile/library/video/").decode('utf-8')
dirs, files = xbmcvfs.listdir(path)
for dir in dirs:
if dir.decode('utf-8').startswith('Emby'):
shutil.rmtree("%s%s" % (path, dir.decode('utf-8')))
for file in files:
if file.decode('utf-8').startswith('emby'):
xbmcvfs.delete("%s%s" % (path, file.decode('utf-8')))