# -*- coding: utf-8 -*- ################################################################################################# import logging import sqlite3 from contextlib import closing import sys import xbmc import xbmcaddon import xbmcgui import xbmcplugin import xbmcvfs from utils import window, should_stop, settings, language, deletePlaylists, deleteNodes ################################################################################################# log = logging.getLogger("EMBY."+__name__) KODI = xbmc.getInfoLabel('System.BuildVersion')[:2] ################################################################################################# def video_database(): db_version = { '13': 78, # Gotham '14': 90, # Helix '15': 93, # Isengard '16': 99, # Jarvis '17': 107 # Krypton } path = xbmc.translatePath("special://database/MyVideos%s.db" % db_version.get(KODI, "")).decode('utf-8') return path def music_database(): db_version = { '13': 46, # Gotham '14': 48, # Helix '15': 52, # Isengard '16': 56, # Jarvis '17': 60 # Krypton } path = xbmc.translatePath("special://database/MyMusic%s.db" % db_version.get(KODI, "")).decode('utf-8') return path def texture_database(): return xbmc.translatePath("special://database/Textures13.db").decode('utf-8') def emby_database(): return xbmc.translatePath("special://database/emby.db").decode('utf-8') def kodi_commit(): # verification for the Kodi video scan kodi_scan = window('emby_kodiScan') == "true" count = 0 while kodi_scan: log.info("kodi scan is running, waiting...") if count == 10: log.info("flag still active, but will try to commit") window('emby_kodiScan', clear=True) elif should_stop() or xbmc.Monitor().waitForAbort(1): log.info("commit unsuccessful. sync terminating") return False kodi_scan = window('emby_kodiScan') == "true" count += 1 return True class DatabaseConn(object): # To be called as context manager - i.e. with DatabaseConn() as conn: #dostuff def __init__(self, database_file="video", commit_on_close=True, timeout=120): """ database_file can be custom: emby, texture, music, video, :memory: or path to the file commit_mode set to None to autocommit (isolation_level). See python documentation. """ self.db_file = database_file self.commit_on_close = commit_on_close self.timeout = timeout def __enter__(self): # Open the connection self.path = self._SQL(self.db_file) log.info("opening database: %s", self.path) if settings('dblock') == "true": self.conn = sqlite3.connect(self.path, isolation_level=None, timeout=self.timeout) else: self.conn = sqlite3.connect(self.path, timeout=self.timeout) return self.conn def _SQL(self, media_type): databases = { 'emby': emby_database, 'texture': texture_database, 'music': music_database, 'video': video_database } return databases[media_type]() if media_type in databases else self.db_file def __exit__(self, exc_type, exc_val, exc_tb): # Close the connection changes = self.conn.total_changes if exc_type is not None: # Errors were raised in the with statement log.error("Type: %s Value: %s", exc_type, exc_val) if self.commit_on_close == True and changes: log.info("number of rows updated: %s", changes) if self.db_file == "video": kodi_commit() self.conn.commit() log.info("commit: %s", self.path) log.info("close: %s", self.path) self.conn.close() def db_reset(): dialog = xbmcgui.Dialog() if not dialog.yesno(language(29999), language(33074)): return # first stop any db sync window('emby_online', value="reset") window('emby_shouldStop', value="true") count = 10 while window('emby_dbScan') == "true": log.info("Sync is running, will retry: %s..." % count) count -= 1 if count == 0: dialog.ok(language(29999), language(33085)) return xbmc.sleep(1000) # Clean up the playlists deletePlaylists() # Clean up the video nodes deleteNodes() # Wipe the kodi databases log.warn("Resetting the Kodi video database.") with DatabaseConn('video') as conn: with closing(conn.cursor()) as cursor: cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"') rows = cursor.fetchall() for row in rows: tablename = row[0] if tablename != "version": cursor.execute("DELETE FROM " + tablename) if settings('enableMusic') == "true": log.warn("Resetting the Kodi music database.") with DatabaseConn('music') as conn: with closing(conn.cursor()) as cursor: cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"') rows = cursor.fetchall() for row in rows: tablename = row[0] if tablename != "version": cursor.execute("DELETE FROM " + tablename) # Wipe the emby database log.warn("Resetting the Emby database.") with DatabaseConn('emby') as conn: with closing(conn.cursor()) as cursor: cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"') rows = cursor.fetchall() for row in rows: tablename = row[0] if tablename != "version": cursor.execute("DELETE FROM " + tablename) cursor.execute('DROP table IF EXISTS emby') cursor.execute('DROP table IF EXISTS view') cursor.execute("DROP table IF EXISTS version") # Offer to wipe cached thumbnails if dialog.yesno(language(29999), language(33086)): log.warn("Resetting all cached artwork") # Remove all existing textures first import artwork artwork.Artwork().delete_cache() # reset the install run flag settings('SyncInstallRunDone', value="false") # Remove emby info resp = dialog.yesno(language(29999), language(33087)) if resp: import connectmanager # Delete the settings addon = xbmcaddon.Addon() addondir = xbmc.translatePath( "special://profile/addon_data/plugin.video.emby/").decode('utf-8') dataPath = "%ssettings.xml" % addondir xbmcvfs.delete(dataPath) connectmanager.ConnectManager().clear_data() dialog.ok(heading=language(29999), line1=language(33088)) xbmc.executebuiltin('RestartApp') return xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, xbmcgui.ListItem())