mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2025-01-12 11:06:10 +00:00
Merge branch 'develop' of https://github.com/MediaBrowser/plugin.video.emby into develop
This commit is contained in:
commit
c211a26a35
11 changed files with 509 additions and 589 deletions
|
@ -23,6 +23,7 @@ import entrypoint
|
||||||
import loghandler
|
import loghandler
|
||||||
from utils import window, dialog, language as lang
|
from utils import window, dialog, language as lang
|
||||||
from ga_client import GoogleAnalytics
|
from ga_client import GoogleAnalytics
|
||||||
|
import database
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
|
|
||||||
|
@ -80,7 +81,7 @@ class Main(object):
|
||||||
import utils
|
import utils
|
||||||
modes = {
|
modes = {
|
||||||
|
|
||||||
'reset': utils.reset,
|
'reset': database.db_reset,
|
||||||
'resetauth': entrypoint.resetAuth,
|
'resetauth': entrypoint.resetAuth,
|
||||||
'play': entrypoint.doPlayback,
|
'play': entrypoint.doPlayback,
|
||||||
'passwords': utils.passwordsXML,
|
'passwords': utils.passwordsXML,
|
||||||
|
|
|
@ -13,7 +13,9 @@ import xbmcvfs
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
import image_cache_thread
|
import image_cache_thread
|
||||||
from utils import window, settings, dialog, language as lang, kodiSQL, JSONRPC
|
from utils import window, settings, dialog, language as lang, JSONRPC
|
||||||
|
from database import DatabaseConn
|
||||||
|
from contextlib import closing
|
||||||
|
|
||||||
##################################################################################################
|
##################################################################################################
|
||||||
|
|
||||||
|
@ -164,13 +166,14 @@ class Artwork(object):
|
||||||
|
|
||||||
def _cache_all_video_entries(self, pdialog):
|
def _cache_all_video_entries(self, pdialog):
|
||||||
|
|
||||||
conn = kodiSQL('video')
|
with DatabaseConn('video') as conn:
|
||||||
cursor = conn.cursor()
|
with closing(conn.cursor()) as cursor_video:
|
||||||
cursor.execute("SELECT url FROM art WHERE media_type != 'actor'") # dont include actors
|
|
||||||
result = cursor.fetchall()
|
cursor_video.execute("SELECT url FROM art WHERE media_type != 'actor'") # dont include actors
|
||||||
|
result = cursor_video.fetchall()
|
||||||
total = len(result)
|
total = len(result)
|
||||||
log.info("Image cache sync about to process %s images", total)
|
log.info("Image cache sync about to process %s images", total)
|
||||||
cursor.close()
|
cursor_video.close()
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
for url in result:
|
for url in result:
|
||||||
|
@ -186,13 +189,14 @@ class Artwork(object):
|
||||||
|
|
||||||
def _cache_all_music_entries(self, pdialog):
|
def _cache_all_music_entries(self, pdialog):
|
||||||
|
|
||||||
conn = kodiSQL('music')
|
with DatabaseConn('music') as conn:
|
||||||
cursor = conn.cursor()
|
with closing(conn.cursor()) as cursor_music:
|
||||||
cursor.execute("SELECT url FROM art")
|
|
||||||
result = cursor.fetchall()
|
cursor_music.execute("SELECT url FROM art")
|
||||||
|
result = cursor_music.fetchall()
|
||||||
total = len(result)
|
total = len(result)
|
||||||
|
|
||||||
log.info("Image cache sync about to process %s images", total)
|
log.info("Image cache sync about to process %s images", total)
|
||||||
cursor.close()
|
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
for url in result:
|
for url in result:
|
||||||
|
@ -226,16 +230,14 @@ class Artwork(object):
|
||||||
log.debug("deleted: %s", filename)
|
log.debug("deleted: %s", filename)
|
||||||
|
|
||||||
# remove all existing data from texture DB
|
# remove all existing data from texture DB
|
||||||
conn = kodiSQL('texture')
|
with DatabaseConn('texture') as conn:
|
||||||
cursor = conn.cursor()
|
with closing(conn.cursor()) as cursor_texture:
|
||||||
cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
|
cursor_texture.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
|
||||||
rows = cursor.fetchall()
|
rows = cursor_texture.fetchall()
|
||||||
for row in rows:
|
for row in rows:
|
||||||
table_name = row[0]
|
table_name = row[0]
|
||||||
if table_name != "version":
|
if table_name != "version":
|
||||||
cursor.execute("DELETE FROM " + table_name)
|
cursor_texture.execute("DELETE FROM " + table_name)
|
||||||
conn.commit()
|
|
||||||
cursor.close()
|
|
||||||
|
|
||||||
def _add_worker_image_thread(self, url):
|
def _add_worker_image_thread(self, url):
|
||||||
|
|
||||||
|
@ -429,12 +431,11 @@ class Artwork(object):
|
||||||
@classmethod
|
@classmethod
|
||||||
def delete_cached_artwork(cls, url):
|
def delete_cached_artwork(cls, url):
|
||||||
# Only necessary to remove and apply a new backdrop or poster
|
# Only necessary to remove and apply a new backdrop or poster
|
||||||
conn = kodiSQL('texture')
|
with DatabaseConn('texture') as conn:
|
||||||
cursor = conn.cursor()
|
with closing(conn.cursor()) as cursor_texture:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cursor.execute("SELECT cachedurl FROM texture WHERE url = ?", (url,))
|
cursor_texture.execute("SELECT cachedurl FROM texture WHERE url = ?", (url,))
|
||||||
cached_url = cursor.fetchone()[0]
|
cached_url = cursor_texture.fetchone()[0]
|
||||||
|
|
||||||
except TypeError:
|
except TypeError:
|
||||||
log.info("Could not find cached url")
|
log.info("Could not find cached url")
|
||||||
|
@ -448,13 +449,10 @@ class Artwork(object):
|
||||||
xbmcvfs.delete(thumbnails)
|
xbmcvfs.delete(thumbnails)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cursor.execute("DELETE FROM texture WHERE url = ?", (url,))
|
cursor_texture.execute("DELETE FROM texture WHERE url = ?", (url,))
|
||||||
conn.commit()
|
|
||||||
except OperationalError:
|
except OperationalError:
|
||||||
log.debug("Issue deleting url from cache. Skipping.")
|
log.debug("Issue deleting url from cache. Skipping.")
|
||||||
|
|
||||||
finally:
|
|
||||||
cursor.close()
|
|
||||||
|
|
||||||
def get_people_artwork(self, people):
|
def get_people_artwork(self, people):
|
||||||
# append imageurl if existing
|
# append imageurl if existing
|
||||||
|
|
|
@ -11,8 +11,10 @@ import api
|
||||||
import read_embyserver as embyserver
|
import read_embyserver as embyserver
|
||||||
import embydb_functions as embydb
|
import embydb_functions as embydb
|
||||||
import musicutils as musicutils
|
import musicutils as musicutils
|
||||||
from utils import settings, dialog, language as lang, kodiSQL
|
from utils import settings, dialog, language as lang
|
||||||
from dialogs import context
|
from dialogs import context
|
||||||
|
from database import DatabaseConn
|
||||||
|
from contextlib import closing
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
|
|
||||||
|
@ -87,11 +89,10 @@ class ContextMenu(object):
|
||||||
|
|
||||||
if not item_id and kodi_id and item_type:
|
if not item_id and kodi_id and item_type:
|
||||||
|
|
||||||
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)
|
||||||
item = emby_db.getItem_byKodiId(kodi_id, item_type)
|
item = emby_db.getItem_byKodiId(kodi_id, item_type)
|
||||||
cursor.close()
|
|
||||||
try:
|
try:
|
||||||
item_id = item[0]
|
item_id = item[0]
|
||||||
except TypeError:
|
except TypeError:
|
||||||
|
@ -164,12 +165,12 @@ class ContextMenu(object):
|
||||||
|
|
||||||
def _rate_song(self):
|
def _rate_song(self):
|
||||||
|
|
||||||
conn = kodiSQL('music')
|
with DatabaseConn('music') as conn:
|
||||||
cursor = conn.cursor()
|
with closing(conn.cursor()) as cursor_music:
|
||||||
query = "SELECT rating FROM song WHERE idSong = ?"
|
query = "SELECT rating FROM song WHERE idSong = ?"
|
||||||
cursor.execute(query, (self.kodi_id,))
|
cursor_music.execute(query, (self.kodi_id,))
|
||||||
try:
|
try:
|
||||||
value = cursor.fetchone()[0]
|
value = cursor_music.fetchone()[0]
|
||||||
current_value = int(round(float(value), 0))
|
current_value = int(round(float(value), 0))
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
|
@ -185,10 +186,7 @@ class ContextMenu(object):
|
||||||
musicutils.updateRatingToFile(new_value, self.api.get_file_path())
|
musicutils.updateRatingToFile(new_value, self.api.get_file_path())
|
||||||
|
|
||||||
query = "UPDATE song SET rating = ? WHERE idSong = ?"
|
query = "UPDATE song SET rating = ? WHERE idSong = ?"
|
||||||
cursor.execute(query, (new_value, self.kodi_id,))
|
cursor_music.execute(query, (new_value, self.kodi_id,))
|
||||||
conn.commit()
|
|
||||||
finally:
|
|
||||||
cursor.close()
|
|
||||||
|
|
||||||
def _delete_item(self):
|
def _delete_item(self):
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,17 @@
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
from contextlib import closing
|
||||||
|
import sys
|
||||||
|
import traceback
|
||||||
|
|
||||||
import xbmc
|
import xbmc
|
||||||
|
import xbmcaddon
|
||||||
|
import xbmcgui
|
||||||
|
import xbmcplugin
|
||||||
|
import xbmcvfs
|
||||||
|
|
||||||
from utils import window, should_stop
|
from utils import window, should_stop, settings, language, deletePlaylists, deleteNodes
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
|
|
||||||
|
@ -79,22 +86,26 @@ def kodi_commit():
|
||||||
class DatabaseConn(object):
|
class DatabaseConn(object):
|
||||||
# To be called as context manager - i.e. with DatabaseConn() as conn: #dostuff
|
# To be called as context manager - i.e. with DatabaseConn() as conn: #dostuff
|
||||||
|
|
||||||
def __init__(self, database_file="video", commit_mode="", timeout=20):
|
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
|
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.
|
commit_mode set to None to autocommit (isolation_level). See python documentation.
|
||||||
"""
|
"""
|
||||||
self.db_file = database_file
|
self.db_file = database_file
|
||||||
self.commit_mode = commit_mode
|
self.commit_on_close = commit_on_close
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
|
|
||||||
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)
|
||||||
self.conn = sqlite3.connect(self.path,
|
#traceback.print_stack()
|
||||||
isolation_level=self.commit_mode,
|
|
||||||
timeout=self.timeout)
|
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
|
return self.conn
|
||||||
|
|
||||||
def _SQL(self, media_type):
|
def _SQL(self, media_type):
|
||||||
|
@ -114,17 +125,102 @@ class DatabaseConn(object):
|
||||||
if exc_type is not None:
|
if exc_type is not None:
|
||||||
# Errors were raised in the with statement
|
# Errors were raised in the with statement
|
||||||
log.error("Type: %s Value: %s", exc_type, exc_val)
|
log.error("Type: %s Value: %s", exc_type, exc_val)
|
||||||
if "database is locked" in exc_val:
|
|
||||||
self.conn.rollback()
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
|
|
||||||
elif self.commit_mode is not None and changes:
|
if self.commit_on_close == True and changes:
|
||||||
log.info("number of rows updated: %s", changes)
|
log.info("number of rows updated: %s", changes)
|
||||||
if self.db_file == "video" and kodi_commit():
|
if self.db_file == "video":
|
||||||
self.conn.commit()
|
kodi_commit()
|
||||||
else:
|
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
|
log.info("commit: %s", self.path)
|
||||||
|
|
||||||
log.info("close: %s", self.path)
|
log.info("closing: %s", self.path)
|
||||||
self.conn.close()
|
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())
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
|
|
||||||
|
@ -178,12 +180,10 @@ def emby_backup():
|
||||||
shutil.copy(src=xbmc.translatePath("special://database/emby.db").decode('utf-8'),
|
shutil.copy(src=xbmc.translatePath("special://database/emby.db").decode('utf-8'),
|
||||||
dst=database)
|
dst=database)
|
||||||
# Videos database
|
# Videos database
|
||||||
shutil.copy(src=utils.getKodiVideoDBPath(),
|
shutil.copy(src=DatabaseConn()._SQL('video'), dst=database)
|
||||||
dst=database)
|
|
||||||
# Music database
|
# Music database
|
||||||
if settings('enableMusic') == "true":
|
if settings('enableMusic') == "true":
|
||||||
shutil.copy(src=utils.getKodiMusicDBPath(),
|
shutil.copy(src=DatabaseConn()._SQL('music'), dst=database)
|
||||||
dst=database)
|
|
||||||
|
|
||||||
dialog(type_="ok",
|
dialog(type_="ok",
|
||||||
heading="{emby}",
|
heading="{emby}",
|
||||||
|
@ -234,11 +234,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 +421,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 = {}
|
||||||
|
|
|
@ -6,7 +6,9 @@ import logging
|
||||||
|
|
||||||
import read_embyserver as embyserver
|
import read_embyserver as embyserver
|
||||||
from objects import Movies, MusicVideos, TVShows, Music
|
from objects import Movies, MusicVideos, TVShows, Music
|
||||||
from utils import settings, kodiSQL
|
from utils import settings
|
||||||
|
from database import DatabaseConn
|
||||||
|
from contextlib import closing
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
|
|
||||||
|
@ -58,6 +60,11 @@ class Items(object):
|
||||||
if pdialog:
|
if pdialog:
|
||||||
pdialog.update(heading="Processing %s: %s items" % (process, total))
|
pdialog.update(heading="Processing %s: %s items" % (process, total))
|
||||||
|
|
||||||
|
# this is going to open a music connection even if it is not needed but
|
||||||
|
# I feel that is better than trying to sort out the login yourself
|
||||||
|
with DatabaseConn('music') as conn:
|
||||||
|
with closing(conn.cursor()) as cursor_music:
|
||||||
|
|
||||||
for itemtype in items:
|
for itemtype in items:
|
||||||
|
|
||||||
# Safety check
|
# Safety check
|
||||||
|
@ -70,13 +77,9 @@ class Items(object):
|
||||||
# The list to process is empty
|
# The list to process is empty
|
||||||
continue
|
continue
|
||||||
|
|
||||||
musicconn = None
|
|
||||||
|
|
||||||
if itemtype in ('MusicAlbum', 'MusicArtist', 'AlbumArtist', 'Audio'):
|
if itemtype in ('MusicAlbum', 'MusicArtist', 'AlbumArtist', 'Audio'):
|
||||||
if self.music_enabled:
|
if self.music_enabled:
|
||||||
musicconn = kodiSQL('music')
|
items_process = itemtypes[itemtype](embycursor, cursor_music, pdialog) # see note above
|
||||||
musiccursor = musicconn.cursor()
|
|
||||||
items_process = itemtypes[itemtype](embycursor, musiccursor, pdialog)
|
|
||||||
else:
|
else:
|
||||||
# Music is not enabled, do not proceed with itemtype
|
# Music is not enabled, do not proceed with itemtype
|
||||||
continue
|
continue
|
||||||
|
@ -84,7 +87,6 @@ class Items(object):
|
||||||
update_videolibrary = True
|
update_videolibrary = True
|
||||||
items_process = itemtypes[itemtype](embycursor, kodicursor, pdialog)
|
items_process = itemtypes[itemtype](embycursor, kodicursor, pdialog)
|
||||||
|
|
||||||
|
|
||||||
if process == "added":
|
if process == "added":
|
||||||
items_process.add_all(itemtype, itemlist)
|
items_process.add_all(itemtype, itemlist)
|
||||||
elif process == "remove":
|
elif process == "remove":
|
||||||
|
@ -94,10 +96,4 @@ class Items(object):
|
||||||
items_process.process_all(itemtype, process, process_items, total)
|
items_process.process_all(itemtype, process, process_items, total)
|
||||||
|
|
||||||
|
|
||||||
if musicconn is not None:
|
|
||||||
# close connection for special types
|
|
||||||
log.info("updating music database")
|
|
||||||
musicconn.commit()
|
|
||||||
musiccursor.close()
|
|
||||||
|
|
||||||
return (True, update_videolibrary)
|
return (True, update_videolibrary)
|
||||||
|
|
|
@ -11,8 +11,10 @@ import xbmcgui
|
||||||
import downloadutils
|
import downloadutils
|
||||||
import embydb_functions as embydb
|
import embydb_functions as embydb
|
||||||
import playbackutils as pbutils
|
import playbackutils as pbutils
|
||||||
from utils import window, settings, kodiSQL
|
from utils import window, settings
|
||||||
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]
|
||||||
|
|
|
@ -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,8 @@ 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
|
||||||
|
|
||||||
##################################################################################################
|
##################################################################################################
|
||||||
|
|
||||||
|
@ -56,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()
|
||||||
|
@ -234,11 +234,10 @@ 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:
|
||||||
|
with closing(conn_emby.cursor()) as cursor_emby, closing(conn_video.cursor()) as cursor_video:
|
||||||
# content sync: movies, tvshows, musicvideos, music
|
# content sync: movies, tvshows, musicvideos, music
|
||||||
kodiconn = utils.kodiSQL('video')
|
|
||||||
kodicursor = kodiconn.cursor()
|
|
||||||
|
|
||||||
if manualrun:
|
if manualrun:
|
||||||
message = "Manual sync"
|
message = "Manual sync"
|
||||||
|
@ -277,8 +276,7 @@ class LibrarySync(threading.Thread):
|
||||||
starttotal = datetime.now()
|
starttotal = datetime.now()
|
||||||
|
|
||||||
# Set views
|
# Set views
|
||||||
self.maintainViews(embycursor, kodicursor)
|
self.maintainViews(cursor_emby, cursor_video)
|
||||||
embyconn.commit()
|
|
||||||
|
|
||||||
# Sync video library
|
# Sync video library
|
||||||
process = {
|
process = {
|
||||||
|
@ -293,7 +291,7 @@ class LibrarySync(threading.Thread):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
startTime = datetime.now()
|
startTime = datetime.now()
|
||||||
completed = process[itemtype](embycursor, kodicursor, pDialog)
|
completed = process[itemtype](cursor_emby, cursor_video, pDialog)
|
||||||
if not completed:
|
if not completed:
|
||||||
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
||||||
utils.setScreensaver(value=screensaver)
|
utils.setScreensaver(value=screensaver)
|
||||||
|
@ -301,30 +299,23 @@ class LibrarySync(threading.Thread):
|
||||||
if pDialog:
|
if pDialog:
|
||||||
pDialog.close()
|
pDialog.close()
|
||||||
|
|
||||||
embycursor.close()
|
|
||||||
kodicursor.close()
|
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
self.dbCommit(kodiconn)
|
|
||||||
embyconn.commit()
|
|
||||||
elapsedTime = datetime.now() - startTime
|
elapsedTime = datetime.now() - startTime
|
||||||
log.info("SyncDatabase (finished %s in: %s)"
|
log.info("SyncDatabase (finished %s in: %s)"
|
||||||
% (itemtype, str(elapsedTime).split('.')[0]))
|
% (itemtype, str(elapsedTime).split('.')[0]))
|
||||||
else:
|
|
||||||
# Close the Kodi cursor
|
|
||||||
kodicursor.close()
|
|
||||||
|
|
||||||
# sync music
|
# sync music
|
||||||
|
# use emby and music
|
||||||
if music_enabled:
|
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()
|
startTime = datetime.now()
|
||||||
completed = self.music(embycursor, musiccursor, pDialog)
|
completed = self.music(cursor_emby, cursor_music, pDialog)
|
||||||
if not completed:
|
if not completed:
|
||||||
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
xbmc.executebuiltin('InhibitIdleShutdown(false)')
|
||||||
utils.setScreensaver(value=screensaver)
|
utils.setScreensaver(value=screensaver)
|
||||||
|
@ -332,25 +323,21 @@ class LibrarySync(threading.Thread):
|
||||||
if pDialog:
|
if pDialog:
|
||||||
pDialog.close()
|
pDialog.close()
|
||||||
|
|
||||||
embycursor.close()
|
|
||||||
musiccursor.close()
|
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
musicconn.commit()
|
|
||||||
embyconn.commit()
|
|
||||||
elapsedTime = datetime.now() - startTime
|
elapsedTime = datetime.now() - startTime
|
||||||
log.info("SyncDatabase (finished music in: %s)"
|
log.info("SyncDatabase (finished music in: %s)"
|
||||||
% (str(elapsedTime).split('.')[0]))
|
% (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:
|
||||||
|
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())
|
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,19 +362,11 @@ class LibrarySync(threading.Thread):
|
||||||
|
|
||||||
def refreshViews(self):
|
def refreshViews(self):
|
||||||
|
|
||||||
embyconn = utils.kodiSQL('emby')
|
with DatabaseConn('emby') as conn_emby, DatabaseConn('video') as conn_video:
|
||||||
embycursor = embyconn.cursor()
|
with closing(conn_emby.cursor()) as cursor_emby, closing(conn_video.cursor()) as cursor_video:
|
||||||
kodiconn = utils.kodiSQL('video')
|
|
||||||
kodicursor = kodiconn.cursor()
|
|
||||||
|
|
||||||
# Compare views, assign correct tags to items
|
# Compare views, assign correct tags to items
|
||||||
self.maintainViews(embycursor, kodicursor)
|
self.maintainViews(cursor_emby, cursor_video)
|
||||||
|
|
||||||
self.dbCommit(kodiconn)
|
|
||||||
kodicursor.close()
|
|
||||||
|
|
||||||
embyconn.commit()
|
|
||||||
embycursor.close()
|
|
||||||
|
|
||||||
def maintainViews(self, embycursor, kodicursor):
|
def maintainViews(self, embycursor, kodicursor):
|
||||||
|
|
||||||
|
@ -736,19 +715,17 @@ class LibrarySync(threading.Thread):
|
||||||
|
|
||||||
def incrementalSync(self):
|
def incrementalSync(self):
|
||||||
|
|
||||||
embyconn = utils.kodiSQL('emby')
|
with DatabaseConn('emby') as conn_emby, DatabaseConn('video') as conn_video:
|
||||||
embycursor = embyconn.cursor()
|
with closing(conn_emby.cursor()) as cursor_emby, closing(conn_video.cursor()) as cursor_video:
|
||||||
kodiconn = utils.kodiSQL('video')
|
|
||||||
kodicursor = kodiconn.cursor()
|
emby_db = embydb.Embydb_Functions(cursor_emby)
|
||||||
emby_db = embydb.Embydb_Functions(embycursor)
|
|
||||||
pDialog = None
|
pDialog = None
|
||||||
update_embydb = False
|
update_embydb = False
|
||||||
|
|
||||||
if self.refresh_views:
|
if self.refresh_views:
|
||||||
# Received userconfig update
|
# Received userconfig update
|
||||||
self.refresh_views = False
|
self.refresh_views = False
|
||||||
self.maintainViews(embycursor, kodicursor)
|
self.maintainViews(cursor_emby, cursor_video)
|
||||||
embycursor.commit()
|
|
||||||
self.forceLibraryUpdate = True
|
self.forceLibraryUpdate = True
|
||||||
update_embydb = True
|
update_embydb = True
|
||||||
|
|
||||||
|
@ -774,7 +751,7 @@ class LibrarySync(threading.Thread):
|
||||||
listItems = list(process[process_type])
|
listItems = list(process[process_type])
|
||||||
del process[process_type][:] # Reset class list
|
del process[process_type][:] # Reset class list
|
||||||
|
|
||||||
items_process = itemtypes.Items(embycursor, kodicursor)
|
items_process = itemtypes.Items(cursor_emby, cursor_video)
|
||||||
update = False
|
update = False
|
||||||
|
|
||||||
# Prepare items according to process process_type
|
# Prepare items according to process process_type
|
||||||
|
@ -808,13 +785,11 @@ class LibrarySync(threading.Thread):
|
||||||
if update_embydb:
|
if update_embydb:
|
||||||
update_embydb = False
|
update_embydb = False
|
||||||
log.info("Updating emby database.")
|
log.info("Updating emby database.")
|
||||||
embyconn.commit()
|
|
||||||
self.saveLastSync()
|
self.saveLastSync()
|
||||||
|
|
||||||
if self.forceLibraryUpdate:
|
if self.forceLibraryUpdate:
|
||||||
# Force update the Kodi library
|
# Force update the Kodi library
|
||||||
self.forceLibraryUpdate = False
|
self.forceLibraryUpdate = False
|
||||||
self.dbCommit(kodiconn)
|
|
||||||
|
|
||||||
log.info("Updating video library.")
|
log.info("Updating video library.")
|
||||||
window('emby_kodiScan', value="true")
|
window('emby_kodiScan', value="true")
|
||||||
|
@ -823,9 +798,6 @@ class LibrarySync(threading.Thread):
|
||||||
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.
|
||||||
|
@ -848,8 +820,8 @@ 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:
|
||||||
cursor = conn.cursor()
|
with closing(conn.cursor()) as cursor:
|
||||||
# emby, view, version
|
# emby, view, version
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
"""CREATE TABLE IF NOT EXISTS emby(
|
"""CREATE TABLE IF NOT EXISTS emby(
|
||||||
|
@ -906,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:
|
||||||
|
|
||||||
embyconn = utils.kodiSQL('emby')
|
emby_db = embydb.Embydb_Functions(cursor)
|
||||||
embycursor = embyconn.cursor()
|
|
||||||
emby_db = embydb.Embydb_Functions(embycursor)
|
|
||||||
currentVersion = emby_db.get_version()
|
currentVersion = emby_db.get_version()
|
||||||
###$ Begin migration $###
|
###$ Begin migration $###
|
||||||
if not currentVersion:
|
if not currentVersion:
|
||||||
currentVersion = emby_db.get_version(settings('dbCreatedWithVersion') or self.clientInfo.get_version())
|
currentVersion = emby_db.get_version(settings('dbCreatedWithVersion') or self.clientInfo.get_version())
|
||||||
embyconn.commit()
|
|
||||||
log.info("Migration of database version completed")
|
log.info("Migration of database version completed")
|
||||||
###$ End migration $###
|
###$ End migration $###
|
||||||
embycursor.close()
|
|
||||||
window('emby_version', value=currentVersion)
|
window('emby_version', value=currentVersion)
|
||||||
|
|
||||||
minVersion = window('emby_minDBVersion')
|
minVersion = window('emby_minDBVersion')
|
||||||
|
@ -932,7 +904,7 @@ class LibrarySync(threading.Thread):
|
||||||
log.warn("Database version is out of date! USER IGNORED!")
|
log.warn("Database version is out of date! USER IGNORED!")
|
||||||
dialog.ok(lang(29999), lang(33023))
|
dialog.ok(lang(29999), lang(33023))
|
||||||
else:
|
else:
|
||||||
utils.reset()
|
database.db_reset()
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -941,7 +913,7 @@ class LibrarySync(threading.Thread):
|
||||||
|
|
||||||
if not startupComplete:
|
if not startupComplete:
|
||||||
# Verify the video database can be found
|
# Verify the video database can be found
|
||||||
videoDb = utils.getKodiVideoDBPath()
|
videoDb = DatabaseConn()._SQL('video')
|
||||||
if not xbmcvfs.exists(videoDb):
|
if not xbmcvfs.exists(videoDb):
|
||||||
# Database does not exists
|
# Database does not exists
|
||||||
log.error(
|
log.error(
|
||||||
|
|
|
@ -11,7 +11,9 @@ import playutils
|
||||||
import playbackutils
|
import playbackutils
|
||||||
import embydb_functions as embydb
|
import embydb_functions as embydb
|
||||||
import read_embyserver as embyserver
|
import read_embyserver as embyserver
|
||||||
from utils import window, kodiSQL, JSONRPC
|
from utils import window, JSONRPC
|
||||||
|
from database import DatabaseConn
|
||||||
|
from contextlib import closing
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
|
|
||||||
|
@ -29,8 +31,8 @@ class Playlist(object):
|
||||||
|
|
||||||
def play_all(self, item_ids, start_at):
|
def play_all(self, item_ids, start_at):
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
player = xbmc.Player()
|
player = xbmc.Player()
|
||||||
|
@ -69,12 +71,11 @@ class Playlist(object):
|
||||||
player.play(playlist)
|
player.play(playlist)
|
||||||
|
|
||||||
self.verify_playlist()
|
self.verify_playlist()
|
||||||
cursor.close()
|
|
||||||
|
|
||||||
def modify_playlist(self, item_ids):
|
def modify_playlist(self, item_ids):
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
log.info("---*** ADD TO PLAYLIST ***---")
|
log.info("---*** ADD TO PLAYLIST ***---")
|
||||||
|
@ -99,7 +100,7 @@ class Playlist(object):
|
||||||
self.add_to_playlist(db_id, media_type)
|
self.add_to_playlist(db_id, media_type)
|
||||||
|
|
||||||
self.verify_playlist()
|
self.verify_playlist()
|
||||||
cursor.close()
|
|
||||||
return playlist
|
return playlist
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -8,7 +8,9 @@ import hashlib
|
||||||
import xbmc
|
import xbmc
|
||||||
|
|
||||||
import downloadutils
|
import downloadutils
|
||||||
from utils import window, settings, kodiSQL
|
from utils import window, settings
|
||||||
|
from database import DatabaseConn
|
||||||
|
from contextlib import closing
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
|
|
||||||
|
@ -102,16 +104,16 @@ class Read_EmbyServer():
|
||||||
viewId = view['Id']
|
viewId = view['Id']
|
||||||
|
|
||||||
# Compare to view table in emby database
|
# Compare to view table in emby database
|
||||||
emby = kodiSQL('emby')
|
with DatabaseConn('emby') as conn:
|
||||||
cursor_emby = emby.cursor()
|
with closing(conn.cursor()) as cursor:
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
|
||||||
"SELECT view_name, media_type",
|
"SELECT view_name, media_type",
|
||||||
"FROM view",
|
"FROM view",
|
||||||
"WHERE view_id = ?"
|
"WHERE view_id = ?"
|
||||||
))
|
))
|
||||||
cursor_emby.execute(query, (viewId,))
|
cursor.execute(query, (viewId,))
|
||||||
result = cursor_emby.fetchone()
|
result = cursor.fetchone()
|
||||||
try:
|
try:
|
||||||
viewName = result[0]
|
viewName = result[0]
|
||||||
mediatype = result[1]
|
mediatype = result[1]
|
||||||
|
@ -119,7 +121,6 @@ class Read_EmbyServer():
|
||||||
viewName = None
|
viewName = None
|
||||||
mediatype = None
|
mediatype = None
|
||||||
|
|
||||||
cursor_emby.close()
|
|
||||||
|
|
||||||
return [viewName, viewId, mediatype]
|
return [viewName, viewId, mediatype]
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
|
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
@ -15,6 +14,7 @@ import unicodedata
|
||||||
import xml.etree.ElementTree as etree
|
import xml.etree.ElementTree as etree
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
import xbmc
|
import xbmc
|
||||||
import xbmcaddon
|
import xbmcaddon
|
||||||
import xbmcgui
|
import xbmcgui
|
||||||
|
@ -120,55 +120,6 @@ def should_stop():
|
||||||
else: # Keep going
|
else: # Keep going
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def kodiSQL(media_type="video"):
|
|
||||||
|
|
||||||
if media_type == "emby":
|
|
||||||
dbPath = xbmc.translatePath("special://database/emby.db").decode('utf-8')
|
|
||||||
elif media_type == "texture":
|
|
||||||
dbPath = xbmc.translatePath("special://database/Textures13.db").decode('utf-8')
|
|
||||||
elif media_type == "music":
|
|
||||||
dbPath = getKodiMusicDBPath()
|
|
||||||
else:
|
|
||||||
dbPath = getKodiVideoDBPath()
|
|
||||||
|
|
||||||
if settings('dblock') == "true":
|
|
||||||
connection = sqlite3.connect(dbPath, isolation_level=None, timeout=20)
|
|
||||||
else:
|
|
||||||
connection = sqlite3.connect(dbPath, timeout=20)
|
|
||||||
return connection
|
|
||||||
|
|
||||||
def getKodiVideoDBPath():
|
|
||||||
|
|
||||||
dbVersion = {
|
|
||||||
|
|
||||||
"13": 78, # Gotham
|
|
||||||
"14": 90, # Helix
|
|
||||||
"15": 93, # Isengard
|
|
||||||
"16": 99, # Jarvis
|
|
||||||
"17": 107 # Krypton
|
|
||||||
}
|
|
||||||
|
|
||||||
dbPath = xbmc.translatePath(
|
|
||||||
"special://database/MyVideos%s.db"
|
|
||||||
% dbVersion.get(xbmc.getInfoLabel('System.BuildVersion')[:2], "")).decode('utf-8')
|
|
||||||
return dbPath
|
|
||||||
|
|
||||||
def getKodiMusicDBPath():
|
|
||||||
|
|
||||||
dbVersion = {
|
|
||||||
|
|
||||||
"13": 46, # Gotham
|
|
||||||
"14": 48, # Helix
|
|
||||||
"15": 52, # Isengard
|
|
||||||
"16": 56, # Jarvis
|
|
||||||
"17": 60 # Krypton
|
|
||||||
}
|
|
||||||
|
|
||||||
dbPath = xbmc.translatePath(
|
|
||||||
"special://database/MyMusic%s.db"
|
|
||||||
% dbVersion.get(xbmc.getInfoLabel('System.BuildVersion')[:2], "")).decode('utf-8')
|
|
||||||
return dbPath
|
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
# Utility methods
|
# Utility methods
|
||||||
|
|
||||||
|
@ -280,99 +231,6 @@ def profiling(sortby="cumulative"):
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
# Addon utilities
|
# Addon utilities
|
||||||
|
|
||||||
def 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.")
|
|
||||||
connection = kodiSQL('video')
|
|
||||||
cursor = connection.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)
|
|
||||||
connection.commit()
|
|
||||||
cursor.close()
|
|
||||||
|
|
||||||
if settings('enableMusic') == "true":
|
|
||||||
log.warn("Resetting the Kodi music database.")
|
|
||||||
connection = kodiSQL('music')
|
|
||||||
cursor = connection.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)
|
|
||||||
connection.commit()
|
|
||||||
cursor.close()
|
|
||||||
|
|
||||||
# Wipe the emby database
|
|
||||||
log.warn("Resetting the Emby database.")
|
|
||||||
connection = kodiSQL('emby')
|
|
||||||
cursor = connection.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")
|
|
||||||
connection.commit()
|
|
||||||
cursor.close()
|
|
||||||
|
|
||||||
# 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())
|
|
||||||
|
|
||||||
def sourcesXML():
|
def sourcesXML():
|
||||||
# To make Master lock compatible
|
# To make Master lock compatible
|
||||||
path = xbmc.translatePath("special://profile/").decode('utf-8')
|
path = xbmc.translatePath("special://profile/").decode('utf-8')
|
||||||
|
|
Loading…
Reference in a new issue