2021-05-20 01:57:40 +02:00
|
|
|
import logging
|
2021-12-07 16:58:12 +01:00
|
|
|
import asyncio
|
2021-05-02 16:51:54 +02:00
|
|
|
from pathlib import Path
|
|
|
|
from tortoise import Tortoise
|
2021-12-05 18:37:35 +01:00
|
|
|
from aerich import Command
|
2021-08-16 10:49:52 +02:00
|
|
|
from mobilizon_reshare.config.publishers import publisher_names
|
2021-11-24 23:58:06 +01:00
|
|
|
from mobilizon_reshare.storage.query.write import update_publishers
|
2021-12-05 18:37:35 +01:00
|
|
|
|
|
|
|
from mobilizon_reshare.config.config import get_settings
|
2021-07-05 23:07:12 +02:00
|
|
|
|
2021-05-20 01:57:40 +02:00
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
2021-05-02 16:51:54 +02:00
|
|
|
|
2021-12-05 18:37:35 +01:00
|
|
|
def get_db_url():
|
|
|
|
"""gets db url from settings
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
str : db url
|
|
|
|
"""
|
|
|
|
settings = get_settings()
|
|
|
|
db_path = Path(settings.db_path)
|
|
|
|
db_url = f"sqlite:///{db_path}"
|
|
|
|
return db_url
|
|
|
|
|
|
|
|
|
|
|
|
TORTOISE_ORM = {
|
|
|
|
"connections": {"default": get_db_url()},
|
|
|
|
"apps": {
|
|
|
|
"models": {
|
|
|
|
"models": ["mobilizon_reshare.models.event",
|
|
|
|
"mobilizon_reshare.models.notification",
|
|
|
|
"mobilizon_reshare.models.publication",
|
|
|
|
"mobilizon_reshare.models.publisher", "aerich.models"],
|
|
|
|
"default_connection": "default",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-12-07 16:58:12 +01:00
|
|
|
async def shutdown(loop):
|
|
|
|
"""shutdown method"""
|
|
|
|
logging.critical("SHUTDOWN CALLED")
|
|
|
|
logging.info("closing database connections")
|
|
|
|
tasks = [t for t in asyncio.all_tasks() if t is asyncio.current_task()]
|
|
|
|
_ = [task.cancel() for task in tasks]
|
|
|
|
logging.info("Cancelling %i tasks", len(tasks))
|
|
|
|
await asyncio.gather(*tasks, return_exceptions=True)
|
|
|
|
logging.info("flushing metrics")
|
|
|
|
loop.stop()
|
|
|
|
|
|
|
|
|
|
|
|
async def handle_exception(loop, context):
|
|
|
|
"""exception handler"""
|
|
|
|
logging.critical("HANDLER CALLED")
|
|
|
|
msg = context.get("exception", context["message"])
|
|
|
|
logging.critical("Caught exception: %s", msg)
|
|
|
|
logging.info("shutting down")
|
|
|
|
await shutdown(loop)
|
|
|
|
await tear_down()
|
|
|
|
|
|
|
|
|
2021-08-16 10:49:52 +02:00
|
|
|
class MoReDB:
|
2021-05-31 01:11:50 +02:00
|
|
|
def __init__(self, path: Path):
|
2021-12-07 16:58:12 +01:00
|
|
|
loop = asyncio.get_event_loop()
|
|
|
|
loop.set_exception_handler(handle_exception)
|
|
|
|
|
2021-05-02 16:51:54 +02:00
|
|
|
self.path = path
|
2021-05-31 01:11:50 +02:00
|
|
|
# TODO: Check if DB is openable/"queriable"
|
|
|
|
self.is_init = self.path.exists() and (not self.path.is_dir())
|
|
|
|
if not self.is_init:
|
|
|
|
self.path.parent.mkdir(parents=True, exist_ok=True)
|
2021-05-02 16:51:54 +02:00
|
|
|
|
2021-12-05 17:11:24 +01:00
|
|
|
async def _implement_db_changes(self):
|
|
|
|
logging.info("Updating database to latest version")
|
2021-12-07 12:10:32 +01:00
|
|
|
try:
|
|
|
|
|
|
|
|
command = Command(tortoise_config=TORTOISE_ORM, app='models',
|
|
|
|
location='./migrations')
|
|
|
|
await command.init()
|
|
|
|
await command.upgrade()
|
|
|
|
except FileNotFoundError:
|
|
|
|
logging.critical("aerich configuration not found, fatal error")
|
2021-12-07 16:58:12 +01:00
|
|
|
raise
|
2021-12-04 17:55:43 +01:00
|
|
|
|
2021-05-02 16:51:54 +02:00
|
|
|
async def setup(self):
|
2021-12-07 16:58:12 +01:00
|
|
|
implement_db_changes = asyncio.create_task(self._implement_db_changes())
|
|
|
|
_, _ = await asyncio.wait({implement_db_changes},
|
|
|
|
return_when=asyncio.FIRST_EXCEPTION)
|
|
|
|
if implement_db_changes.exception():
|
|
|
|
logging.critical("exception during aerich init")
|
|
|
|
raise implement_db_changes.exception()
|
2021-05-02 16:51:54 +02:00
|
|
|
await Tortoise.init(
|
2021-12-05 18:37:35 +01:00
|
|
|
db_url=get_db_url(),
|
2021-05-31 01:11:50 +02:00
|
|
|
modules={
|
|
|
|
"models": [
|
2021-08-16 10:49:52 +02:00
|
|
|
"mobilizon_reshare.models.event",
|
|
|
|
"mobilizon_reshare.models.notification",
|
|
|
|
"mobilizon_reshare.models.publication",
|
|
|
|
"mobilizon_reshare.models.publisher",
|
2021-05-31 01:11:50 +02:00
|
|
|
]
|
|
|
|
},
|
|
|
|
# always store UTC time in database
|
|
|
|
use_tz=True,
|
2021-05-02 16:51:54 +02:00
|
|
|
)
|
2021-05-31 01:11:50 +02:00
|
|
|
if not self.is_init:
|
2021-05-02 16:51:54 +02:00
|
|
|
await Tortoise.generate_schemas()
|
2021-05-31 01:11:50 +02:00
|
|
|
self.is_init = True
|
2021-11-11 15:18:04 +01:00
|
|
|
logger.info(f"Successfully initialized database at {self.path}")
|
2021-05-31 01:19:24 +02:00
|
|
|
|
2021-08-05 00:29:50 +02:00
|
|
|
await update_publishers(publisher_names)
|
|
|
|
|
2021-05-31 01:19:24 +02:00
|
|
|
|
2021-07-21 09:08:19 +02:00
|
|
|
async def tear_down():
|
|
|
|
return await Tortoise.close_connections()
|