добавил страницу шаринга
Gitea Actions Demo / build_and_push (push) Has been cancelled Details

This commit is contained in:
artem 2026-02-07 14:11:56 +03:00
parent 6a1bbb9a08
commit 3baab00f80
7 changed files with 84 additions and 7 deletions

View File

@ -1 +1 @@
cpython-3.13.5-linux-x86_64-gnu
cpython-3.13.12-linux-x86_64-gnu

View File

@ -14,7 +14,7 @@ format:
uv run ruff format
lint:
uv run mypy ./ --explicit-package-bases;
uv run mypy ./server --explicit-package-bases;
ruff check --fix
pipinstall:

View File

@ -3,11 +3,13 @@ from dataclasses import dataclass
from typing import Annotated
import inject
from litestar import Controller, Request, Response, post
from litestar import Controller, Request, Response, get, post
from litestar.datastructures import UploadFile
from litestar.enums import RequestEncodingType
from litestar.params import Body
from litestar.response import Template
from server.modules.attachments import AtachmentService
from server.modules.recognizer import RecognizerService
@ -49,3 +51,18 @@ class BreedsController(Controller):
body = await data.read()
result = await recognizer_service.predict_cat_image(body)
return result.to_serializable()
@get("/dogs/share/{result_id:str}")
async def beerds_share(self, result_id: str) -> Template:
recognizer_service: RecognizerService = inject.instance(RecognizerService)
result = await recognizer_service.get_results(result_id)
attach_service: AtachmentService = inject.instance(AtachmentService)
attachments = await attach_service.get_info_byid(session=None, attach_id= [result.attachment_id])
return Template(
template_name="share.html",
context={
"result": result,
"attachments": attachments,
},
)

View File

@ -1,7 +1,8 @@
from server.modules.descriptions.repository.repository import (
ACharactersRepository,
Breed,
CharactersRepository,
PGCharactersRepository,
)
__all__ = ("CharactersRepository", "ACharactersRepository", "PGCharactersRepository")
__all__ = ("CharactersRepository", "ACharactersRepository", "PGCharactersRepository", "Breed")

View File

@ -13,9 +13,9 @@ from sqlalchemy.orm import relationship
from server.config import get_app_config
from server.infra.db.db_mapper import mapper_registry
from server.modules.rate import domain
from server.modules.attachments.repository.attachments import Attachment
from server.modules.descriptions.repository.models import Beerds
from server.modules.rate import domain
@mapper_registry.mapped

View File

@ -14,7 +14,7 @@ import torch
from torchvision import transforms # type: ignore
from server.modules.attachments.domains.attachments import Attachment
from server.modules.descriptions.repository import ACharactersRepository
from server.modules.descriptions.repository import ACharactersRepository, Breed
from server.modules.recognizer.repository import ARecognizerRepository, models
TorchModel = NewType("TorchModel", torch.nn.Module)
@ -48,6 +48,17 @@ class RecognizerResult(UJsonMixin):
description: dict[str, list] | None
uploaded_attach_id: str | None
@dataclass
class SharingBeerds(UJsonMixin):
alias: str
name: str
images: list[ResultImages]
@dataclass
class SharingResult(UJsonMixin):
beerds: list[SharingBeerds]
attachment_id: str
class RecognizerService:
__slots__ = ("_repository", "_attachment_service", "_repository_characters")
@ -81,6 +92,22 @@ class RecognizerService:
[ch.id for ch in characters if ch.name in beerd_names],
)
async def get_results(self, result_id: str) -> SharingResult:
results = await self._repository.get_results()
beerds_store: dict[str, Breed] = {b.id: b for b in await self._repository_characters.get_characters()}
images_dogs = await self._repository.images_dogs()
for r in results:
if r.result.id != result_id:
continue
beers: list[SharingBeerds] = []
for beerd in r.beerds:
beers.append(SharingBeerds(
alias=beerds_store[beerd.beerd_id].alias,
name=beerds_store[beerd.beerd_id].name,
images = [ResultImages(name=beerds_store[beerd.beerd_id].name, url=[f"/static/assets/cat/{beerds_store[beerd.beerd_id].name}/{i}" for i in images_dogs[beerds_store[beerd.beerd_id].name.replace(" ", "_")]])]
))
return SharingResult(beerds=beers, attachment_id=r.result.attachment_id)
async def predict_dog_image(self, image: bytes, user_id: str, device_id: str | None) -> RecognizerResult:
if device_id is None:
device_id = "mobile"

View File

@ -0,0 +1,32 @@
{% extends "base.html" %}
{% block meta %}
<meta name="description" content="Определение породы кошки по фото бесплатно и без регистраций. Определение породы происходит при помощи нейронной сети - точность опеределения составляет 70%." />
{% endblock %}
{% block title %}Определение породы кошки по фото бесплатно{% endblock %}
{% block content %}
<h1>Определить породу кошки по фото</h1>
<p>Загрузите фото, чтобы опеределить породу собаки или щенка. Если порода смешанная (или порода определена неточно), после загрузки будет показана вероятность породы животного.</p>
<p>Определение породы происходит при помощи нейронной сети - точность опеределения составляет 60%, сеть обучена на 65 породах. Если на фото будет неизвестная порода будет предложено несколько похожих пород.</p>
{% endblock %}
{% block form %}
<div>
<div id="result">
<h3 class="image-results">Результаты</h3>
{% for result in result.beerds %}
<div class="image-block"><div class="image-text">{{ result.name }} (вероятность: {{ result.percent }}%) <br>{{ attachments[result.attachment_id].path }}<a href="{{ result.path }}" target="_blank">Описание и фото</a></div>
<div class="gallery-container">
<div class="main-image-container">
<img src="{{ result.images[0].path }}" class="main-image" data-urls="[&quot;/static/assets/dog/леонбергер/leonberger_140.webp&quot;,&quot;/static/assets/dog/леонбергер/leonberger_30.webp&quot;,&quot;/static/assets/dog/леонбергер/leonberger_47.webp&quot;,&quot;/static/assets/dog/леонбергер/leonberger_50.webp&quot;,&quot;/static/assets/dog/леонбергер/leonberger_82.webp&quot;]"></div>
<div class="thumbnails" style="display:none;">
{% for image in result.images %}
<img src="{{ image.path }}" class="thumbnail">
{% endfor %}
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}