Merge remote-tracking branch 'worker/db' into Develop
# Conflicts: # cps/tasks/convert.py
This commit is contained in:
commit
3b8e5ddfb3
|
@ -83,6 +83,8 @@ log = logger.create()
|
||||||
|
|
||||||
from . import services
|
from . import services
|
||||||
|
|
||||||
|
db.CalibreDB.setup_db(config, cli.settingspath)
|
||||||
|
|
||||||
calibre_db = db.CalibreDB()
|
calibre_db = db.CalibreDB()
|
||||||
|
|
||||||
def create_app():
|
def create_app():
|
||||||
|
@ -101,7 +103,6 @@ def create_app():
|
||||||
app.secret_key = os.getenv('SECRET_KEY', config_sql.get_flask_session_key(ub.session))
|
app.secret_key = os.getenv('SECRET_KEY', config_sql.get_flask_session_key(ub.session))
|
||||||
|
|
||||||
web_server.init_app(app, config)
|
web_server.init_app(app, config)
|
||||||
calibre_db.setup_db(config, cli.settingspath)
|
|
||||||
|
|
||||||
babel.init_app(app)
|
babel.init_app(app)
|
||||||
_BABEL_TRANSLATIONS.update(str(item) for item in babel.list_translations())
|
_BABEL_TRANSLATIONS.update(str(item) for item in babel.list_translations())
|
||||||
|
|
80
cps/db.py
80
cps/db.py
|
@ -42,14 +42,15 @@ from flask_babel import gettext as _
|
||||||
from . import logger, ub, isoLanguages
|
from . import logger, ub, isoLanguages
|
||||||
from .pagination import Pagination
|
from .pagination import Pagination
|
||||||
|
|
||||||
|
from weakref import WeakSet
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import unidecode
|
import unidecode
|
||||||
|
|
||||||
use_unidecode = True
|
use_unidecode = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
use_unidecode = False
|
use_unidecode = False
|
||||||
|
|
||||||
Session = None
|
|
||||||
|
|
||||||
cc_exceptions = ['datetime', 'comments', 'composite', 'series']
|
cc_exceptions = ['datetime', 'comments', 'composite', 'series']
|
||||||
cc_classes = {}
|
cc_classes = {}
|
||||||
|
|
||||||
|
@ -366,6 +367,7 @@ class Books(Base):
|
||||||
def atom_timestamp(self):
|
def atom_timestamp(self):
|
||||||
return (self.timestamp.strftime('%Y-%m-%dT%H:%M:%S+00:00') or '')
|
return (self.timestamp.strftime('%Y-%m-%dT%H:%M:%S+00:00') or '')
|
||||||
|
|
||||||
|
|
||||||
class Custom_Columns(Base):
|
class Custom_Columns(Base):
|
||||||
__tablename__ = 'custom_columns'
|
__tablename__ = 'custom_columns'
|
||||||
|
|
||||||
|
@ -385,6 +387,7 @@ class Custom_Columns(Base):
|
||||||
display_dict['enum_values'] = [x.decode('unicode_escape') for x in display_dict['enum_values']]
|
display_dict['enum_values'] = [x.decode('unicode_escape') for x in display_dict['enum_values']]
|
||||||
return display_dict
|
return display_dict
|
||||||
|
|
||||||
|
|
||||||
class AlchemyEncoder(json.JSONEncoder):
|
class AlchemyEncoder(json.JSONEncoder):
|
||||||
|
|
||||||
def default(self, obj):
|
def default(self, obj):
|
||||||
|
@ -420,17 +423,32 @@ class AlchemyEncoder(json.JSONEncoder):
|
||||||
|
|
||||||
|
|
||||||
class CalibreDB():
|
class CalibreDB():
|
||||||
|
_init = False
|
||||||
|
engine = None
|
||||||
|
config = None
|
||||||
|
session_factory = None
|
||||||
|
# This is a WeakSet so that references here don't keep other CalibreDB
|
||||||
|
# instances alive once they reach the end of their respective scopes
|
||||||
|
instances = WeakSet()
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.engine = None
|
""" Initialize a new CalibreDB session
|
||||||
|
"""
|
||||||
self.session = None
|
self.session = None
|
||||||
self.log = None
|
if self._init:
|
||||||
self.config = None
|
self.initSession()
|
||||||
|
|
||||||
def setup_db(self, config, app_db_path):
|
self.instances.add(self)
|
||||||
self.config = config
|
|
||||||
self.dispose()
|
|
||||||
global Session
|
def initSession(self):
|
||||||
|
self.session = self.session_factory()
|
||||||
|
self.update_title_sort(self.config)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setup_db(cls, config, app_db_path):
|
||||||
|
cls.config = config
|
||||||
|
cls.dispose()
|
||||||
|
|
||||||
if not config.config_calibre_dir:
|
if not config.config_calibre_dir:
|
||||||
config.invalidate()
|
config.invalidate()
|
||||||
|
@ -442,22 +460,21 @@ class CalibreDB():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.engine = create_engine('sqlite://',
|
cls.engine = create_engine('sqlite://',
|
||||||
echo=False,
|
echo=False,
|
||||||
isolation_level="SERIALIZABLE",
|
isolation_level="SERIALIZABLE",
|
||||||
connect_args={'check_same_thread': False},
|
connect_args={'check_same_thread': False},
|
||||||
poolclass=StaticPool)
|
poolclass=StaticPool)
|
||||||
self.engine.execute("attach database '{}' as calibre;".format(dbpath))
|
cls.engine.execute("attach database '{}' as calibre;".format(dbpath))
|
||||||
self.engine.execute("attach database '{}' as app_settings;".format(app_db_path))
|
cls.engine.execute("attach database '{}' as app_settings;".format(app_db_path))
|
||||||
|
|
||||||
conn = self.engine.connect()
|
conn = cls.engine.connect()
|
||||||
# conn.text_factory = lambda b: b.decode(errors = 'ignore') possible fix for #1302
|
# conn.text_factory = lambda b: b.decode(errors = 'ignore') possible fix for #1302
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
config.invalidate(e)
|
config.invalidate(e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
config.db_configured = True
|
config.db_configured = True
|
||||||
self.update_title_sort(config, conn.connection)
|
|
||||||
|
|
||||||
if not cc_classes:
|
if not cc_classes:
|
||||||
cc = conn.execute("SELECT id, datatype FROM custom_columns")
|
cc = conn.execute("SELECT id, datatype FROM custom_columns")
|
||||||
|
@ -527,10 +544,13 @@ class CalibreDB():
|
||||||
secondary=books_custom_column_links[cc_id[0]],
|
secondary=books_custom_column_links[cc_id[0]],
|
||||||
backref='books'))
|
backref='books'))
|
||||||
|
|
||||||
Session = scoped_session(sessionmaker(autocommit=False,
|
cls.session_factory = scoped_session(sessionmaker(autocommit=False,
|
||||||
autoflush=True,
|
autoflush=True,
|
||||||
bind=self.engine))
|
bind=cls.engine))
|
||||||
self.session = Session()
|
for inst in cls.instances:
|
||||||
|
inst.initSession()
|
||||||
|
|
||||||
|
cls._init = True
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_book(self, book_id):
|
def get_book(self, book_id):
|
||||||
|
@ -587,7 +607,8 @@ class CalibreDB():
|
||||||
def fill_indexpage(self, page, pagesize, database, db_filter, order, *join):
|
def fill_indexpage(self, page, pagesize, database, db_filter, order, *join):
|
||||||
return self.fill_indexpage_with_archived_books(page, pagesize, database, db_filter, order, False, *join)
|
return self.fill_indexpage_with_archived_books(page, pagesize, database, db_filter, order, False, *join)
|
||||||
|
|
||||||
def fill_indexpage_with_archived_books(self, page, pagesize, database, db_filter, order, allow_show_archived, *join):
|
def fill_indexpage_with_archived_books(self, page, pagesize, database, db_filter, order, allow_show_archived,
|
||||||
|
*join):
|
||||||
pagesize = pagesize or self.config.config_books_per_page
|
pagesize = pagesize or self.config.config_books_per_page
|
||||||
if current_user.show_detail_random():
|
if current_user.show_detail_random():
|
||||||
randm = self.session.query(Books) \
|
randm = self.session.query(Books) \
|
||||||
|
@ -702,17 +723,23 @@ class CalibreDB():
|
||||||
conn = conn or self.session.connection().connection.connection
|
conn = conn or self.session.connection().connection.connection
|
||||||
conn.create_function("title_sort", 1, _title_sort)
|
conn.create_function("title_sort", 1, _title_sort)
|
||||||
|
|
||||||
def dispose(self):
|
@classmethod
|
||||||
|
def dispose(cls):
|
||||||
# global session
|
# global session
|
||||||
|
|
||||||
old_session = self.session
|
for inst in cls.instances:
|
||||||
self.session = None
|
old_session = inst.session
|
||||||
|
inst.session = None
|
||||||
if old_session:
|
if old_session:
|
||||||
try: old_session.close()
|
try:
|
||||||
except: pass
|
old_session.close()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
if old_session.bind:
|
if old_session.bind:
|
||||||
try: old_session.bind.dispose()
|
try:
|
||||||
except Exception: pass
|
old_session.bind.dispose()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
for attr in list(Books.__dict__.keys()):
|
for attr in list(Books.__dict__.keys()):
|
||||||
if attr.startswith("custom_column_"):
|
if attr.startswith("custom_column_"):
|
||||||
|
@ -729,10 +756,11 @@ class CalibreDB():
|
||||||
Base.metadata.remove(table)
|
Base.metadata.remove(table)
|
||||||
|
|
||||||
def reconnect_db(self, config, app_db_path):
|
def reconnect_db(self, config, app_db_path):
|
||||||
self.session.close()
|
self.dispose()
|
||||||
self.engine.dispose()
|
self.engine.dispose()
|
||||||
self.setup_db(config, app_db_path)
|
self.setup_db(config, app_db_path)
|
||||||
|
|
||||||
|
|
||||||
def lcase(s):
|
def lcase(s):
|
||||||
try:
|
try:
|
||||||
return unidecode.unidecode(s.lower())
|
return unidecode.unidecode(s.lower())
|
||||||
|
|
|
@ -70,7 +70,8 @@ class TaskConvert(CalibreTask):
|
||||||
return self._handleError(str(e))
|
return self._handleError(str(e))
|
||||||
|
|
||||||
def _convert_ebook_format(self):
|
def _convert_ebook_format(self):
|
||||||
local_session = db.Session()
|
error_message = None
|
||||||
|
local_session = db.CalibreDB()
|
||||||
file_path = self.file_path
|
file_path = self.file_path
|
||||||
book_id = self.bookid
|
book_id = self.bookid
|
||||||
format_old_ext = u'.' + self.settings['old_book_format'].lower()
|
format_old_ext = u'.' + self.settings['old_book_format'].lower()
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user