diff --git a/resources/lib/database.py b/resources/lib/database.py index eccf2132..72b2cecb 100644 --- a/resources/lib/database.py +++ b/resources/lib/database.py @@ -14,7 +14,8 @@ import xbmcgui import xbmcplugin import xbmcvfs -from utils import window, should_stop, settings, language, deletePlaylists, deleteNodes +from views import Playlist, VideoNodes +from utils import window, should_stop, settings, language ################################################################################################# @@ -157,10 +158,10 @@ def db_reset(): xbmc.sleep(1000) # Clean up the playlists - deletePlaylists() + Playlist().delete_playlists() # Clean up the video nodes - deleteNodes() + VideoNodes().deleteNodes() # Wipe the kodi databases log.warn("Resetting the Kodi video database.") diff --git a/resources/lib/entrypoint.py b/resources/lib/entrypoint.py index a94d46e0..c35fa356 100644 --- a/resources/lib/entrypoint.py +++ b/resources/lib/entrypoint.py @@ -27,6 +27,7 @@ import playlist import playbackutils as pbutils import playutils import api +from views import Playlist, VideoNodes from utils import window, settings, dialog, language as lang from database import DatabaseConn from contextlib import closing @@ -548,9 +549,9 @@ def refreshPlaylist(): dialog = xbmcgui.Dialog() try: # First remove playlists - utils.deletePlaylists() + Playlist().delete_playlists() # Remove video nodes - utils.deleteNodes() + VideoNodes().deleteNodes() # Refresh views lib.refreshViews() dialog.notification( diff --git a/resources/lib/librarysync.py b/resources/lib/librarysync.py index 8d302a97..f77ac879 100644 --- a/resources/lib/librarysync.py +++ b/resources/lib/librarysync.py @@ -508,13 +508,9 @@ class LibrarySync(threading.Thread): # do a view update if needed if self.refresh_views: - with DatabaseConn('emby') as conn_emby, DatabaseConn('video') as conn_video: - with closing(conn_emby.cursor()) as cursor_emby, closing(conn_video.cursor()) as cursor_video: - # Received userconfig update - self.refresh_views = False - self.maintainViews(cursor_emby, cursor_video) - self.forceLibraryUpdate = True - update_embydb = True + self.refreshViews() + self.refresh_views = False + self.forceLibraryUpdate = True # do a lib update if any items in list totalUpdates = len(self.addedItems) + len(self.updateItems) + len(self.userdataItems) + len(self.removeItems) diff --git a/resources/lib/utils.py b/resources/lib/utils.py index 9191c702..33b7450f 100644 --- a/resources/lib/utils.py +++ b/resources/lib/utils.py @@ -150,26 +150,6 @@ def convertDate(date): return date -def normalize_nodes(text): - # For video nodes - text = text.replace(":", "") - text = text.replace("/", "-") - text = text.replace("\\", "-") - text = text.replace("<", "") - text = text.replace(">", "") - text = text.replace("*", "") - text = text.replace("?", "") - text = text.replace('|', "") - text = text.replace('(', "") - text = text.replace(')', "") - text = text.strip() - # Remove dots from the last character as windows can not have directories - # with dots at the end - text = text.rstrip('.') - text = unicodedata.normalize('NFKD', unicode(text, 'utf-8')).encode('ascii', 'ignore') - - return text - def normalize_string(text): # For theme media, do not modify unless # modified in TV Tunes @@ -366,88 +346,3 @@ def passwordsXML(): icon="special://home/addons/plugin.video.emby/icon.png", time=1000, sound=False) - -def playlistXSP(mediatype, tagname, viewid, viewtype="", delete=False): - # Tagname is in unicode - actions: add or delete - tagname = tagname.encode('utf-8') - - path = xbmc.translatePath("special://profile/playlists/video/").decode('utf-8') - if viewtype == "mixed": - plname = "%s - %s" % (tagname, mediatype) - xsppath = "%sEmby %s - %s.xsp" % (path, viewid, mediatype) - else: - plname = tagname - xsppath = "%sEmby %s.xsp" % (path, viewid) - - # Create the playlist directory - if not xbmcvfs.exists(path): - log.info("Creating directory: %s" % path) - xbmcvfs.mkdirs(path) - - # Only add the playlist if it doesn't already exists - if xbmcvfs.exists(xsppath): - - if delete: - xbmcvfs.delete(xsppath) - log.info("Successfully removed playlist: %s." % tagname) - - return - - # Using write process since there's no guarantee the xml declaration works with etree - itemtypes = { - 'homevideos': "movies" - } - log.info("Writing playlist file to: %s" % xsppath) - try: - f = xbmcvfs.File(xsppath, 'w') - except: - log.info("Failed to create playlist: %s" % xsppath) - return - else: - f.write( - '\n' - '\n\t' - 'Emby %s\n\t' - 'all\n\t' - '\n\t\t' - '%s\n\t' - '' - '' - % (itemtypes.get(mediatype, mediatype), plname, tagname)) - f.close() - log.info("Successfully added playlist: %s" % tagname) - -def deletePlaylists(): - - # Clean up the playlists - path = xbmc.translatePath("special://profile/playlists/video/").decode('utf-8') - dirs, files = xbmcvfs.listdir(path) - 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/emby/").decode('utf-8') - if (xbmcvfs.exists(path)): - try: - shutil.rmtree(path) - except: - log.warn("Failed to delete directory: %s" % path) - # Old cleanup code kept for cleanup of old style nodes - 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'): - try: - shutil.rmtree("%s%s" % (path, dir.decode('utf-8'))) - except: - log.warn("Failed to delete directory: %s" % dir.decode('utf-8')) - for file in files: - if file.decode('utf-8').startswith('emby'): - try: - xbmcvfs.delete("%s%s" % (path, file.decode('utf-8'))) - except: - log.warn("Failed to delete file: %s" % file.decode('utf-8')) \ No newline at end of file diff --git a/resources/lib/views.py b/resources/lib/views.py index 8a2384dc..8a359d85 100644 --- a/resources/lib/views.py +++ b/resources/lib/views.py @@ -13,7 +13,7 @@ import xbmcvfs import read_embyserver as embyserver import embydb_functions as embydb -from utils import window, language as lang, normalize_nodes, indent as xml_indent +from utils import window, language as lang, indent as xml_indent ################################################################################################# @@ -33,7 +33,6 @@ class Views(object): grouped_views = list() media_types = { - 'movies': "Movie", 'tvshows': "Series", 'musicvideos': "MusicVideo", @@ -79,7 +78,7 @@ class Views(object): self.nodes = list() # Prevent duplicate for nodes of the same type self.playlists = list() # Prevent duplicate for playlists of the same type - # Get media folders from the ordered + # Get media folders to include mixed views as well for folder in self.emby.getViews(media_type, root=True): view_id = folder['id'] @@ -287,7 +286,15 @@ class Views(object): self.playlist.process_playlist(media_type, view_id, view_name, view_type) self.playlists.append(view_name) # Create the video node - self._create_node(media_type, view_id, view_name, view_type) + if view_name not in self.nodes and media_type not in ('musicvideos', 'music'): + index = self.sorted_views.index(view_name) + self.video_nodes.viewNode(index, view_name, media_type,view_type, view_id) + + if view_type == "mixed": # Change the value + self.sorted_views[index] = "%ss" % view_name + + self.nodes.append(view_name) + self.total_nodes += 1 def delete_playlist_node(self, media_type, view_id, view_name, view_type): @@ -302,19 +309,8 @@ class Views(object): if media_type != "musicvideos": self.video_nodes.viewNode(None, view_name, media_type, view_type, view_id, True) - def _create_node(self, media_type, view_id, view_name, view_type): - - if view_name not in self.nodes and media_type not in ('musicvideos', 'music'): - index = self.sorted_views.index(view_name) - self.video_nodes.viewNode(index, view_name, media_type,view_type, view_id) - - if view_type == "mixed": # Change the value - self.sorted_views[index] = "%ss" % view_name - - self.nodes.append(view_name) - self.total_nodes += 1 - def add_single_nodes(self): + singles = [ ("Favorite movies", "movies", "favourites"), ("Favorite tvshows", "tvshows", "favourites"), @@ -385,6 +381,14 @@ class Playlist(object): xbmcvfs.delete(path) log.info("successfully removed playlist: %s", path) + def delete_playlists(self): + # Clean up the playlists + path = xbmc.translatePath("special://profile/playlists/video/").decode('utf-8') + dirs, files = xbmcvfs.listdir(path) + for file in files: + if file.decode('utf-8').startswith('Emby'): + self._delete_playlist(os.path.join(path, file)) + class VideoNodes(object): @@ -392,6 +396,26 @@ class VideoNodes(object): def __init__(self): pass + def normalize_nodes(self, text): + # For video nodes + text = text.replace(":", "") + text = text.replace("/", "-") + text = text.replace("\\", "-") + text = text.replace("<", "") + text = text.replace(">", "") + text = text.replace("*", "") + text = text.replace("?", "") + text = text.replace('|', "") + text = text.replace('(', "") + text = text.replace(')', "") + text = text.strip() + # Remove dots from the last character as windows can not have directories + # with dots at the end + text = text.rstrip('.') + text = unicodedata.normalize('NFKD', unicode(text, 'utf-8')).encode('ascii', 'ignore') + + return text + def commonRoot(self, order, label, tagname="", roottype=1): if roottype == 0: @@ -693,7 +717,7 @@ class VideoNodes(object): def singleNode(self, indexnumber, tagname, mediatype, itemtype): tagname = tagname.encode('utf-8') - cleantagname = normalize_nodes(tagname) + cleantagname = self.normalize_nodes(tagname) nodepath = xbmc.translatePath("special://profile/library/video/").decode('utf-8') nodeXML = "%semby_%s.xml" % (nodepath, cleantagname) path = "library://video/emby_%s.xml" % cleantagname @@ -742,6 +766,30 @@ class VideoNodes(object): except: pass etree.ElementTree(root).write(nodeXML) + def deleteNodes(self): + # Clean up video nodes + path = xbmc.translatePath("special://profile/library/video/emby/").decode('utf-8') + if (xbmcvfs.exists(path)): + try: + shutil.rmtree(path) + except: + log.warn("Failed to delete directory: %s" % path) + # Old cleanup code kept for cleanup of old style nodes + 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'): + try: + shutil.rmtree("%s%s" % (path, dir.decode('utf-8'))) + except: + log.warn("Failed to delete directory: %s" % dir.decode('utf-8')) + for file in files: + if file.decode('utf-8').startswith('emby'): + try: + xbmcvfs.delete("%s%s" % (path, file.decode('utf-8'))) + except: + log.warn("Failed to delete file: %s" % file.decode('utf-8')) + def clearProperties(self): log.info("Clearing nodes properties.")