mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2024-11-10 04:06:11 +00:00
Merge pull request #191 from angelblue05/develop
Refine full sync process
This commit is contained in:
commit
4a26225594
5 changed files with 162 additions and 110 deletions
|
@ -21,7 +21,6 @@ from database import reset, get_sync, Database, emby_db, get_credentials
|
|||
from objects import Objects, Actions
|
||||
from downloader import TheVoid
|
||||
from helper import _, event, settings, window, dialog, api, JSONRPC
|
||||
from emby import Emby
|
||||
|
||||
#################################################################################################
|
||||
|
||||
|
|
|
@ -361,7 +361,9 @@ class Service(xbmc.Monitor):
|
|||
libraries = data['Id'].split(',')
|
||||
|
||||
for lib in libraries:
|
||||
self.library_thread.remove_library(lib)
|
||||
|
||||
if not self.library_thread.remove_library(lib):
|
||||
return
|
||||
|
||||
self.library_thread.add_library(data['Id'])
|
||||
xbmc.executebuiltin("Container.Refresh")
|
||||
|
@ -370,7 +372,9 @@ class Service(xbmc.Monitor):
|
|||
libraries = data['Id'].split(',')
|
||||
|
||||
for lib in libraries:
|
||||
self.library_thread.remove_library(lib)
|
||||
|
||||
if not self.library_thread.remove_library(lib):
|
||||
return
|
||||
|
||||
xbmc.executebuiltin("Container.Refresh")
|
||||
|
||||
|
@ -473,8 +477,6 @@ class Service(xbmc.Monitor):
|
|||
''' Reload objects which depends on the patch module.
|
||||
This allows to see the changes in code without restarting the python interpreter.
|
||||
'''
|
||||
import full_sync
|
||||
|
||||
reload_modules = ['objects.movies', 'objects.musicvideos', 'objects.tvshows',
|
||||
'objects.music', 'objects.obj', 'objects.actions', 'objects.kodi.kodi',
|
||||
'objects.kodi.movies', 'objects.kodi.musicvideos', 'objects.kodi.tvshows',
|
||||
|
@ -487,7 +489,6 @@ class Service(xbmc.Monitor):
|
|||
reload(objects.kodi)
|
||||
reload(objects)
|
||||
reload(library)
|
||||
reload(full_sync)
|
||||
reload(monitor)
|
||||
|
||||
LOG.warn("---[ objects reloaded ]")
|
||||
|
|
|
@ -13,10 +13,9 @@ import xbmcvfs
|
|||
import downloader as server
|
||||
import helper.xmls as xmls
|
||||
from database import Database, get_sync, save_sync, emby_db
|
||||
from objects import Movies, TVShows, MusicVideos, Music
|
||||
from helper import _, settings, window, progress, dialog, LibraryException
|
||||
from helper.utils import get_screensaver, set_screensaver
|
||||
from emby import Emby
|
||||
from views import Views
|
||||
|
||||
##################################################################################################
|
||||
|
||||
|
@ -27,18 +26,37 @@ LOG = logging.getLogger("EMBY."+__name__)
|
|||
|
||||
class FullSync(object):
|
||||
|
||||
''' This should be called like a context.
|
||||
i.e. with FullSync('emby') as sync:
|
||||
sync.libraries()
|
||||
'''
|
||||
# Borg - multiple instances, shared state
|
||||
_shared_state = {}
|
||||
sync = None
|
||||
running = False
|
||||
screensaver = None
|
||||
|
||||
def __init__(self, library, library_id=None, update=False):
|
||||
|
||||
''' Map the syncing process and start the sync. Ensure only one sync is running.
|
||||
def __init__(self, library, server):
|
||||
|
||||
''' You can call all big syncing methods here.
|
||||
Initial, update, repair, remove.
|
||||
'''
|
||||
self.__dict__ = self._shared_state
|
||||
window('emby_sync.bool', True)
|
||||
|
||||
if self.running:
|
||||
dialog("ok", heading="{emby}", line1=_(33197))
|
||||
|
||||
raise Exception("Sync is already running.")
|
||||
|
||||
self.library = library
|
||||
self.server = server
|
||||
|
||||
def __enter__(self):
|
||||
|
||||
''' Do everything we need before the sync
|
||||
'''
|
||||
LOG.info("-->[ fullsync ]")
|
||||
|
||||
if not settings('dbSyncScreensaver.bool'):
|
||||
|
||||
|
@ -46,44 +64,43 @@ class FullSync(object):
|
|||
self.screensaver = get_screensaver()
|
||||
set_screensaver(value="")
|
||||
|
||||
if not self.running:
|
||||
self.running = True
|
||||
window('emby_sync.bool', True)
|
||||
|
||||
self.running = True
|
||||
self.library = library
|
||||
self.direct_path = settings('useDirectPaths') == "1"
|
||||
self.update_library = update
|
||||
self.server = Emby()
|
||||
self.sync = get_sync()
|
||||
return self
|
||||
|
||||
if library_id:
|
||||
libraries = library_id.split(',')
|
||||
|
||||
for selected in libraries:
|
||||
def libraries(self, library_id=None, update=False):
|
||||
|
||||
if selected not in [x.replace('Mixed:', "") for x in self.sync['Libraries']]:
|
||||
library = self.get_libraries(selected)
|
||||
''' Map the syncing process and start the sync. Ensure only one sync is running.
|
||||
'''
|
||||
self.direct_path = settings('useDirectPaths') == "1"
|
||||
self.update_library = update
|
||||
self.sync = get_sync()
|
||||
|
||||
if library:
|
||||
if library_id:
|
||||
libraries = library_id.split(',')
|
||||
|
||||
self.sync['Libraries'].append("Mixed:%s" % selected if library[1] == 'mixed' else selected)
|
||||
for selected in libraries:
|
||||
|
||||
if library[1] in ('mixed', 'movies'):
|
||||
self.sync['Libraries'].append('Boxsets:%s' % selected)
|
||||
else:
|
||||
self.sync['Libraries'].append(selected)
|
||||
else:
|
||||
self.mapping()
|
||||
if selected not in [x.replace('Mixed:', "") for x in self.sync['Libraries']]:
|
||||
library = self.get_libraries(selected)
|
||||
|
||||
xmls.sources()
|
||||
if library:
|
||||
|
||||
if not xmls.advanced_settings() and self.sync['Libraries']:
|
||||
self.start()
|
||||
else:
|
||||
self.running = False
|
||||
self.sync['Libraries'].append("Mixed:%s" % selected if library[1] == 'mixed' else selected)
|
||||
|
||||
if library[1] in ('mixed', 'movies'):
|
||||
self.sync['Libraries'].append('Boxsets:%s' % selected)
|
||||
else:
|
||||
self.sync['Libraries'].append(selected)
|
||||
else:
|
||||
dialog("ok", heading="{emby}", line1=_(33197))
|
||||
self.mapping()
|
||||
|
||||
raise Exception("Sync is already running.")
|
||||
xmls.sources()
|
||||
|
||||
if not xmls.advanced_settings() and self.sync['Libraries']:
|
||||
self.start()
|
||||
|
||||
def get_libraries(self, library_id=None):
|
||||
|
||||
|
@ -162,6 +179,7 @@ class FullSync(object):
|
|||
|
||||
return [libraries[x - 1] for x in selection]
|
||||
|
||||
|
||||
def start(self):
|
||||
|
||||
''' Main sync process.
|
||||
|
@ -239,24 +257,13 @@ class FullSync(object):
|
|||
|
||||
raise
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
|
||||
''' Exiting sync
|
||||
'''
|
||||
self.running = False
|
||||
window('emby_sync', clear=True)
|
||||
|
||||
if not settings('dbSyncScreensaver.bool'):
|
||||
|
||||
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
||||
set_screensaver(value=self.screensaver)
|
||||
|
||||
|
||||
@progress()
|
||||
def movies(self, library, dialog):
|
||||
|
||||
''' Process movies from a single library.
|
||||
'''
|
||||
Movies = self.library.media['Movies']
|
||||
|
||||
with self.library.database_lock:
|
||||
with Database() as videodb:
|
||||
with Database('emby') as embydb:
|
||||
|
@ -296,6 +303,8 @@ class FullSync(object):
|
|||
|
||||
''' Process tvshows and episodes from a single library.
|
||||
'''
|
||||
TVShows = self.library.media['TVShows']
|
||||
|
||||
with self.library.database_lock:
|
||||
with Database() as videodb:
|
||||
with Database('emby') as embydb:
|
||||
|
@ -344,6 +353,8 @@ class FullSync(object):
|
|||
|
||||
''' Process musicvideos from a single library.
|
||||
'''
|
||||
MusicVideos = self.library.media['MusicVideos']
|
||||
|
||||
with self.library.database_lock:
|
||||
with Database() as videodb:
|
||||
with Database('emby') as embydb:
|
||||
|
@ -382,6 +393,8 @@ class FullSync(object):
|
|||
|
||||
''' Process artists, album, songs from a single library.
|
||||
'''
|
||||
Music = self.library.media['Music']
|
||||
|
||||
with self.library.music_database_lock:
|
||||
with Database('music') as musicdb:
|
||||
with Database('emby') as embydb:
|
||||
|
@ -442,6 +455,8 @@ class FullSync(object):
|
|||
|
||||
''' Process all boxsets.
|
||||
'''
|
||||
Movies = self.library.media['Movies']
|
||||
|
||||
with self.library.database_lock:
|
||||
with Database() as videodb:
|
||||
with Database('emby') as embydb:
|
||||
|
@ -463,6 +478,8 @@ class FullSync(object):
|
|||
|
||||
''' Delete all exisitng boxsets and re-add.
|
||||
'''
|
||||
Movies = self.library.media['Movies']
|
||||
|
||||
with self.library.database_lock:
|
||||
with Database() as videodb:
|
||||
with Database('emby') as embydb:
|
||||
|
@ -471,3 +488,81 @@ class FullSync(object):
|
|||
obj.boxsets_reset()
|
||||
|
||||
self.boxsets(None)
|
||||
|
||||
@progress(_(33144))
|
||||
def remove_library(self, library_id, dialog):
|
||||
|
||||
''' Remove library by their id from the Kodi database.
|
||||
'''
|
||||
MEDIA = self.library.MEDIA
|
||||
direct_path = self.library.direct_path
|
||||
|
||||
with Database('emby') as embydb:
|
||||
|
||||
db = emby_db.EmbyDatabase(embydb.cursor)
|
||||
library = db.get_view(library_id.replace('Mixed:', ""))
|
||||
items = db.get_item_by_media_folder(library_id.replace('Mixed:', ""))
|
||||
media = 'music' if library[1] == 'music' else 'video'
|
||||
|
||||
if media == 'music':
|
||||
settings('MusicRescan.bool', False)
|
||||
|
||||
if items:
|
||||
count = 0
|
||||
|
||||
with self.library.music_database_lock if media == 'music' else self.library.database_lock:
|
||||
with Database(media) as kodidb:
|
||||
|
||||
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, direct_path)['Remove']
|
||||
|
||||
for item in movies:
|
||||
|
||||
obj(item[0])
|
||||
dialog.update(int((float(count) / float(len(items))*100)), heading="%s: %s" % (_('addon_name'), library[0]))
|
||||
count += 1
|
||||
|
||||
obj = MEDIA['Series'](self.server, embydb, kodidb, direct_path)['Remove']
|
||||
|
||||
for item in tvshows:
|
||||
|
||||
obj(item[0])
|
||||
dialog.update(int((float(count) / float(len(items))*100)), heading="%s: %s" % (_('addon_name'), library[0]))
|
||||
count += 1
|
||||
else:
|
||||
obj = MEDIA[items[0][1]](self.server, embydb, kodidb, direct_path)['Remove']
|
||||
|
||||
for item in items:
|
||||
|
||||
obj(item[0])
|
||||
dialog.update(int((float(count) / float(len(items))*100)), heading="%s: %s" % (_('addon_name'), library[0]))
|
||||
count += 1
|
||||
|
||||
self.sync = get_sync()
|
||||
|
||||
if library_id in self.sync['Whitelist']:
|
||||
self.sync['Whitelist'].remove(library_id)
|
||||
|
||||
elif 'Mixed:%s' % library_id in self.sync['Whitelist']:
|
||||
self.sync['Whitelist'].remove('Mixed:%s' % library_id)
|
||||
|
||||
save_sync(self.sync)
|
||||
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
|
||||
''' Exiting sync
|
||||
'''
|
||||
self.running = False
|
||||
window('emby_sync', clear=True)
|
||||
|
||||
if not settings('dbSyncScreensaver.bool') and self.screensaver is not None:
|
||||
|
||||
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
||||
set_screensaver(value=self.screensaver)
|
||||
|
||||
LOG.info("--<[ fullsync ]")
|
||||
|
|
|
@ -51,7 +51,7 @@ def window(key, value=None, clear=False, window_id=10000):
|
|||
key = key.replace('.bool', "")
|
||||
value = "true" if value else "false"
|
||||
|
||||
window.setProperty(key.replace('.json', "").replace('.bool', ""), value)
|
||||
window.setProperty(key, value)
|
||||
else:
|
||||
result = window.getProperty(key.replace('.json', "").replace('.bool', ""))
|
||||
|
||||
|
|
|
@ -55,11 +55,14 @@ class Library(threading.Thread):
|
|||
|
||||
def __init__(self, monitor):
|
||||
|
||||
self.media = {'Movies': Movies, 'TVShows': TVShows, 'MusicVideos': MusicVideos, 'Music': Music}
|
||||
self.MEDIA = MEDIA
|
||||
|
||||
self.direct_path = settings('useDirectPaths') == "1"
|
||||
self.progress_display = int(settings('syncProgress') or 50)
|
||||
self.monitor = monitor
|
||||
self.player = monitor.monitor.player
|
||||
self.server = Emby()
|
||||
self.server = Emby().get_client()
|
||||
self.updated_queue = Queue.Queue()
|
||||
self.userdata_queue = Queue.Queue()
|
||||
self.removed_queue = Queue.Queue()
|
||||
|
@ -326,14 +329,18 @@ class Library(threading.Thread):
|
|||
if get_sync()['Libraries']:
|
||||
|
||||
try:
|
||||
FullSync(self)
|
||||
with FullSync(self, self.server) as sync:
|
||||
sync.libraries()
|
||||
|
||||
Views().get_nodes()
|
||||
except Exception as error:
|
||||
LOG.error(error)
|
||||
|
||||
elif not settings('SyncInstallRunDone.bool'):
|
||||
|
||||
FullSync(self)
|
||||
with FullSync(self, self.server) as sync:
|
||||
sync.libraries()
|
||||
|
||||
Views().get_nodes()
|
||||
|
||||
return True
|
||||
|
@ -513,7 +520,8 @@ class Library(threading.Thread):
|
|||
def add_library(self, library_id, update=False):
|
||||
|
||||
try:
|
||||
FullSync(self, library_id, update=update)
|
||||
with FullSync(self, server=self.server) as sync:
|
||||
sync.libraries(library_id, update)
|
||||
except Exception as error:
|
||||
LOG.exception(error)
|
||||
|
||||
|
@ -523,69 +531,18 @@ class Library(threading.Thread):
|
|||
|
||||
return True
|
||||
|
||||
@progress(_(33144))
|
||||
def remove_library(self, library_id, dialog):
|
||||
window('emby_sync.bool', True)
|
||||
def remove_library(self, library_id):
|
||||
|
||||
try:
|
||||
with Database('emby') as embydb:
|
||||
with FullSync(self, self.server) as sync:
|
||||
sync.remove_library(library_id)
|
||||
|
||||
db = emby_db.EmbyDatabase(embydb.cursor)
|
||||
library = db.get_view(library_id.replace('Mixed:', ""))
|
||||
items = db.get_item_by_media_folder(library_id.replace('Mixed:', ""))
|
||||
media = 'music' if library[1] == 'music' else 'video'
|
||||
|
||||
if media == 'music':
|
||||
settings('MusicRescan.bool', False)
|
||||
|
||||
if items:
|
||||
count = 0
|
||||
|
||||
with self.music_database_lock if media == 'music' else self.database_lock:
|
||||
with Database(media) as kodidb:
|
||||
|
||||
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])
|
||||
dialog.update(int((float(count) / float(len(items))*100)), heading="%s: %s" % (_('addon_name'), library[0]))
|
||||
count += 1
|
||||
|
||||
obj = MEDIA['Series'](self.server, embydb, kodidb, self.direct_path)['Remove']
|
||||
|
||||
for item in tvshows:
|
||||
obj(item[0])
|
||||
dialog.update(int((float(count) / float(len(items))*100)), heading="%s: %s" % (_('addon_name'), library[0]))
|
||||
count += 1
|
||||
else:
|
||||
obj = MEDIA[items[0][1]](self.server, embydb, kodidb, self.direct_path)['Remove']
|
||||
|
||||
for item in items:
|
||||
obj(item[0])
|
||||
dialog.update(int((float(count) / float(len(items))*100)), heading="%s: %s" % (_('addon_name'), library[0]))
|
||||
count += 1
|
||||
|
||||
sync = get_sync()
|
||||
|
||||
if library_id in sync['Whitelist']:
|
||||
sync['Whitelist'].remove(library_id)
|
||||
elif 'Mixed:%s' % library_id in sync['Whitelist']:
|
||||
sync['Whitelist'].remove('Mixed:%s' % library_id)
|
||||
|
||||
save_sync(sync)
|
||||
Views().remove_library(library_id)
|
||||
except Exception as error:
|
||||
|
||||
LOG.exception(error)
|
||||
window('emby_sync', clear=True)
|
||||
|
||||
return False
|
||||
|
||||
window('emby_sync', clear=True)
|
||||
Views().get_views()
|
||||
Views().get_nodes()
|
||||
|
||||
|
|
Loading…
Reference in a new issue