use new DatabaseCon context class

This commit is contained in:
shaun 2016-11-05 13:19:57 +11:00
parent a58b644062
commit 881b3f8e70
4 changed files with 183 additions and 209 deletions

View file

@ -6,6 +6,7 @@ import logging
import sqlite3 import sqlite3
from contextlib import closing from contextlib import closing
import sys import sys
import traceback
import xbmc import xbmc
import xbmcaddon import xbmcaddon
@ -97,7 +98,8 @@ class DatabaseConn(object):
def __enter__(self): def __enter__(self):
# Open the connection # Open the connection
self.path = self._SQL(self.db_file) self.path = self._SQL(self.db_file)
log.info("opening database: %s", self.path) log.info("opening: %s", self.path)
#traceback.print_stack()
if settings('dblock') == "true": if settings('dblock') == "true":
self.conn = sqlite3.connect(self.path, isolation_level=None, timeout=self.timeout) self.conn = sqlite3.connect(self.path, isolation_level=None, timeout=self.timeout)
@ -131,7 +133,7 @@ class DatabaseConn(object):
self.conn.commit() self.conn.commit()
log.info("commit: %s", self.path) log.info("commit: %s", self.path)
log.info("close: %s", self.path) log.info("closing: %s", self.path)
self.conn.close() self.conn.close()

View file

@ -28,6 +28,8 @@ import playbackutils as pbutils
import playutils import playutils
import api import api
from utils import window, settings, dialog, language as lang from utils import window, settings, dialog, language as lang
from database import DatabaseConn
from contextlib import closing
################################################################################################# #################################################################################################
@ -234,11 +236,10 @@ def deleteItem():
log.info("Unknown type, unable to proceed.") log.info("Unknown type, unable to proceed.")
return return
embyconn = utils.kodiSQL('emby') with DatabaseConn('emby') as conn:
embycursor = embyconn.cursor() with closing(conn.cursor()) as cursor:
emby_db = embydb.Embydb_Functions(embycursor) emby_db = embydb.Embydb_Functions(cursor)
item = emby_db.getItem_byKodiId(dbId, itemType) item = emby_db.getItem_byKodiId(dbId, itemType)
embycursor.close()
try: try:
itemId = item[0] itemId = item[0]
@ -422,11 +423,10 @@ def getThemeMedia():
return return
# Get every user view Id # Get every user view Id
embyconn = utils.kodiSQL('emby') with DatabaseConn('emby') as conn:
embycursor = embyconn.cursor() with closing(conn.cursor()) as cursor:
emby_db = embydb.Embydb_Functions(embycursor) emby_db = embydb.Embydb_Functions(cursor)
viewids = emby_db.getViews() viewids = emby_db.getViews()
embycursor.close()
# Get Ids with Theme Videos # Get Ids with Theme Videos
itemIds = {} itemIds = {}

View file

@ -13,6 +13,8 @@ import embydb_functions as embydb
import playbackutils as pbutils import playbackutils as pbutils
from utils import window, settings, kodiSQL from utils import window, settings, kodiSQL
from ga_client import log_error from ga_client import log_error
from database import DatabaseConn
from contextlib import closing
################################################################################################# #################################################################################################
@ -165,11 +167,10 @@ class KodiMonitor(xbmc.Monitor):
item_id = None item_id = None
conn = kodiSQL('emby') with DatabaseConn('emby') as conn:
cursor = conn.cursor() with closing(conn.cursor()) as cursor:
emby_db = embydb.Embydb_Functions(cursor) emby_db = embydb.Embydb_Functions(cursor)
db_item = emby_db.getItem_byKodiId(kodi_id, item_type) db_item = emby_db.getItem_byKodiId(kodi_id, item_type)
cursor.close()
try: try:
item_id = db_item[0] item_id = db_item[0]

View file

