diff --git a/resources/lib/entrypoint/default.py b/resources/lib/entrypoint/default.py index 64e551da..f4ab6869 100644 --- a/resources/lib/entrypoint/default.py +++ b/resources/lib/entrypoint/default.py @@ -123,6 +123,7 @@ def listing(): ''' total = int(window('Emby.nodes.total') or 0) sync = get_sync() + whitelist = [x.replace('Mixed:', "") for x in sync['Whitelist']] servers = get_credentials()['Servers'][1:] for i in range(total): @@ -139,11 +140,10 @@ def listing(): view_id = window('%s.id' % window_prop) context = [] - if view_id and node in ('movies', 'tvshows', 'musicvideos', 'music') and view_id not in sync['Whitelist']: - + if view_id and node in ('movies', 'tvshows', 'musicvideos', 'music') and view_id not in whitelist: context.append((_(33123), "RunPlugin(plugin://plugin.video.emby?mode=synclib&id=%s)" % view_id)) - if view_id and node in ('movies', 'tvshows', 'musicvideos', 'music') and view_id in sync['Whitelist']: + if view_id and node in ('movies', 'tvshows', 'musicvideos', 'music') and view_id in whitelist: context.append((_(33136), "RunPlugin(plugin://plugin.video.emby?mode=synclib&id=%s)" % view_id)) context.append((_(33132), "RunPlugin(plugin://plugin.video.emby?mode=repairlib&id=%s)" % view_id)) diff --git a/resources/lib/entrypoint/service.py b/resources/lib/entrypoint/service.py index 4ac5a78d..5eb193b8 100644 --- a/resources/lib/entrypoint/service.py +++ b/resources/lib/entrypoint/service.py @@ -139,7 +139,7 @@ class Service(xbmc.Monitor): url = "https://sheets.googleapis.com/v4/spreadsheets/1cKWQCVL0lVONulO2KyGzBilzhGvsyuSjFvrqe8g6nJw/values/A2:B?key=AIzaSyAP-1mcBglk9zIofJlqGpvKXkff3GRMhdI" try: - versions = {k.lower(): v for k, v in dict(requests.get(url, verify=False).json()['values']).items()} + versions = {k.lower(): v for k, v in dict(requests.get(url).json()['values']).items()} build = find(versions, kodi.lower()) if not build: @@ -284,11 +284,7 @@ class Service(xbmc.Monitor): if not data.get('Id'): return - libraries = data['Id'].split(',') - - for lib in libraries: - self.library_thread.add_library(lib) - + self.library_thread.add_library(data['Id']) xbmc.executebuiltin("Container.Refresh") elif method == 'RepairLibrary': @@ -299,8 +295,8 @@ class Service(xbmc.Monitor): for lib in libraries: self.library_thread.remove_library(lib) - self.library_thread.add_library(lib) - + + self.library_thread.add_library(data['Id']) xbmc.executebuiltin("Container.Refresh") elif method == 'RemoveLibrary': @@ -398,7 +394,7 @@ class Service(xbmc.Monitor): "emby_state", "emby_serverStatus", "emby_syncRunning", "emby_dbCheck", "emby_currUser", "emby_dbScan", - "emby_initialScan", "emby_playbackProps", + "emby_initialScan", "emby_play", "emby_online", "emby.connected", "emby_should_stop", "emby.resume", "emby.external", "emby.external_check" diff --git a/resources/lib/full_sync.py b/resources/lib/full_sync.py index f3735e60..b19cb228 100644 --- a/resources/lib/full_sync.py +++ b/resources/lib/full_sync.py @@ -12,7 +12,7 @@ import xbmcvfs import downloader as server import helper.xmls as xmls -from database import Database, get_sync, save_sync +from database import Database, get_sync, save_sync, emby_db from objects import Movies, TVShows, MusicVideos, Music from helper import _, settings, progress, dialog, LibraryException from emby import Emby @@ -37,7 +37,16 @@ class FullSync(object): self.sync = get_sync() if library_id: - self.sync['Libraries'].append(library_id) + libraries = library_id.split(',') + + for selected in libraries: + if selected not in [x.replace('Mixed:', "") for x in self.sync['Whitelist']]: + library = self.get_libraries(selected) + + if library[1] == 'mixed': + selected = "Mixed:%s" % selected + + self.sync['Libraries'].append(selected) else: self.mapping() @@ -45,6 +54,14 @@ class FullSync(object): if not xmls.advanced_settings(): self.start() + def get_libraries(self, library_id=None): + + with Database('emby') as embydb: + if library_id is None: + return emby_db.EmbyDatabase(embydb.cursor).get_views() + else: + return emby_db.EmbyDatabase(embydb.cursor).get_view(library_id) + def mapping(self): ''' Load the mapping of the full sync. @@ -61,13 +78,10 @@ class FullSync(object): LOG.info("generate full sync") libraries = [] - for library in self.server['api'].get_media_folders()['Items']: - library['Media'] = library.get('OriginalCollectionType', library.get('CollectionType', "mixed")) + for library in self.get_libraries(): - if library['Type'] in ('Channel', 'PlaylistsFolder') or library['Media'] not in ('movies', 'tvshows', 'musicvideos', 'music', 'mixed'): - continue - - libraries.append(library) + if library[2] in ('movies', 'tvshows', 'musicvideos', 'music', 'mixed'): + libraries.append({'Id': library[0], 'Name': library[1], 'Media': library[2]}) libraries = self.select_libraries(libraries) diff --git a/resources/lib/library.py b/resources/lib/library.py index 788839f9..dceabd2c 100644 --- a/resources/lib/library.py +++ b/resources/lib/library.py @@ -219,15 +219,18 @@ class Library(threading.Thread): FullSync(self) Views().get_nodes() - self.started = True return True except LibraryException as error: LOG.error(error.status) if error.status in 'SyncLibraryLater': + dialog("ok", heading="{emby}", line1=_(33129)) settings('SyncInstallRunDone.bool', True) + sync = get_sync() + sync['Libraries'] = [] + save_sync(sync) return True @@ -307,6 +310,7 @@ class Library(threading.Thread): 'AddLibrarySelection': 'SyncLibrary' } sync = get_sync() + whitelist = [x.replace('Mixed:', "") for x in sync['Whitelist']] libraries = [] with Database('emby') as embydb: @@ -318,7 +322,7 @@ class Library(threading.Thread): name = db.get_view_name(library.replace('Mixed:', "")) libraries.append({'Id': library, 'Name': name}) else: - available = [x for x in sync['SortedViews'] if x not in [y.replace('Mixed:', "") for y in sync['Whitelist']]] + available = [x for x in sync['SortedViews'] if x not in whitelist] for library in available: name, media = db.get_view(library) @@ -372,10 +376,25 @@ class Library(threading.Thread): if items: with self.music_database_lock if media == 'music' else self.database_lock: with Database(media) as kodidb: - obj = MEDIA[items[0][1]](self.server, embydb, kodidb, self.direct_path)['Remove'] - for item in items: - obj(item[0]) + if library[1] == 'mixed': + movies = [x for x in items if x[1] == 'Movie'] + tvshows = [x for x in items if x[1] == 'Series'] + + obj = MEDIA['Movie'](self.server, embydb, kodidb, self.direct_path)['Remove'] + + for item in movies: + obj(item[0]) + + obj = MEDIA['Series'](self.server, embydb, kodidb, self.direct_path)['Remove'] + + for item in tvshows: + obj(item[0]) + else: + obj = MEDIA[items[0][1]](self.server, embydb, kodidb, self.direct_path)['Remove'] + + for item in items: + obj(item[0]) sync = get_sync() diff --git a/resources/lib/views.py b/resources/lib/views.py index 3806cf4c..d00c9765 100644 --- a/resources/lib/views.py +++ b/resources/lib/views.py @@ -619,36 +619,53 @@ class Views(object): Setup the window properties that reflect the emby server views and more. ''' self.window_clear() + self.window_clear('Emby.wnodes') with Database('emby') as embydb: libraries = emby_db.EmbyDatabase(embydb.cursor).get_views() libraries = self.order_media_folders(libraries or []) index = 0 + windex = 0 for library in (libraries or []): view = {'Id': library[0], 'Name': library[1], 'Tag': library[1], 'Media': library[2]} - if library[0] in self.sync['Whitelist']: # Synced libraries + if library[0] in [x.replace('Mixed:', "") for x in self.sync['Whitelist']]: # Synced libraries if view['Media'] in ('movies', 'tvshows', 'musicvideos', 'mixed'): - for node in NODES[view['Media']]: - if view['Media'] == 'mixed': - for media in ('movies', 'tvshows'): + if view['Media'] == 'mixed': + for media in ('movies', 'tvshows'): + + for node in NODES[media]: temp_view = dict(view) temp_view['Media'] = media temp_view['Name'] = "%s (%s)" % (view['Name'], _(media)) self.window_node(index, temp_view, *node) + self.window_wnode(windex, view, *node) else: # Add one to compensate for the duplicate. index += 1 - else: + windex += 1 + else: + for node in NODES[view['Media']]: + self.window_node(index, view, *node) + if view['Media'] in ('movies', 'tvshows'): + self.window_wnode(windex, view, *node) + + if view['Media'] in ('movies', 'tvshows'): + windex += 1 + elif view['Media'] == 'music': self.window_node(index, view, 'music') else: # Dynamic entry + if view['Media'] in ('homevideos', 'books', 'audiobooks'): + self.window_wnode(windex, view, 'browse') + windex += 1 + self.window_node(index, view, 'browse') index += 1 @@ -661,6 +678,8 @@ class Views(object): index += 1 window('Emby.nodes.total', str(index)) + LOG.info(windex) + window('Emby.wnodes.total', str(windex)) def window_node(self, index, view, node=None, node_label=None): @@ -688,16 +707,16 @@ class Views(object): window_prop = "Emby.nodes.%s" % index window('%s.index' % window_prop, path.replace('all.xml', "")) # dir - window('%s.title' % window_prop, view['Name']) + window('%s.title' % window_prop, view['Name'].encode('utf-8')) window('%s.content' % window_prop, path) elif node == 'browse': window_prop = "Emby.nodes.%s" % index - window('%s.title' % window_prop, view['Name']) + window('%s.title' % window_prop, view['Name'].encode('utf-8')) else: window_prop = "Emby.nodes.%s.%s" % (index, node) - window('%s.title' % window_prop, str(node_label) or view['Name']) + window('%s.title' % window_prop, str(node_label) or view['Name'].encode('utf-8')) window('%s.content' % window_prop, path) window('%s.id' % window_prop, view['Id']) @@ -722,6 +741,47 @@ class Views(object): window('%s.content' % window_prop, path) window('%s.type' % window_prop, item_type) + def window_wnode(self, index, view, node=None, node_label=None): + + ''' Similar to window_node, but does not contain music, musicvideos. + Contains books, audiobooks. + ''' + if view['Media'] in ('homevideos', 'photos'): + path = self.window_browse(view, None if node in ('all', 'browse') else node) + else: + path = self.window_path(view, node) + + if node in ('browse', 'homevideos', 'photos'): + window_path = path + else: + window_path = "ActivateWindow(Videos,%s,return)" % path + + if node == 'all': + + window_prop = "Emby.wnodes.%s" % index + window('%s.index' % window_prop, path.replace('all.xml', "")) # dir + window('%s.title' % window_prop, view['Name'].encode('utf-8')) + window('%s.content' % window_prop, path) + + elif node == 'browse': + + window_prop = "Emby.wnodes.%s" % index + window('%s.title' % window_prop, view['Name'].encode('utf-8')) + window('%s.content' % window_prop, path) + else: + window_prop = "Emby.wnodes.%s.%s" % (index, node) + window('%s.title' % window_prop, str(node_label) or view['Name'].encode('utf-8')) + window('%s.content' % window_prop, path) + + window('%s.id' % window_prop, view['Id']) + window('%s.path' % window_prop, window_path) + window('%s.type' % window_prop, view['Media']) + + if self.server['connected']: + + artwork = api.API(None, self.server['auth/server-address']).get_artwork(view['Id'], 'Primary') + window('%s.artwork' % window_prop, artwork) + def window_path(self, view, node): return "library://video/emby%s%s/%s.xml" % (view['Media'], view['Id'], node) @@ -752,11 +812,11 @@ class Views(object): return "%s?%s" % ("plugin://plugin.video.emby", urllib.urlencode(params)) - def window_clear(self): + def window_clear(self, name=None): ''' Clearing window prop setup for Views. ''' - total = int(window('Emby.nodes.total') or 0) + total = int(window((name or 'Emby.nodes') + '.total') or 0) props = [ "index","id","path","title","content","type"