Merge remote-tracking branch 'MediaBrowser/master' into develop
This commit is contained in:
commit
c98e7ad60c
7 changed files with 526 additions and 170 deletions
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<addon id="plugin.video.plexkodiconnect"
|
||||
name="PlexKodiConnect"
|
||||
version="1.1.79"
|
||||
version="1.1.80"
|
||||
provider-name="croneter">
|
||||
<requires>
|
||||
<import addon="xbmc.python" version="2.1.0"/>
|
||||
|
|
|
@ -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
|
||||
- Add music rating system
|
||||
- Add home videos as a dynamic plugin entry (requires a reset)
|
||||
|
|
|
@ -106,7 +106,7 @@ class Main:
|
|||
import librarysync
|
||||
lib = librarysync.LibrarySync()
|
||||
if mode == "manualsync":
|
||||
lib.fullSync(manualrun=True)
|
||||
librarysync.ManualSync()
|
||||
else:
|
||||
lib.fullSync(repair=True)
|
||||
else:
|
||||
|
|
|
@ -112,15 +112,15 @@ def doMainListing():
|
|||
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
|
||||
addDirectoryItem("Network credentials", "plugin://plugin.video.plexkodiconnect/?mode=passwords")
|
||||
addDirectoryItem("Settings", "plugin://plugin.video.plexkodiconnect/?mode=settings")
|
||||
addDirectoryItem("Add user to session", "plugin://plugin.video.plexkodiconnect/?mode=adduser")
|
||||
addDirectoryItem("Refresh Emby playlists", "plugin://plugin.video.plexkodiconnect/?mode=refreshplaylist")
|
||||
addDirectoryItem("Perform manual sync", "plugin://plugin.video.plexkodiconnect/?mode=manualsync")
|
||||
addDirectoryItem("Repair local database (force update all content)", "plugin://plugin.video.plexkodiconnect/?mode=repair")
|
||||
addDirectoryItem("Perform local database reset (full resync)", "plugin://plugin.video.plexkodiconnect/?mode=reset")
|
||||
addDirectoryItem("Cache all images to Kodi texture cache", "plugin://plugin.video.plexkodiconnect/?mode=texturecache")
|
||||
addDirectoryItem("Sync Emby Theme Media to Kodi", "plugin://plugin.video.plexkodiconnect/?mode=thememedia")
|
||||
addDirectoryItem("Network credentials", "plugin://plugin.video.emby/?mode=passwords")
|
||||
addDirectoryItem("Settings", "plugin://plugin.video.emby/?mode=settings")
|
||||
addDirectoryItem("Add user to session", "plugin://plugin.video.emby/?mode=adduser")
|
||||
addDirectoryItem("Refresh Emby playlists/nodes", "plugin://plugin.video.emby/?mode=refreshplaylist")
|
||||
addDirectoryItem("Perform manual sync", "plugin://plugin.video.emby/?mode=manualsync")
|
||||
addDirectoryItem("Repair local database (force update all content)", "plugin://plugin.video.emby/?mode=repair")
|
||||
addDirectoryItem("Perform local database reset (full resync)", "plugin://plugin.video.emby/?mode=reset")
|
||||
addDirectoryItem("Cache all images to Kodi texture cache", "plugin://plugin.video.emby/?mode=texturecache")
|
||||
addDirectoryItem("Sync Emby Theme Media to Kodi", "plugin://plugin.video.emby/?mode=thememedia")
|
||||
|
||||
xbmcplugin.endOfDirectory(int(sys.argv[1]))
|
||||
|
||||
|
@ -412,19 +412,22 @@ def refreshPlaylist():
|
|||
try:
|
||||
# First remove playlists
|
||||
utils.deletePlaylists()
|
||||
# Remove video nodes
|
||||
utils.deleteNodes()
|
||||
# Refresh views
|
||||
lib.refreshViews()
|
||||
dialog.notification(
|
||||
heading="Emby for Kodi",
|
||||
message="Emby playlist refreshed",
|
||||
message="Emby playlists/nodes refreshed",
|
||||
icon="special://home/addons/plugin.video.plexkodiconnect/icon.png",
|
||||
time=1000,
|
||||
sound=False)
|
||||
|
||||
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(
|
||||
heading="Emby for Kodi",
|
||||
message="Emby playlist refresh failed",
|
||||
message="Emby playlists/nodes refresh failed",
|
||||
icon=xbmcgui.NOTIFICATION_ERROR,
|
||||
time=1000,
|
||||
sound=False)
|
||||
|
|
|
@ -1833,6 +1833,7 @@ class Music(Items):
|
|||
track = disc*2**16 + tracknumber
|
||||
year = item.get('ProductionYear')
|
||||
duration = API.getRuntime()
|
||||
rating = userdata['UserRating']
|
||||
|
||||
#if enabled, try to get the rating from file and/or emby
|
||||
if not self.directstream:
|
||||
|
@ -1840,7 +1841,6 @@ class Music(Items):
|
|||
else:
|
||||
hasEmbeddedCover = False
|
||||
comment = API.getOverview()
|
||||
rating = userdata['UserRating']
|
||||
|
||||
|
||||
##### GET THE FILE AND PATH #####
|
||||
|
|
|
@ -403,9 +403,9 @@ class LibrarySync(threading.Thread):
|
|||
# musicconn = utils.kodiSQL('music')
|
||||
# musiccursor = musicconn.cursor()
|
||||
|
||||
# startTime = datetime.now()
|
||||
# completed = self.music(embycursor, musiccursor, pDialog, compare=manualrun)
|
||||
# if not completed:
|
||||
# startTime = datetime.now()
|
||||
# completed = self.music(embycursor, musiccursor, pDialog)
|
||||
# if not completed:
|
||||
|
||||
# utils.window('emby_dbScan', clear=True)
|
||||
|
||||
|
@ -428,6 +428,7 @@ class LibrarySync(threading.Thread):
|
|||
elapsedtotal = datetime.now() - starttotal
|
||||
|
||||
utils.window('emby_dbScan', clear=True)
|
||||
utils.window('emby_initialScan', clear=True)
|
||||
xbmcgui.Dialog().notification(
|
||||
heading=self.addonName,
|
||||
message="%s completed in: %s" %
|
||||
|
@ -778,7 +779,6 @@ class LibrarySync(threading.Thread):
|
|||
"""
|
||||
Updates ALL plex elements' view status ('watched' or 'unwatched') and
|
||||
also updates resume times.
|
||||
|
||||
This is done by downloading one XML for ALL elements with viewId
|
||||
"""
|
||||
starttotal = datetime.now()
|
||||
|
@ -795,7 +795,7 @@ class LibrarySync(threading.Thread):
|
|||
self.logMsg("Syncing userdata for itemtype %s and viewid %s took "
|
||||
"%s seconds" % (itemType, viewId, elapsedtotal), 0)
|
||||
|
||||
def musicvideos(self, embycursor, kodicursor, pdialog, compare=False):
|
||||
def musicvideos(self, embycursor, kodicursor, pdialog):
|
||||
# Get musicvideos from emby
|
||||
emby = self.emby
|
||||
emby_db = embydb.Embydb_Functions(embycursor)
|
||||
|
@ -804,16 +804,6 @@ class LibrarySync(threading.Thread):
|
|||
views = emby_db.getView_byType('musicvideos')
|
||||
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:
|
||||
|
||||
if self.shouldStop():
|
||||
|
@ -828,38 +818,10 @@ class LibrarySync(threading.Thread):
|
|||
heading="Emby for Kodi",
|
||||
message="Gathering musicvideos from view: %s..." % viewName)
|
||||
|
||||
if compare:
|
||||
# Manual sync
|
||||
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[:]
|
||||
else:
|
||||
# Initial or repair sync
|
||||
all_embymvideos = emby.getMusicVideos(viewId, dialog=pdialog)
|
||||
total = all_embymvideos['TotalRecordCount']
|
||||
embymvideos = all_embymvideos['Items']
|
||||
|
||||
# Initial or repair sync
|
||||
all_embymvideos = emby.getMusicVideos(viewId, dialog=pdialog)
|
||||
total = all_embymvideos['TotalRecordCount']
|
||||
embymvideos = all_embymvideos['Items']
|
||||
|
||||
if pdialog:
|
||||
pdialog.update(heading="Processing %s / %s items" % (viewName, total))
|
||||
|
@ -879,15 +841,6 @@ class LibrarySync(threading.Thread):
|
|||
else:
|
||||
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
|
||||
|
||||
def PlexTVShows(self):
|
||||
|
@ -993,7 +946,6 @@ class LibrarySync(threading.Thread):
|
|||
for view in views:
|
||||
self.PlexUpdateWatched(view['id'], itemType)
|
||||
|
||||
##### PROCESS DELETES #####
|
||||
if self.compare:
|
||||
# Manual sync, process deletes
|
||||
with itemtypes.TVShows() as TVShow:
|
||||
|
@ -1003,34 +955,12 @@ class LibrarySync(threading.Thread):
|
|||
self.logMsg("%s sync is finished." % itemType, 1)
|
||||
return True
|
||||
|
||||
def music(self, embycursor, kodicursor, pdialog, compare=False):
|
||||
def music(self, embycursor, kodicursor, pdialog):
|
||||
# Get music from emby
|
||||
emby = self.emby
|
||||
emby_db = embydb.Embydb_Functions(embycursor)
|
||||
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 = {
|
||||
|
||||
'artists': [emby.getArtists, music.add_updateArtist],
|
||||
|
@ -1041,47 +971,9 @@ class LibrarySync(threading.Thread):
|
|||
for type in types:
|
||||
|
||||
if pdialog:
|
||||
pass
|
||||
if compare:
|
||||
# Manual Sync
|
||||
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']
|
||||
all_embyitems = process[type][0](dialog=pdialog)
|
||||
total = all_embyitems['TotalRecordCount']
|
||||
embyitems = all_embyitems['Items']
|
||||
|
||||
if pdialog:
|
||||
pass
|
||||
|
@ -1102,27 +994,6 @@ class LibrarySync(threading.Thread):
|
|||
else:
|
||||
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
|
||||
|
||||
# Reserved for websocket_client.py and fast start
|
||||
|
@ -1368,3 +1239,475 @@ class LibrarySync(threading.Thread):
|
|||
def resumeThread(self):
|
||||
self.suspend_thread = False
|
||||
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
|
|
@ -74,17 +74,17 @@ def window(property, value=None, clear=False, windowid=10000):
|
|||
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
|
||||
if isinstance(property, unicode):
|
||||
'''if isinstance(property, unicode):
|
||||
property = property.encode("utf-8")
|
||||
if isinstance(value, unicode):
|
||||
value = value.encode("utf-8")
|
||||
value = value.encode("utf-8")'''
|
||||
|
||||
if clear:
|
||||
WINDOW.clearProperty(property)
|
||||
elif value is not None:
|
||||
WINDOW.setProperty(property, value)
|
||||
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):
|
||||
# Get or add addon setting
|
||||
|
@ -170,15 +170,7 @@ def reset():
|
|||
deletePlaylists()
|
||||
|
||||
# Clean up the 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')))
|
||||
deleteNodes()
|
||||
|
||||
# Wipe the kodi databases
|
||||
logMsg("EMBY", "Resetting the Kodi video database.")
|
||||
|
@ -533,3 +525,16 @@ def deletePlaylists():
|
|||
for file in files:
|
||||
if file.decode('utf-8').startswith('Emby'):
|
||||
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')))
|
Loading…
Reference in a new issue