Tool black: auto-format Python code

This commit is contained in:
Odd Stråbø 2024-06-10 09:19:47 +00:00
commit 7763762212
54 changed files with 6545 additions and 4723 deletions

View file

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import division, absolute_import, print_function, unicode_literals
#################################################################################################
import datetime
@ -28,51 +29,56 @@ ADDON_DATA = translate_path("special://profile/addon_data/plugin.video.jellyfin/
class Database(object):
"""This should be called like a context.
i.e. with Database('jellyfin') as db:
db.cursor
db.conn.commit()
"""
''' This should be called like a context.
i.e. with Database('jellyfin') as db:
db.cursor
db.conn.commit()
'''
timeout = 120
discovered = False
discovered_file = None
def __init__(self, db_file=None, commit_close=True):
''' file: jellyfin, texture, music, video, :memory: or path to file
'''
"""file: jellyfin, texture, music, video, :memory: or path to file"""
self.db_file = db_file or "video"
self.commit_close = commit_close
def __enter__(self):
''' Open the connection and return the Database class.
This is to allow for the cursor, conn and others to be accessible.
'''
"""Open the connection and return the Database class.
This is to allow for the cursor, conn and others to be accessible.
"""
self.path = self._sql(self.db_file)
self.conn = sqlite3.connect(self.path, timeout=self.timeout)
self.cursor = self.conn.cursor()
if self.db_file in ('video', 'music', 'texture', 'jellyfin'):
self.conn.execute("PRAGMA journal_mode=WAL") # to avoid writing conflict with kodi
if self.db_file in ("video", "music", "texture", "jellyfin"):
self.conn.execute(
"PRAGMA journal_mode=WAL"
) # to avoid writing conflict with kodi
LOG.debug("--->[ database: %s ] %s", self.db_file, id(self.conn))
if not window('jellyfin_db_check.bool') and self.db_file == 'jellyfin':
if not window("jellyfin_db_check.bool") and self.db_file == "jellyfin":
window('jellyfin_db_check.bool', True)
window("jellyfin_db_check.bool", True)
jellyfin_tables(self.cursor)
self.conn.commit()
# Migration for #162
if self.db_file == 'music':
query = self.conn.execute('SELECT * FROM path WHERE strPath LIKE "%/emby/%"')
if self.db_file == "music":
query = self.conn.execute(
'SELECT * FROM path WHERE strPath LIKE "%/emby/%"'
)
contents = query.fetchall()
if contents:
for item in contents:
new_path = item[1].replace('/emby/', '/')
self.conn.execute('UPDATE path SET strPath = "{}" WHERE idPath = "{}"'.format(new_path, item[0]))
new_path = item[1].replace("/emby/", "/")
self.conn.execute(
'UPDATE path SET strPath = "{}" WHERE idPath = "{}"'.format(
new_path, item[0]
)
)
return self
@ -97,68 +103,68 @@ class Database(object):
return path
def _discover_database(self, database):
"""Use UpdateLibrary(video) to update the date modified
on the database file used by Kodi.
"""
if database == "video":
''' Use UpdateLibrary(video) to update the date modified
on the database file used by Kodi.
'''
if database == 'video':
xbmc.executebuiltin('UpdateLibrary(video)')
xbmc.executebuiltin("UpdateLibrary(video)")
xbmc.sleep(200)
databases = translate_path("special://database/")
types = {
'video': "MyVideos",
'music': "MyMusic",
'texture': "Textures"
}
types = {"video": "MyVideos", "music": "MyMusic", "texture": "Textures"}
database = types[database]
dirs, files = xbmcvfs.listdir(databases)
target = {'db_file': '', 'version': 0}
target = {"db_file": "", "version": 0}
for db_file in reversed(files):
if (db_file.startswith(database)
and not db_file.endswith('-wal')
and not db_file.endswith('-shm')
and not db_file.endswith('db-journal')):
if (
db_file.startswith(database)
and not db_file.endswith("-wal")
and not db_file.endswith("-shm")
and not db_file.endswith("db-journal")
):
version_string = re.search('{}(.*).db'.format(database), db_file)
version_string = re.search("{}(.*).db".format(database), db_file)
version = int(version_string.group(1))
if version > target['version']:
target['db_file'] = db_file
target['version'] = version
if version > target["version"]:
target["db_file"] = db_file
target["version"] = version
LOG.debug("Discovered database: %s", target)
self.discovered_file = target['db_file']
self.discovered_file = target["db_file"]
return translate_path("special://database/%s" % target['db_file'])
return translate_path("special://database/%s" % target["db_file"])
def _sql(self, db_file):
''' Get the database path based on the file objects/obj_map.json
Compatible check, in the event multiple db version are supported with the same Kodi version.
Discover by file as a last resort.
'''
"""Get the database path based on the file objects/obj_map.json
Compatible check, in the event multiple db version are supported with the same Kodi version.
Discover by file as a last resort.
"""
databases = obj.Objects().objects
if db_file not in ('video', 'music', 'texture') or databases.get('database_set%s' % db_file):
if db_file not in ("video", "music", "texture") or databases.get(
"database_set%s" % db_file
):
return self._get_database(databases[db_file], True)
discovered = self._discover_database(db_file) if not databases.get('database_set%s' % db_file) else None
discovered = (
self._discover_database(db_file)
if not databases.get("database_set%s" % db_file)
else None
)
databases[db_file] = discovered
self.discovered = True
databases['database_set%s' % db_file] = True
databases["database_set%s" % db_file] = True
LOG.info("Database locked in: %s", databases[db_file])
return databases[db_file]
def __exit__(self, exc_type, exc_val, exc_tb):
''' Close the connection and cursor.
'''
"""Close the connection and cursor."""
changes = self.conn.total_changes
if exc_type is not None: # errors raised
@ -175,41 +181,43 @@ class Database(object):
def jellyfin_tables(cursor):
''' Create the tables for the jellyfin database.
jellyfin, view, version
'''
"""Create the tables for the jellyfin database.
jellyfin, view, version
"""
cursor.execute(
"""CREATE TABLE IF NOT EXISTS jellyfin(
jellyfin_id TEXT UNIQUE, media_folder TEXT, jellyfin_type TEXT, media_type TEXT,
kodi_id INTEGER, kodi_fileid INTEGER, kodi_pathid INTEGER, parent_id INTEGER,
checksum INTEGER, jellyfin_parent_id TEXT)""")
checksum INTEGER, jellyfin_parent_id TEXT)"""
)
cursor.execute(
"""CREATE TABLE IF NOT EXISTS view(
view_id TEXT UNIQUE, view_name TEXT, media_type TEXT)""")
view_id TEXT UNIQUE, view_name TEXT, media_type TEXT)"""
)
cursor.execute("CREATE TABLE IF NOT EXISTS version(idVersion TEXT)")
columns = cursor.execute("SELECT * FROM jellyfin")
if 'jellyfin_parent_id' not in [description[0] for description in columns.description]:
if "jellyfin_parent_id" not in [
description[0] for description in columns.description
]:
LOG.debug("Add missing column jellyfin_parent_id")
cursor.execute("ALTER TABLE jellyfin ADD COLUMN jellyfin_parent_id 'TEXT'")
def reset():
''' Reset both the jellyfin database and the kodi database.
'''
"""Reset both the jellyfin database and the kodi database."""
from ..views import Views
views = Views()
if not dialog("yesno", "{jellyfin}", translate(33074)):
return
window('jellyfin_should_stop.bool', True)
window("jellyfin_should_stop.bool", True)
count = 10
while window('jellyfin_sync.bool'):
while window("jellyfin_sync.bool"):
LOG.info("Sync is running...")
count -= 1
@ -239,12 +247,12 @@ def reset():
if xbmcvfs.exists(os.path.join(ADDON_DATA, "sync.json")):
xbmcvfs.delete(os.path.join(ADDON_DATA, "sync.json"))
settings('enableMusic.bool', False)
settings('MinimumSetup', "")
settings('MusicRescan.bool', False)
settings('SyncInstallRunDone.bool', False)
settings("enableMusic.bool", False)
settings("MinimumSetup", "")
settings("MusicRescan.bool", False)
settings("SyncInstallRunDone.bool", False)
dialog("ok", "{jellyfin}", translate(33088))
xbmc.executebuiltin('RestartApp')
xbmc.executebuiltin("RestartApp")
def reset_kodi():
@ -256,18 +264,20 @@ def reset_kodi():
name = table[0]
# These tables are populated by Kodi and we shouldn't wipe them
if name not in ['version', 'videoversiontype']:
if name not in ["version", "videoversiontype"]:
videodb.cursor.execute("DELETE FROM " + name)
if settings('enableMusic.bool') or dialog("yesno", "{jellyfin}", translate(33162)):
if settings("enableMusic.bool") or dialog("yesno", "{jellyfin}", translate(33162)):
with Database('music') as musicdb:
musicdb.cursor.execute("SELECT tbl_name FROM sqlite_master WHERE type='table'")
with Database("music") as musicdb:
musicdb.cursor.execute(
"SELECT tbl_name FROM sqlite_master WHERE type='table'"
)
for table in musicdb.cursor.fetchall():
name = table[0]
if name != 'version':
if name != "version":
musicdb.cursor.execute("DELETE FROM " + name)
LOG.info("[ reset kodi ]")
@ -275,13 +285,15 @@ def reset_kodi():
def reset_jellyfin():
with Database('jellyfin') as jellyfindb:
jellyfindb.cursor.execute("SELECT tbl_name FROM sqlite_master WHERE type='table'")
with Database("jellyfin") as jellyfindb:
jellyfindb.cursor.execute(
"SELECT tbl_name FROM sqlite_master WHERE type='table'"
)
for table in jellyfindb.cursor.fetchall():
name = table[0]
if name not in ('version', 'view'):
if name not in ("version", "view"):
jellyfindb.cursor.execute("DELETE FROM " + name)
jellyfindb.cursor.execute("DROP table IF EXISTS jellyfin")
@ -292,10 +304,8 @@ def reset_jellyfin():
def reset_artwork():
''' Remove all existing texture.
'''
thumbnails = translate_path('special://thumbnails/')
"""Remove all existing texture."""
thumbnails = translate_path("special://thumbnails/")
if xbmcvfs.exists(thumbnails):
dirs, ignore = xbmcvfs.listdir(thumbnails)
@ -307,13 +317,13 @@ def reset_artwork():
LOG.debug("DELETE thumbnail %s", thumb)
xbmcvfs.delete(os.path.join(thumbnails, directory, thumb))
with Database('texture') as texdb:
with Database("texture") as texdb:
texdb.cursor.execute("SELECT tbl_name FROM sqlite_master WHERE type='table'")
for table in texdb.cursor.fetchall():
name = table[0]
if name != 'version':
if name != "version":
texdb.cursor.execute("DELETE FROM " + name)
LOG.info("[ reset artwork ]")
@ -327,18 +337,18 @@ def get_sync():
xbmcvfs.mkdirs(ADDON_DATA)
try:
with open(os.path.join(ADDON_DATA, 'sync.json'), 'rb') as infile:
with open(os.path.join(ADDON_DATA, "sync.json"), "rb") as infile:
sync = json.load(infile)
except Exception:
sync = {}
sync['Libraries'] = sync.get('Libraries', [])
sync['RestorePoint'] = sync.get('RestorePoint', {})
sync['Whitelist'] = list(set(sync.get('Whitelist', [])))
sync['SortedViews'] = sync.get('SortedViews', [])
sync["Libraries"] = sync.get("Libraries", [])
sync["RestorePoint"] = sync.get("RestorePoint", {})
sync["Whitelist"] = list(set(sync.get("Whitelist", [])))
sync["SortedViews"] = sync.get("SortedViews", [])
# Temporary cleanup from #494/#511, remove in a future version
sync['Libraries'] = [lib_id for lib_id in sync['Libraries'] if ',' not in lib_id]
sync["Libraries"] = [lib_id for lib_id in sync["Libraries"] if "," not in lib_id]
return sync
@ -348,12 +358,12 @@ def save_sync(sync):
if not xbmcvfs.exists(ADDON_DATA):
xbmcvfs.mkdirs(ADDON_DATA)
sync['Date'] = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
sync["Date"] = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")
with open(os.path.join(ADDON_DATA, 'sync.json'), 'wb') as outfile:
with open(os.path.join(ADDON_DATA, "sync.json"), "wb") as outfile:
data = json.dumps(sync, sort_keys=True, indent=4, ensure_ascii=False)
if isinstance(data, text_type):
data = data.encode('utf-8')
data = data.encode("utf-8")
outfile.write(data)
@ -365,30 +375,30 @@ def get_credentials():
xbmcvfs.mkdirs(ADDON_DATA)
try:
with open(os.path.join(ADDON_DATA, 'data.json'), 'rb') as infile:
with open(os.path.join(ADDON_DATA, "data.json"), "rb") as infile:
credentials = json.load(infile)
except IOError:
credentials = {}
credentials['Servers'] = credentials.get('Servers', [])
credentials["Servers"] = credentials.get("Servers", [])
# Migration for #145
# TODO: CLEANUP for 1.0.0 release
for server in credentials['Servers']:
for server in credentials["Servers"]:
# Functionality removed in #60
if 'RemoteAddress' in server:
del server['RemoteAddress']
if 'ManualAddress' in server:
server['address'] = server['ManualAddress']
del server['ManualAddress']
if "RemoteAddress" in server:
del server["RemoteAddress"]
if "ManualAddress" in server:
server["address"] = server["ManualAddress"]
del server["ManualAddress"]
# If manual is present, local should always be here, but better to be safe
if 'LocalAddress' in server:
del server['LocalAddress']
elif 'LocalAddress' in server:
server['address'] = server['LocalAddress']
del server['LocalAddress']
if 'LastConnectionMode' in server:
del server['LastConnectionMode']
if "LocalAddress" in server:
del server["LocalAddress"]
elif "LocalAddress" in server:
server["address"] = server["LocalAddress"]
del server["LocalAddress"]
if "LastConnectionMode" in server:
del server["LastConnectionMode"]
return credentials
@ -399,21 +409,21 @@ def save_credentials(credentials):
if not xbmcvfs.exists(ADDON_DATA):
xbmcvfs.mkdirs(ADDON_DATA)
try:
with open(os.path.join(ADDON_DATA, 'data.json'), 'wb') as outfile:
with open(os.path.join(ADDON_DATA, "data.json"), "wb") as outfile:
data = json.dumps(credentials, sort_keys=True, indent=4, ensure_ascii=False)
if isinstance(data, text_type):
data = data.encode('utf-8')
data = data.encode("utf-8")
outfile.write(data)
except Exception:
LOG.exception("Failed to save credentials:")
def get_item(kodi_id, media):
''' Get jellyfin item based on kodi id and media.
'''
with Database('jellyfin') as jellyfindb:
item = jellyfin_db.JellyfinDatabase(jellyfindb.cursor).get_full_item_by_kodi_id(kodi_id, media)
"""Get jellyfin item based on kodi id and media."""
with Database("jellyfin") as jellyfindb:
item = jellyfin_db.JellyfinDatabase(jellyfindb.cursor).get_full_item_by_kodi_id(
kodi_id, media
)
if not item:
LOG.debug("Not an jellyfin item")