mirror of
				https://github.com/janeczku/calibre-web
				synced 2025-10-31 15:23:02 +00:00 
			
		
		
		
	Initial attempt at setting up CalibreDB as a class that carries the engine and DB connection, and the instance being the session
This commit is contained in:
		| @@ -83,6 +83,8 @@ log = logger.create() | ||||
|  | ||||
| from . import services | ||||
|  | ||||
| db.CalibreDB.setup_db(config, cli.settingspath) | ||||
|  | ||||
| calibre_db = db.CalibreDB() | ||||
|  | ||||
| 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)) | ||||
|  | ||||
|     web_server.init_app(app, config) | ||||
|     calibre_db.setup_db(config, cli.settingspath) | ||||
|  | ||||
|     babel.init_app(app) | ||||
|     _BABEL_TRANSLATIONS.update(str(item) for item in babel.list_translations()) | ||||
|   | ||||
							
								
								
									
										72
									
								
								cps/db.py
									
									
									
									
									
								
							
							
						
						
									
										72
									
								
								cps/db.py
									
									
									
									
									
								
							| @@ -42,8 +42,11 @@ from flask_babel import gettext as _ | ||||
| from . import logger, ub, isoLanguages | ||||
| from .pagination import Pagination | ||||
|  | ||||
| from weakref import WeakSet | ||||
|  | ||||
| try: | ||||
|     import unidecode | ||||
|  | ||||
|     use_unidecode = True | ||||
| except ImportError: | ||||
|     use_unidecode = False | ||||
| @@ -354,6 +357,7 @@ class Books(Base): | ||||
|     def atom_timestamp(self): | ||||
|         return (self.timestamp.strftime('%Y-%m-%dT%H:%M:%S+00:00') or '') | ||||
|  | ||||
|  | ||||
| class Custom_Columns(Base): | ||||
|     __tablename__ = 'custom_columns' | ||||
|  | ||||
| @@ -373,6 +377,7 @@ class Custom_Columns(Base): | ||||
|             display_dict['enum_values'] = [x.decode('unicode_escape') for x in display_dict['enum_values']] | ||||
|         return display_dict | ||||
|  | ||||
|  | ||||
| class AlchemyEncoder(json.JSONEncoder): | ||||
|  | ||||
|     def default(self, obj): | ||||
| @@ -408,16 +413,28 @@ class AlchemyEncoder(json.JSONEncoder): | ||||
|  | ||||
|  | ||||
| class CalibreDB(): | ||||
|     _init = False | ||||
|     engine = None | ||||
|     log = None  # todo: ??? this isn't used, and even then, not sure if it's supposed to be per session or what | ||||
|     config = None | ||||
|     session_factory = None | ||||
|     instances = WeakSet() | ||||
|  | ||||
|     def __init__(self): | ||||
|         self.engine = None | ||||
|         self.session = None | ||||
|         self.log = None | ||||
|         self.config = None | ||||
|         """ Initialize a new CalibreDB session | ||||
|         """ | ||||
|         if not self._init: | ||||
|             raise Exception("CalibreDB not initialized") | ||||
|         self.session = self.session_factory() | ||||
|         self.instances.add(self) | ||||
|         self.update_title_sort(self.config) | ||||
|  | ||||
|     def setup_db(self, config, app_db_path): | ||||
|         self.config = config | ||||
|         self.dispose() | ||||
|     @classmethod | ||||
|     def setup_db(cls, config, app_db_path): | ||||
|         cls.config = config | ||||
|         cls.dispose() | ||||
|  | ||||
|         # todo: remove...? | ||||
|         global Session | ||||
|  | ||||
|         if not config.config_calibre_dir: | ||||
| @@ -430,22 +447,21 @@ class CalibreDB(): | ||||
|             return False | ||||
|  | ||||
|         try: | ||||
|             self.engine = create_engine('sqlite://', | ||||
|             cls.engine = create_engine('sqlite://', | ||||
|                                        echo=False, | ||||
|                                        isolation_level="SERIALIZABLE", | ||||
|                                        connect_args={'check_same_thread': False}, | ||||
|                                        poolclass=StaticPool) | ||||
|             self.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 calibre;".format(dbpath)) | ||||
|             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 | ||||
|         except Exception as e: | ||||
|             config.invalidate(e) | ||||
|             return False | ||||
|  | ||||
|         config.db_configured = True | ||||
|         self.update_title_sort(config, conn.connection) | ||||
|  | ||||
|         if not cc_classes: | ||||
|             cc = conn.execute("SELECT id, datatype FROM custom_columns") | ||||
| @@ -515,10 +531,10 @@ class CalibreDB(): | ||||
|                                          secondary=books_custom_column_links[cc_id[0]], | ||||
|                                          backref='books')) | ||||
|  | ||||
|         Session = scoped_session(sessionmaker(autocommit=False, | ||||
|         cls.session_factory = scoped_session(sessionmaker(autocommit=False, | ||||
|                                                           autoflush=True, | ||||
|                                               bind=self.engine)) | ||||
|         self.session = Session() | ||||
|                                                           bind=cls.engine)) | ||||
|         cls._init = True | ||||
|         return True | ||||
|  | ||||
|     def get_book(self, book_id): | ||||
| @@ -575,7 +591,8 @@ class CalibreDB(): | ||||
|     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) | ||||
|  | ||||
|     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 | ||||
|         if current_user.show_detail_random(): | ||||
|             randm = self.session.query(Books) \ | ||||
| @@ -687,17 +704,23 @@ class CalibreDB(): | ||||
|         conn = conn or self.session.connection().connection.connection | ||||
|         conn.create_function("title_sort", 1, _title_sort) | ||||
|  | ||||
|     def dispose(self): | ||||
|     @classmethod | ||||
|     def dispose(cls): | ||||
|         # global session | ||||
|  | ||||
|         old_session = self.session | ||||
|         self.session = None | ||||
|         for inst in cls.instances: | ||||
|             old_session = inst.session | ||||
|             inst.session = None | ||||
|             if old_session: | ||||
|             try: old_session.close() | ||||
|             except: pass | ||||
|                 try: | ||||
|                     old_session.close() | ||||
|                 except: | ||||
|                     pass | ||||
|                 if old_session.bind: | ||||
|                 try: old_session.bind.dispose() | ||||
|                 except Exception: pass | ||||
|                     try: | ||||
|                         old_session.bind.dispose() | ||||
|                     except Exception: | ||||
|                         pass | ||||
|  | ||||
|         for attr in list(Books.__dict__.keys()): | ||||
|             if attr.startswith("custom_column_"): | ||||
| @@ -714,10 +737,11 @@ class CalibreDB(): | ||||
|                     Base.metadata.remove(table) | ||||
|  | ||||
|     def reconnect_db(self, config, app_db_path): | ||||
|         self.session.close() | ||||
|         self.dispose() | ||||
|         self.engine.dispose() | ||||
|         self.setup_db(config, app_db_path) | ||||
|  | ||||
|  | ||||
| def lcase(s): | ||||
|     try: | ||||
|         return unidecode.unidecode(s.lower()) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 blitzmann
					blitzmann