diff --git a/server/admin/__main__.py b/server/admin/__main__.py
index bcd6874..0332c54 100644
--- a/server/admin/__main__.py
+++ b/server/admin/__main__.py
@@ -1,4 +1,3 @@
-
import flask_login
from flask import Response, redirect, render_template, request, url_for
from flask_admin import Admin, AdminIndexView, expose
@@ -40,14 +39,14 @@ async def get_file(raw_path: str):
cache_ctrl = "public, max-age=864000" # 10 дней
last_mod = attach[0].created_at.strftime("%a, %d %b %Y %H:%M:%S GMT")
- return Response(
- body,
- mimetype=attach[0].content_type,
- headers={
- "Cache-Control": cache_ctrl,
- "Last-Modified": last_mod,
- },
- )
+ return Response(
+ body,
+ mimetype=attach[0].content_type,
+ headers={
+ "Cache-Control": cache_ctrl,
+ "Last-Modified": last_mod,
+ },
+ )
@login_manager.user_loader
diff --git a/server/admin/config.py b/server/admin/config.py
index 000e357..a90eaaf 100644
--- a/server/admin/config.py
+++ b/server/admin/config.py
@@ -12,7 +12,7 @@ app.config["SQLALCHEMY_DATABASE_URI"] = (
app.config["SQLALCHEMY_ENGINE_OPTIONS"] = {
"pool_recycle": 600,
"pool_pre_ping": True,
- "pool_size": 5,
+ "pool_size": 30,
}
app.config["SECRET_KEY"] = cnf.admin_secret_key
app.config["SQLALCHEMY_ECHO"] = True
diff --git a/server/admin/views/attachments.py b/server/admin/views/attachments.py
index a6a1471..5222e2e 100644
--- a/server/admin/views/attachments.py
+++ b/server/admin/views/attachments.py
@@ -23,7 +23,7 @@ class AttachmentView(ModelView):
@staticmethod
def _list_thumbnail(view, _context, model, _name):
data = ""
- data += f'
'
+ data += f'
'
return Markup(data)
diff --git a/server/infra/db/pg.py b/server/infra/db/pg.py
index 24c93cc..2167e40 100644
--- a/server/infra/db/pg.py
+++ b/server/infra/db/pg.py
@@ -24,7 +24,7 @@ class AsyncDB(AbstractDB):
# self.engine.execution_options(stream_results=True)
if self.engine is None:
raise ConnectError
- session = asyncio.async_sessionmaker(self.engine, expire_on_commit=False)
+ session = asyncio.async_sessionmaker(self.engine, expire_on_commit=True)
if session is None:
raise ConnectError
self.async_session = session
@@ -35,13 +35,10 @@ class AsyncDB(AbstractDB):
@property
def session(self):
- return asyncio.async_sessionmaker(self.engine, expire_on_commit=False)
-
- def new_session(self):
- return asyncio.async_sessionmaker(self.engine, expire_on_commit=False)()
+ return asyncio.async_sessionmaker(self.engine, expire_on_commit=True)
def session_master(self):
- return self.new_session()
+ return self.async_session()
def session_slave(self):
- return self.new_session()
+ return self.async_session()
diff --git a/server/infra/web/__init__.py b/server/infra/web/__init__.py
index 469f7ab..2d646b5 100644
--- a/server/infra/web/__init__.py
+++ b/server/infra/web/__init__.py
@@ -1,6 +1,7 @@
+from server.infra.web.attachments import AtachmentController
from server.infra.web.description import DescriptionController
from server.infra.web.recognizer import BreedsController
from server.infra.web.seo import SeoController
from server.infra.web.vote import VoteController
-__all__ = ("DescriptionController", "SeoController", "BreedsController", "VoteController")
+__all__ = ("DescriptionController", "SeoController", "BreedsController", "VoteController", "AtachmentController")
diff --git a/server/infra/web/attachments.py b/server/infra/web/attachments.py
new file mode 100644
index 0000000..da0f05a
--- /dev/null
+++ b/server/infra/web/attachments.py
@@ -0,0 +1,35 @@
+import inject
+from litestar import Controller, get
+from litestar.exceptions import HTTPException
+from litestar.response import Response
+
+from server.modules.attachments import AtachmentService
+
+
+class AtachmentController(Controller):
+
+ @get("/attachments/{raw_path:path}", media_type="image/jpeg")
+ async def get_file(self, raw_path: str) -> Response:
+ attach_service: AtachmentService = inject.instance(AtachmentService)
+
+ attach_path = attach_service.path_from_url(raw_path)
+ # Query within session scope
+ attach = await attach_service.get_info_bypath(session=None, path=[attach_path])
+ if not attach:
+ raise HTTPException(status_code=404, detail="Attachment not found")
+
+ # Get file data (assuming async)
+ body = await attach_service.get_data(attach_path)
+
+ # Extract metadata within session scope
+ content_type = attach[0].content_type
+ last_mod = attach[0].created_at.strftime("%a, %d %b %Y %H:%M:%S GMT")
+
+ return Response(
+ content=body,
+ media_type=content_type,
+ headers={
+ "Cache-Control": "public, max-age=864000",
+ "Last-Modified": last_mod,
+ },
+ )
diff --git a/server/main.py b/server/main.py
index 6d9cc46..0744f07 100644
--- a/server/main.py
+++ b/server/main.py
@@ -12,7 +12,7 @@ from litestar.template.config import TemplateConfig
from server.config import get_app_config
from server.infra.db import AsyncDB
-from server.infra.web import BreedsController, DescriptionController, SeoController, VoteController
+from server.infra.web import AtachmentController, BreedsController, DescriptionController, SeoController, VoteController
from server.modules.attachments import AtachmentService, DBAttachmentRepository, S3StorageDriver
from server.modules.descriptions import CharactersService, PGCharactersRepository
from server.modules.rate import PGVoteRepository, VotesService
@@ -45,6 +45,7 @@ app = Litestar(
DescriptionController,
SeoController,
VoteController,
+ AtachmentController,
create_static_files_router(path="/static", directories=["server/static"]),
],
template_config=TemplateConfig(
diff --git a/server/modules/attachments/services/attachment.py b/server/modules/attachments/services/attachment.py
index 1e53142..0ae7b0a 100644
--- a/server/modules/attachments/services/attachment.py
+++ b/server/modules/attachments/services/attachment.py
@@ -237,7 +237,7 @@ class AtachmentService:
if ".original" not in url:
raise ValueError(f"wrong url: {url}")
parts = url.split(".original")[0]
- return f"/{parts}"
+ return parts
def url(self, attachment_id: str, content_type: str | None = None) -> str:
return f"{self._cnf.app_public_url}/api/v0/attachment/{attachment_id}.original.{self.extension(content_type)}"