Coverage for seedboxsync/core/taskmanager/manager.py: 98%
46 statements
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-26 17:14 +0000
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-26 17:14 +0000
1#
2# Copyright (C) 2015-2026 Guillaume Kulakowski <guillaume@kulakowski.fr>
3#
4# For the full copyright and license information, please view the LICENSE
5# file that was distributed with this source code.
6#
7"""Taskmanager Manager module."""
9import os
10from pathlib import Path
11import re
12from typing import Any
13from urllib.parse import unquote, urlparse
14from flask import Flask
15from huey import SqliteHuey
18class Manager:
19 """
20 Manage the Huey task queue integration with Flask.
22 The manager creates a Huey instance from the application configuration,
23 stores it in the Flask extensions registry, and proxies Huey attributes
24 through the manager instance.
25 """
27 HUEY_DB_NAME = "huey.db"
28 HUEY_APP_NAME = "seedboxsync"
30 def __init__(self, app: Flask | None = None) -> None:
31 """
32 Initialize the Huey manager.
34 Args:
35 app: Optional Flask application to initialize immediately.
36 """
37 self.app: Flask | None = None
38 self.__instance: SqliteHuey | None = None
40 if app is not None:
41 self.init_app(app)
43 def init_app(self, app: Flask) -> None:
44 """
45 Initialize the Huey manager for a Flask application.
47 The created Huey instance is stored in the Flask extensions registry
48 under the ``huey`` key.
50 Args:
51 app: Flask application to initialize.
52 """
53 self.app = app
55 huey_instance = self.init_huey()
56 app.extensions["huey"] = huey_instance
57 self.__instance = huey_instance
59 def init_huey(self) -> SqliteHuey:
60 """
61 Create and configure the Huey task queue instance.
63 Returns:
64 The configured SQLite-backed Huey instance.
65 """
66 return SqliteHuey(
67 self.HUEY_APP_NAME,
68 filename=str(self._get_huey_database()),
69 )
71 def __getattr__(self, name: str) -> Any:
72 """
73 Proxy unknown attributes to the underlying Huey instance.
75 Args:
76 name: Name of the requested attribute.
78 Returns:
79 The attribute exposed by the underlying Huey instance.
81 Raises:
82 RuntimeError: If the manager has not been initialized.
83 AttributeError: If the Huey instance does not expose the requested
84 attribute.
85 """
86 if self.__instance is None:
87 raise RuntimeError("The Huey manager has not been initialized with a Flask application.")
89 return getattr(self.__instance, name)
91 def _get_huey_database(self) -> Path:
92 """
93 Build the Huey database path from the application database URL.
95 The Huey database is created in the same directory as the main SQLite
96 database configured through ``app.config["DATABASE"]``.
98 For example, the following database URL:
100 ``sqlite:////home/user/.config/seedboxsync/seedboxsync.db``
102 produces:
104 ``/home/user/.config/seedboxsync/huey.db``
106 Returns:
107 The path to the Huey SQLite database file.
109 Raises:
110 RuntimeError: If the manager has not been initialized with a Flask
111 application.
112 ValueError: If the configured database is not a file-based SQLite
113 database.
114 """
115 if self.app is None:
116 raise RuntimeError("The Huey manager has not been initialized with a Flask application.")
118 database_url: str = self.app.config["DATABASE"]
119 parsed_url = urlparse(database_url)
121 clean_path = unquote(parsed_url.path)
123 # SQLite URI represents Windows drive paths as /C:/...
124 if os.name == "nt" and re.match(r"^/[A-Za-z]:/", clean_path):
125 clean_path = clean_path[1:]
127 if clean_path.startswith("//"):
128 clean_path = clean_path[1:]
130 if parsed_url.scheme != "sqlite":
131 raise ValueError(f"Unsupported database scheme: {parsed_url.scheme or '<missing>'}")
133 if not parsed_url.path:
134 raise ValueError("The SQLite database URL does not contain a file path.")
136 if parsed_url.path in {":memory:", "/:memory:"}:
137 raise ValueError("An in-memory SQLite database cannot be used to derive the Huey database path.")
139 database_path = Path(clean_path)
140 huey_database_path = database_path.with_name(self.HUEY_DB_NAME)
142 self.app.logger.debug(
143 "Using Huey task queue database path: %s",
144 huey_database_path,
145 )
147 return huey_database_path