@ -12,7 +12,6 @@ import xbmcgui
import xbmcvfs import xbmcvfs
import api import api
import database
import utils import utils
import clientinfo import clientinfo
import downloadutils import downloadutils
@ -25,6 +24,7 @@ import videonodes
from objects import Movies, MusicVideos, TVShows, Music from objects import Movies, MusicVideos, TVShows, Music
from utils import window, settings, language as lang, should_stop from utils import window, settings, language as lang, should_stop
from ga_client import GoogleAnalytics from ga_client import GoogleAnalytics
from database import DatabaseConn
from contextlib import closing from contextlib import closing
################################################################################################## ##################################################################################################
@ -57,7 +57,6 @@ class LibrarySync(threading.Thread):
self.monitor = xbmc.Monitor() self.monitor = xbmc.Monitor()
self.clientInfo = clientinfo.ClientInfo() self.clientInfo = clientinfo.ClientInfo()
self.database = database.DatabaseConn
self.doUtils = downloadutils.DownloadUtils().downloadUrl self.doUtils = downloadutils.DownloadUtils().downloadUrl
self.user = userclient.UserClient() self.user = userclient.UserClient()
self.emby = embyserver.Read_EmbyServer() self.emby = embyserver.Read_EmbyServer()
@ -235,123 +234,110 @@ class LibrarySync(threading.Thread):
# Add sources # Add sources
utils.sourcesXML() utils.sourcesXML()
embyconn = utils.kodiSQL('emby') # use emby and video DBs
embycursor = embyconn.cursor() with DatabaseConn('emby') as conn_emby, DatabaseConn('video') as conn_video:
# content sync: movies, tvshows, musicvideos, music with closing(conn_emby.cursor()) as cursor_emby, closing(conn_video.cursor()) as cursor_video:
kodiconn = utils.kodiSQL('video') # content sync: movies, tvshows, musicvideos, music
kodicursor = kodiconn.cursor()
if manualrun: if manualrun:
message = "Manual sync" message = "Manual sync"
elif repair: elif repair:
message = "Repair sync" message = "Repair sync"
repair_list = [] repair_list = []
choices = ['all', 'movies', 'musicvideos', 'tvshows'] choices = ['all', 'movies', 'musicvideos', 'tvshows']
if music_enabled: if music_enabled:
choices.append('music') choices.append('music')
if self.kodi_version > 15: if self.kodi_version > 15:
# Jarvis or higher # Jarvis or higher
types = xbmcgui.Dialog().multiselect(lang(33094), choices) types = xbmcgui.Dialog().multiselect(lang(33094), choices)
if types is None: if types is None:
pass pass
elif 0 in types: # all elif 0 in types: # all
choices.pop(0) choices.pop(0)
repair_list.extend(choices) repair_list.extend(choices)
else:
for index in types:
repair_list.append(choices[index])
else:
resp = xbmcgui.Dialog().select(lang(33094), choices)
if resp == 0: # all
choices.pop(resp)
repair_list.extend(choices)
else:
repair_list.append(choices[resp])
log.info("Repair queued for: %s", repair_list)
else: else:
for index in types: message = "Initial sync"
repair_list.append(choices[index]) window('emby_initialScan', value="true")
else:
resp = xbmcgui.Dialog().select(lang(33094), choices)
if resp == 0: # all
choices.pop(resp)
repair_list.extend(choices)
else:
repair_list.append(choices[resp])
log.info("Repair queued for: %s", repair_list) pDialog = self.progressDialog("%s" % message)
else: starttotal = datetime.now()
message = "Initial sync"
window('emby_initialScan', value="true")
pDialog = self.progressDialog("%s" % message) # Set views
starttotal = datetime.now() self.maintainViews(cursor_emby, cursor_video)
# Set views # Sync video library
self.maintainViews(embycursor, kodicursor) process = {
embyconn.commit()
# Sync video library 'movies': self.movies,
process = { 'musicvideos': self.musicvideos,
'tvshows': self.tvshows
}
for itemtype in process:
'movies': self.movies, if repair and itemtype not in repair_list:
'musicvideos': self.musicvideos, continue
'tvshows': self.tvshows
}
for itemtype in process:
if repair and itemtype not in repair_list: startTime = datetime.now()
continue completed = process[itemtype](cursor_emby, kodicursor, pDialog)
if not completed:
xbmc.executebuiltin('InhibitIdleShutdown(false)')
utils.setScreensaver(value=screensaver)
window('emby_dbScan', clear=True)
if pDialog:
pDialog.close()
startTime = datetime.now() return False
completed = process[itemtype](embycursor, kodicursor, pDialog) else:
if not completed: elapsedTime = datetime.now() - startTime
xbmc.executebuiltin('InhibitIdleShutdown(false)') log.info("SyncDatabase (finished %s in: %s)"
utils.setScreensaver(value=screensaver) % (itemtype, str(elapsedTime).split('.')[0]))
window('emby_dbScan', clear=True)
if pDialog:
pDialog.close()
embycursor.close()
kodicursor.close()
return False
else:
self.dbCommit(kodiconn)
embyconn.commit()
elapsedTime = datetime.now() - startTime
log.info("SyncDatabase (finished %s in: %s)"
% (itemtype, str(elapsedTime).split('.')[0]))
else:
# Close the Kodi cursor
kodicursor.close()
# sync music # sync music
if music_enabled: # use emby and music
if music_enabled:
if repair and 'music' not in repair_list: if repair and 'music' not in repair_list:
pass pass
else: else:
musicconn = utils.kodiSQL('music') with DatabaseConn('emby') as conn_emby, DatabaseConn('music') as conn_music:
musiccursor = musicconn.cursor() with closing(conn_emby.cursor()) as cursor_emby, closing(conn_music.cursor()) as cursor_music:
startTime = datetime.now()
completed = self.music(cursor_emby, cursor_music, pDialog)
if not completed:
xbmc.executebuiltin('InhibitIdleShutdown(false)')
utils.setScreensaver(value=screensaver)
window('emby_dbScan', clear=True)
if pDialog:
pDialog.close()
startTime = datetime.now() return False
completed = self.music(embycursor, musiccursor, pDialog) else:
if not completed: elapsedTime = datetime.now() - startTime
xbmc.executebuiltin('InhibitIdleShutdown(false)') log.info("SyncDatabase (finished music in: %s)"
utils.setScreensaver(value=screensaver) % (str(elapsedTime).split('.')[0]))
window('emby_dbScan', clear=True)
if pDialog:
pDialog.close()
embycursor.close()
musiccursor.close()
return False
else:
musicconn.commit()
embyconn.commit()
elapsedTime = datetime.now() - startTime
log.info("SyncDatabase (finished music in: %s)"
% (str(elapsedTime).split('.')[0]))
musiccursor.close()
if pDialog: if pDialog:
pDialog.close() pDialog.close()
emby_db = embydb.Embydb_Functions(embycursor) with DatabaseConn('emby') as conn_emby:
current_version = emby_db.get_version(self.clientInfo.get_version()) with closing(conn_emby.cursor()) as cursor_emby:
emby_db = embydb.Embydb_Functions(cursor_emby)
current_version = emby_db.get_version(self.clientInfo.get_version())
window('emby_version', current_version) window('emby_version', current_version)
embyconn.commit()
embycursor.close()
settings('SyncInstallRunDone', value="true") settings('SyncInstallRunDone', value="true")
@ -375,20 +361,12 @@ class LibrarySync(threading.Thread):
def refreshViews(self): def refreshViews(self):
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:
# Compare views, assign correct tags to items
self.maintainViews(cursor_emby, cursor_video)
embyconn = utils.kodiSQL('emby')
embycursor = embyconn.cursor()
kodiconn = utils.kodiSQL('video')
kodicursor = kodiconn.cursor()
# Compare views, assign correct tags to items
self.maintainViews(embycursor, kodicursor)
self.dbCommit(kodiconn)
kodicursor.close()
embyconn.commit()
embycursor.close()
def maintainViews(self, embycursor, kodicursor): def maintainViews(self, embycursor, kodicursor):
@ -736,97 +714,90 @@ class LibrarySync(threading.Thread):
processlist[process].extend(items) processlist[process].extend(items)
def incrementalSync(self): def incrementalSync(self):
embyconn = utils.kodiSQL('emby')
embycursor = embyconn.cursor()
kodiconn = utils.kodiSQL('video')
kodicursor = kodiconn.cursor()
emby_db = embydb.Embydb_Functions(embycursor)
pDialog = None
update_embydb = False
if self.refresh_views:
# Received userconfig update
self.refresh_views = False
self.maintainViews(embycursor, kodicursor)
embycursor.commit()
self.forceLibraryUpdate = True
update_embydb = True
incSyncIndicator = int(settings('incSyncIndicator') or 10)
totalUpdates = len(self.addedItems) + len(self.updateItems) + len(self.userdataItems) + len(self.removeItems)
if incSyncIndicator != -1 and totalUpdates > incSyncIndicator: with DatabaseConn('emby') as conn_emby, DatabaseConn('video') as conn_video:
# Only present dialog if we are going to process items with closing(conn_emby.cursor()) as cursor_emby, closing(conn_video.cursor()) as cursor_video:
pDialog = self.progressDialog('Incremental sync')
log.info("incSyncIndicator=" + str(incSyncIndicator) + " totalUpdates=" + str(totalUpdates)) emby_db = embydb.Embydb_Functions(cursor_emby)
pDialog = None
update_embydb = False
process = { if self.refresh_views:
# Received userconfig update
self.refresh_views = False
self.maintainViews(cursor_emby, cursor_video)
self.forceLibraryUpdate = True
update_embydb = True
'added': self.addedItems, incSyncIndicator = int(settings('incSyncIndicator') or 10)
'update': self.updateItems, totalUpdates = len(self.addedItems) + len(self.updateItems) + len(self.userdataItems) + len(self.removeItems)
'userdata': self.userdataItems,
'remove': self.removeItems if incSyncIndicator != -1 and totalUpdates > incSyncIndicator:
} # Only present dialog if we are going to process items
for process_type in ['added', 'update', 'userdata', 'remove']: pDialog = self.progressDialog('Incremental sync')
log.info("incSyncIndicator=" + str(incSyncIndicator) + " totalUpdates=" + str(totalUpdates))
if process[process_type] and window('emby_kodiScan') != "true": process = {
listItems = list(process[process_type]) 'added': self.addedItems,
del process[process_type][:] # Reset class list 'update': self.updateItems,
'userdata': self.userdataItems,
'remove': self.removeItems
}
for process_type in ['added', 'update', 'userdata', 'remove']:
items_process = itemtypes.Items(embycursor, kodicursor) if process[process_type] and window('emby_kodiScan') != "true":
update = False
# Prepare items according to process process_type listItems = list(process[process_type])
if process_type == "added": del process[process_type][:] # Reset class list
items = self.emby.sortby_mediatype(listItems)
elif process_type in ("userdata", "remove"): items_process = itemtypes.Items(cursor_emby, cursor_video)
items = emby_db.sortby_mediaType(listItems, unsorted=False) update = False
else: # Prepare items according to process process_type
items = emby_db.sortby_mediaType(listItems) if process_type == "added":
if items.get('Unsorted'): items = self.emby.sortby_mediatype(listItems)
sorted_items = self.emby.sortby_mediatype(items['Unsorted'])
doupdate = items_process.itemsbyId(sorted_items, "added", pDialog) elif process_type in ("userdata", "remove"):
items = emby_db.sortby_mediaType(listItems, unsorted=False)
else:
items = emby_db.sortby_mediaType(listItems)
if items.get('Unsorted'):
sorted_items = self.emby.sortby_mediatype(items['Unsorted'])
doupdate = items_process.itemsbyId(sorted_items, "added", pDialog)
if doupdate:
embyupdate, kodiupdate_video = doupdate
if embyupdate:
update_embydb = True
if kodiupdate_video:
self.forceLibraryUpdate = True
del items['Unsorted']
doupdate = items_process.itemsbyId(items, process_type, pDialog)
if doupdate: if doupdate:
embyupdate, kodiupdate_video = doupdate embyupdate, kodiupdate_video = doupdate
if embyupdate: if embyupdate:
update_embydb = True update_embydb = True
if kodiupdate_video: if kodiupdate_video:
self.forceLibraryUpdate = True self.forceLibraryUpdate = True
del items['Unsorted']
doupdate = items_process.itemsbyId(items, process_type, pDialog) if update_embydb:
if doupdate: update_embydb = False
embyupdate, kodiupdate_video = doupdate log.info("Updating emby database.")
if embyupdate: self.saveLastSync()
update_embydb = True
if kodiupdate_video:
self.forceLibraryUpdate = True
if update_embydb: if self.forceLibraryUpdate:
update_embydb = False # Force update the Kodi library
log.info("Updating emby database.") self.forceLibraryUpdate = False
embyconn.commit()
self.saveLastSync()
if self.forceLibraryUpdate: log.info("Updating video library.")
# Force update the Kodi library window('emby_kodiScan', value="true")
self.forceLibraryUpdate = False xbmc.executebuiltin('UpdateLibrary(video)')
self.dbCommit(kodiconn)
log.info("Updating video library.")
window('emby_kodiScan', value="true")
xbmc.executebuiltin('UpdateLibrary(video)')
if pDialog: if pDialog:
pDialog.close() pDialog.close()
kodicursor.close()
embycursor.close()
def compareDBVersion(self, current, minimum): def compareDBVersion(self, current, minimum):
# It returns True is database is up to date. False otherwise. # It returns True is database is up to date. False otherwise.
@ -849,7 +820,7 @@ class LibrarySync(threading.Thread):
def _verify_emby_database(self): def _verify_emby_database(self):
# Create the tables for the emby database # Create the tables for the emby database
with self.database('emby') as conn: with DatabaseConn('emby') as conn:
with closing(conn.cursor()) as cursor: with closing(conn.cursor()) as cursor:
# emby, view, version # emby, view, version
cursor.execute( cursor.execute(
@ -907,18 +878,18 @@ class LibrarySync(threading.Thread):
if (window('emby_dbCheck') != "true" and settings('SyncInstallRunDone') == "true"): if (window('emby_dbCheck') != "true" and settings('SyncInstallRunDone') == "true"):
# Verify the validity of the database # Verify the validity of the database
log.info("Doing DB Version Check")
with DatabaseConn('emby') as conn:
with closing(conn.cursor()) as cursor:
emby_db = embydb.Embydb_Functions(cursor)
currentVersion = emby_db.get_version()
###$ Begin migration $###
if not currentVersion:
currentVersion = emby_db.get_version(settings('dbCreatedWithVersion') or self.clientInfo.get_version())
log.info("Migration of database version completed")
###$ End migration $###
embyconn = utils.kodiSQL('emby')
embycursor = embyconn.cursor()
emby_db = embydb.Embydb_Functions(embycursor)
currentVersion = emby_db.get_version()
###$ Begin migration $###
if not currentVersion:
currentVersion = emby_db.get_version(settings('dbCreatedWithVersion') or self.clientInfo.get_version())
embyconn.commit()
log.info("Migration of database version completed")
###$ End migration $###
embycursor.close()
window('emby_version', value=currentVersion) window('emby_version', value=currentVersion)
minVersion = window('emby_minDBVersion') minVersion = window('emby_minDBVersion')