diff --git a/pyproject.toml b/pyproject.toml
index 38a6d1a..c29afc2 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -21,6 +21,14 @@ dependencies = [
"torchvision>=0.24.1",
"types-requests>=2.32.4.20250913",
"types-markdown>=3.10.0.20251106",
+ "sqlalchemy>=2.0.44",
+ "inject>=5.3.0",
+ "aiofiles>=25.1.0",
+ "botocore>=1.42.9",
+ "types-aiofiles>=25.1.0.20251011",
+ "betterconf>=4.5.0",
+ "dataclasses-ujson>=0.0.34",
+ "asyncpg>=0.31.0",
]
[project.optional-dependencies]
@@ -49,7 +57,3 @@ name = "pytorch-cpu"
url = "https://download.pytorch.org/whl/cpu"
explicit = true
-[tool.uv.workspace]
-members = [
- "kivy",
-]
diff --git a/server/config/__init__.py b/server/config/__init__.py
new file mode 100644
index 0000000..2ed1a49
--- /dev/null
+++ b/server/config/__init__.py
@@ -0,0 +1,41 @@
+"""Config for application"""
+
+from functools import lru_cache
+
+from betterconf import betterconf, field
+from betterconf.caster import to_bool, to_int, to_list
+
+
+@betterconf
+class AppConfig:
+ # pylint: disable=R0903
+ """
+ Class of configuration the application
+ """
+
+ app_debug: bool = field("APP_DEBUG", default=False, caster=to_bool)
+ app_origin: list = field("APP_ORIGIN", default=[], caster=to_list)
+ app_host: str = field("APP_HOST", default="0.0.0.0")
+ app_port: int = field("APP_PORT", default=8000, caster=to_int)
+ app_public_url: str = field("APP_PUBLIC_URL", default="http://127.0.0.1:8000")
+
+ sentry_dns: str = field("SENTRY_DNS", default="")
+ log_level: str = field("LOG_LEVEL", "INFO")
+
+ db_uri: str = field(
+ "DB_URI", "postgresql+asyncpg://svcuser:svcpass@localhost:5432/svc"
+ )
+ db_pass_salt: str = field("DB_PASS_SALT", "")
+ db_search_path: str = field("DB_SEARCH_PATH", "public")
+
+ fs_local_mount_dir: str = field("FS_LOCAL_MOUNT_DIR", default="./tmp/files")
+ fs_s3_bucket: str = field("FS_S3_BUCKET", "")
+ fs_s3_access_key_id: str = field("FS_ACCESS_KEY_ID", "")
+ fs_s3_access_key: str = field("FS_SECRET_ACCESS_KEY", "")
+ fs_s3_endpoint: str = field("FS_S3_ENDPOINT", "")
+
+
+@lru_cache
+def get_app_config() -> AppConfig:
+ # pylint: disable=C0116
+ return AppConfig()
diff --git a/server/services/__init__.py b/server/infra/__init__.py
similarity index 100%
rename from server/services/__init__.py
rename to server/infra/__init__.py
diff --git a/server/infra/cache.py b/server/infra/cache.py
new file mode 100644
index 0000000..14e6aae
--- /dev/null
+++ b/server/infra/cache.py
@@ -0,0 +1,33 @@
+from abc import ABCMeta, abstractmethod
+from typing import Optional
+
+
+class CacheRepository(metaclass=ABCMeta):
+ @abstractmethod
+ async def get(self, key: str) -> Optional[str]:
+ pass
+
+ @abstractmethod
+ async def set(self, key: str, data: str, _exp_min: Optional[int] = None):
+ pass
+
+ @abstractmethod
+ async def delete(self, key: str):
+ pass
+
+
+# TODO: сделать через общий кеш, например, redis. Работу с редис вынести в infra
+class LocalCacheRepository(CacheRepository):
+ _data: dict[str, str]
+
+ def __init__(self) -> None:
+ self._data = {}
+
+ async def get(self, key: str) -> Optional[str]:
+ return self._data.get(key)
+
+ async def set(self, key: str, data: str, _exp_min: Optional[int] = None):
+ self._data[key] = data
+
+ async def delete(self, key: str):
+ del self._data[key]
diff --git a/server/infra/db/__init__.py b/server/infra/db/__init__.py
new file mode 100644
index 0000000..5771c10
--- /dev/null
+++ b/server/infra/db/__init__.py
@@ -0,0 +1,12 @@
+from server.infra.db.abc import AbstractDB, AbstractSession, ExecuteFun
+from server.infra.db.mock import MockDB, MockSession
+from server.infra.db.pg import AsyncDB
+
+__all__ = [
+ "AsyncDB",
+ "AbstractDB",
+ "ExecuteFun",
+ "AbstractSession",
+ "MockDB",
+ "MockSession",
+]
diff --git a/server/infra/db/abc.py b/server/infra/db/abc.py
new file mode 100644
index 0000000..1c3f0e5
--- /dev/null
+++ b/server/infra/db/abc.py
@@ -0,0 +1,41 @@
+"""Abstract realiztion for DB"""
+
+from typing import Any, AsyncContextManager, Awaitable, Callable, TypeAlias
+
+from server.config import AppConfig
+
+ExecuteFun: TypeAlias = Callable[[Any], Awaitable[None]]
+
+
+class ConnectError(Exception):
+ """Custom error wor failed connections"""
+
+
+class AbstractSession:
+ async def __aenter__(self) -> "AbstractSession":
+ raise NotImplementedError
+
+ async def __aexit__(self, exc_type, exc, tb):
+ raise NotImplementedError
+
+ def begin(self) -> AsyncContextManager:
+ raise NotImplementedError
+
+ async def execute(self, data: Any):
+ raise NotImplementedError
+
+ async def commit(self):
+ raise NotImplementedError
+
+
+class AbstractDB:
+ """Abstract realiztion for DB"""
+
+ def __init__(self, cnf: AppConfig):
+ raise NotImplementedError
+
+ def session_master(self) -> AbstractSession:
+ raise NotImplementedError
+
+ def session_slave(self) -> AbstractSession:
+ raise NotImplementedError
diff --git a/server/infra/db/db_mapper.py b/server/infra/db/db_mapper.py
new file mode 100644
index 0000000..37eec4a
--- /dev/null
+++ b/server/infra/db/db_mapper.py
@@ -0,0 +1,11 @@
+from typing import Type, TypeVar
+
+from sqlalchemy.orm import registry
+
+mapper_registry = registry()
+
+DC = TypeVar("DC")
+
+
+def dict_to_dataclass(data: dict, class_type: Type[DC]) -> DC:
+ return class_type(**data)
diff --git a/server/infra/db/mock.py b/server/infra/db/mock.py
new file mode 100644
index 0000000..2f8b334
--- /dev/null
+++ b/server/infra/db/mock.py
@@ -0,0 +1,45 @@
+from typing import Any, AsyncContextManager
+
+from server.config import AppConfig
+from server.infra.db.abc import AbstractDB, AbstractSession
+
+
+class MockBeginSession(AbstractSession):
+ async def __aenter__(self):
+ pass
+
+ async def __aexit__(self, exc_type, exc, tb):
+ pass
+
+
+class MockSession(AbstractSession):
+ async def __aenter__(self) -> "AbstractSession":
+ return self
+
+ async def __aexit__(self, exc_type, exc, tb):
+ pass
+
+ def begin(self) -> AsyncContextManager:
+ return MockBeginSession()
+
+ async def execute(self, data: Any):
+ pass
+
+ async def commit(self):
+ pass
+
+
+class MockDB(AbstractDB):
+ """Mock realiztion for DB"""
+
+ def __init__(self, cnf: AppConfig):
+ pass
+
+ async def __aenter__(self):
+ pass
+
+ async def __aenxit__(self, exc_type, exc, tb):
+ pass
+
+ def session(self) -> MockSession:
+ return MockSession()
diff --git a/server/infra/db/pg.py b/server/infra/db/pg.py
new file mode 100644
index 0000000..3128a36
--- /dev/null
+++ b/server/infra/db/pg.py
@@ -0,0 +1,41 @@
+"""Postgres DB realization"""
+
+from sqlalchemy.ext import asyncio
+
+from server.config import AppConfig
+from server.infra.db.abc import AbstractDB, ConnectError
+
+
+class AsyncDB(AbstractDB):
+ engine: asyncio.AsyncEngine
+ async_session: asyncio.async_sessionmaker[asyncio.AsyncSession]
+
+ def __init__(self, cnf: AppConfig):
+ con_arg = {}
+ if "postgresql+asyncpg" in str(cnf.db_uri):
+ con_arg = {"server_settings": {"search_path": cnf.db_search_path}}
+ self.engine = asyncio.create_async_engine(
+ str(cnf.db_uri),
+ echo=bool(cnf.app_debug),
+ connect_args=con_arg,
+ pool_recycle=1800,
+ )
+
+ # self.engine.execution_options(stream_results=True)
+ if self.engine is None:
+ raise ConnectError
+ session = asyncio.async_sessionmaker(self.engine, expire_on_commit=False)
+ if session is None:
+ raise ConnectError
+ self.async_session = session
+
+ async def connect(self):
+ """connect with DB"""
+ pass
+
+ @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)()
diff --git a/server/infra/logger/__init__.py b/server/infra/logger/__init__.py
new file mode 100644
index 0000000..233bba6
--- /dev/null
+++ b/server/infra/logger/__init__.py
@@ -0,0 +1,76 @@
+"""The logger configuration"""
+
+import logging
+from logging import config as log_config
+
+from server import config
+
+cnf = config.get_app_config()
+
+
+LOGGING_CONFIG = {
+ "version": 1,
+ "disable_existing_loggers": True,
+ "formatters": {
+ "standard": {
+ "use_colors": True,
+ "format": "%(filename)s:%(lineno)d -> %(asctime)s [%(levelname)s]: %(message)s",
+ },
+ "uvicorn_default": {
+ "()": "uvicorn.logging.DefaultFormatter",
+ "format": "%(levelprefix)s %(message)s",
+ "use_colors": True,
+ },
+ "uvicorn_access": {
+ "()": "uvicorn.logging.AccessFormatter",
+ "format": '%(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s', # noqa: E501
+ },
+ },
+ "handlers": {
+ "default": {
+ "level": cnf.log_level,
+ "formatter": "standard",
+ "class": "logging.StreamHandler",
+ "stream": "ext://sys.stdout",
+ },
+ "sentry": {
+ "level": "ERROR",
+ "class": "sentry_sdk.integrations.logging.EventHandler",
+ },
+ "uvicorn_default": {
+ "level": "INFO",
+ "formatter": "uvicorn_default",
+ "class": "logging.StreamHandler",
+ "stream": "ext://sys.stdout",
+ },
+ "uvicorn_access": {
+ "level": "INFO",
+ "formatter": "uvicorn_access",
+ "class": "logging.StreamHandler",
+ "stream": "ext://sys.stdout",
+ },
+ },
+ "loggers": {
+ "": {"handlers": ["default"], "level": cnf.log_level, "propagate": False},
+ "uvicorn.access": {
+ "handlers": ["uvicorn_access"],
+ "level": "INFO",
+ "propagate": False,
+ },
+ "uvicorn.error": {
+ "handlers": ["uvicorn_default"],
+ "level": "INFO",
+ "propagate": False,
+ },
+ "uvicorn.asgi": {
+ "handlers": ["uvicorn_default"],
+ "level": "INFO",
+ "propagate": False,
+ },
+ },
+}
+
+
+def get_logger() -> logging.Logger:
+ log_config.dictConfig(LOGGING_CONFIG)
+ return logging.getLogger()
diff --git a/server/infra/tools/__init__.py b/server/infra/tools/__init__.py
new file mode 100644
index 0000000..62fbae8
--- /dev/null
+++ b/server/infra/tools/__init__.py
@@ -0,0 +1,21 @@
+from server.infra.tools.db.filter import (
+ Filter,
+ FilterLeftField,
+ FilterQuery,
+ FilterSign,
+ data_by_filter,
+ indexes_by_id,
+ sqlalchemy_conditions,
+ sqlalchemy_restrictions,
+)
+
+__all__ = [
+ "FilterSign",
+ "FilterLeftField",
+ "Filter",
+ "FilterQuery",
+ "data_by_filter",
+ "sqlalchemy_conditions",
+ "indexes_by_id",
+ "sqlalchemy_restrictions",
+]
diff --git a/server/services/recognizer/domain.py b/server/infra/tools/db/__init__.py
similarity index 100%
rename from server/services/recognizer/domain.py
rename to server/infra/tools/db/__init__.py
diff --git a/server/infra/tools/db/filter.py b/server/infra/tools/db/filter.py
new file mode 100644
index 0000000..3ac0498
--- /dev/null
+++ b/server/infra/tools/db/filter.py
@@ -0,0 +1,303 @@
+from copy import copy
+from dataclasses import Field, asdict, dataclass
+from enum import Enum
+from typing import Any, ClassVar, Optional, Protocol, assert_never
+
+from sqlalchemy import Select, and_, or_
+
+
+class FilterSign(Enum):
+ NOT_EQ = "not_eq"
+ EQ = "eq"
+ LT = "lt"
+ LE = "le"
+ GT = "gt"
+ GE = "ge"
+ IS = "is"
+ IS_NOT = "is_not"
+ OR = "or"
+ AND = "and"
+ IN = "in"
+
+
+class FilterLeftField(Protocol):
+ name: str
+
+
+@dataclass(frozen=True)
+class Filter:
+ right: Any
+ sign: FilterSign
+ left: Optional[FilterLeftField] = None
+
+ @staticmethod
+ def not_eq(f1: Any, f2: Any):
+ return Filter(left=f1, right=f2, sign=FilterSign.NOT_EQ)
+
+ @staticmethod
+ def eq(f1: Any, f2: Any):
+ return Filter(left=f1, right=f2, sign=FilterSign.EQ)
+
+ @staticmethod
+ def lt(f1: Any, f2: Any):
+ return Filter(left=f1, right=f2, sign=FilterSign.LT)
+
+ @staticmethod
+ def le(f1: Any, f2: Any):
+ return Filter(left=f1, right=f2, sign=FilterSign.LE)
+
+ @staticmethod
+ def gt(f1: Any, f2: Any):
+ return Filter(left=f1, right=f2, sign=FilterSign.GT)
+
+ @staticmethod
+ def ge(f1: Any, f2: Any):
+ return Filter(left=f1, right=f2, sign=FilterSign.GE)
+
+ @staticmethod
+ def is_none(f1: Any):
+ return Filter(left=f1, right=None, sign=FilterSign.IS_NOT)
+
+ @staticmethod
+ def is_not_none(f1: Any):
+ return Filter(left=f1, right=None, sign=FilterSign.IS)
+
+ @staticmethod
+ def or_(f1: list["Filter"]):
+ return Filter(left=None, right=f1, sign=FilterSign.OR)
+
+ @staticmethod
+ def in_(f1: Any, f2: list[Any]):
+ return Filter(left=f1, right=f2, sign=FilterSign.IN)
+
+
+@dataclass
+class RestrictionField:
+ field: Any
+ direction: str
+
+
+@dataclass
+class QueryRestriction:
+ filters: Optional[list[Filter]] = None
+ limit: Optional[int] = None
+ offset: Optional[int] = None
+ sort: Optional[list[RestrictionField]] = None
+
+
+@dataclass(frozen=False)
+class FilterQuery:
+ filters: list[Filter]
+ limit: Optional[int] = None
+ offset: Optional[int] = None
+ sort: Optional[list[RestrictionField]] = None
+
+ @staticmethod
+ def mass_and(fields: list[object], values: list[Any]) -> "FilterQuery":
+ return FilterQuery(
+ filters=[Filter.eq(field, val) for field, val in zip(fields, values)]
+ )
+
+ @staticmethod
+ def mass_or(fields: list[object], values: list[Any]) -> "FilterQuery":
+ return FilterQuery(
+ filters=[
+ Filter.or_(
+ [Filter.eq(field, val) for field, val in zip(fields, values)]
+ )
+ ]
+ )
+
+ @staticmethod
+ def eq(field: object, value: Any) -> "FilterQuery":
+ return FilterQuery(filters=[Filter.eq(field, value)])
+
+ @staticmethod
+ def in_(field: object, value: list[Any]) -> "FilterQuery":
+ return FilterQuery(filters=[Filter.in_(field, value)])
+
+ def add_and(self, field: object, value: Any):
+ self.filters.append(Filter.eq(field, value))
+
+ def add_query_restistions(self, q_restriction: Optional[QueryRestriction] = None):
+ if not q_restriction:
+ return None
+ if q_restriction.limit:
+ self.limit = q_restriction.limit
+ if q_restriction.offset:
+ self.offset = q_restriction.offset
+ if q_restriction.sort:
+ self.sort = q_restriction.sort
+ if q_restriction.filters:
+ self.filters += q_restriction.filters
+ return None
+
+
+class DataclassInstance(Protocol):
+ __dataclass_fields__: ClassVar[dict[str, Field[Any]]]
+
+
+async def indexes_by_id(
+ input_data: list, values: list[str], id_name="id"
+) -> Optional[list[int]]:
+ r_data: list[int] = []
+ for i, _ in enumerate(input_data):
+ if getattr(input_data[i], id_name) in values:
+ r_data.append(i)
+ if not r_data:
+ return None
+ return r_data
+
+
+def data_by_filter[T: DataclassInstance](
+ input_data: list[T], q: FilterQuery
+) -> list[T]:
+ # can't do query AND(OR() + AND())
+ data: list[T] = []
+ data_or: list[T] = []
+ data_and: list[T] = []
+ is_found = False
+ for d in input_data:
+ dict_class = asdict(d)
+ for f in q.filters:
+ if f.sign == FilterSign.OR:
+ for f_or in f.right:
+ data_or += data_by_filter(input_data, q=FilterQuery(filters=[f_or]))
+ continue
+ if f.sign == FilterSign.AND:
+ data_and += data_by_filter(input_data, q=FilterQuery(filters=f.right))
+ continue
+ if f.left is None:
+ continue
+ if f.sign != FilterSign.IS and dict_class.get(f.left.name) is None:
+ break
+ if f.sign != FilterSign.IS_NOT and dict_class.get(f.left.name) is None:
+ break
+ match f.sign:
+ case FilterSign.NOT_EQ:
+ is_found = dict_class.get(f.left.name) != f.right
+ if is_found:
+ continue
+ break
+ case FilterSign.EQ:
+ is_found = dict_class.get(f.left.name) == f.right
+ if is_found:
+ continue
+ break
+ case FilterSign.LT:
+ is_found = dict_class.get(f.left.name) < f.right
+ if is_found:
+ continue
+ break
+ case FilterSign.LE:
+ is_found = dict_class.get(f.left.name) <= f.right
+ if is_found:
+ continue
+ break
+ case FilterSign.GT:
+ is_found = dict_class.get(f.left.name) > f.right
+ if is_found:
+ continue
+ break
+ case FilterSign.GE:
+ is_found = dict_class.get(f.left.name) >= f.right
+ if is_found:
+ continue
+ break
+ case FilterSign.IS:
+ is_found = dict_class.get(f.left.name) is None
+ if is_found:
+ continue
+ break
+ case FilterSign.IS_NOT:
+ is_found = dict_class.get(f.left.name) is not None
+ if is_found:
+ continue
+ break
+ case FilterSign.IN:
+ is_found = dict_class.get(f.left.name) in f.right
+ if is_found:
+ continue
+ break
+ case _ as arg:
+ assert_never(arg)
+ if is_found:
+ data.append(copy(d))
+ if q.limit:
+ limit = q.limit
+ if limit > len(data) - 1:
+ limit = len(data) - 1
+ return data[:limit]
+ if data_and:
+ if not data:
+ data = data_and
+ else:
+ data = list(set(data) & set(data_and))
+ if data_or:
+ if not data:
+ data = data_or
+ else:
+ data = list(set(data) & set(data_or))
+ return data
+
+
+def sqlalchemy_conditions(q: FilterQuery):
+ conditions = []
+ for f in q.filters:
+ if f.sign == FilterSign.OR:
+ conditions.append(
+ or_(*sqlalchemy_conditions(q=FilterQuery(filters=f.right)))
+ )
+ continue
+ if f.sign == FilterSign.AND:
+ conditions.append(
+ and_(*sqlalchemy_conditions(q=FilterQuery(filters=f.right)))
+ )
+ continue
+ if f.left is None:
+ continue
+ match f.sign:
+ case FilterSign.NOT_EQ:
+ conditions.append(f.left != f.right)
+ case FilterSign.EQ:
+ conditions.append(f.left == f.right)
+ case FilterSign.LT:
+ conditions.append(f.left < f.right)
+ case FilterSign.LE:
+ if f.left is None:
+ continue
+ conditions.append(f.left <= f.right)
+ case FilterSign.GT:
+ conditions.append(f.left > f.right)
+ case FilterSign.GE:
+ conditions.append(f.left >= f.right)
+ case FilterSign.IS:
+ conditions.append(f.left.is_(None)) # type: ignore
+ case FilterSign.IS_NOT:
+ conditions.append(f.left.is_not(None)) # type: ignore
+ case FilterSign.IN:
+ conditions.append(f.left.in_(f.right)) # type: ignore
+ case _ as arg:
+ assert_never(arg)
+ return conditions
+
+
+def sqlalchemy_restrictions(
+ f: FilterQuery, q: Select, dict_to_sort: Optional[dict] = None
+) -> Select:
+ if f.limit:
+ q = q.limit(f.limit)
+ if f.offset:
+ q = q.offset(f.offset)
+ if f.sort:
+ for s in f.sort:
+ field = s.field
+ if dict_to_sort and str(s.field) in dict_to_sort:
+ if s.direction == "desc":
+ q = q.order_by(dict_to_sort[str(s.field)].desc()) # type: ignore
+ continue
+ return q.order_by(dict_to_sort[str(s.field)]) # type: ignore
+ if s.direction == "desc":
+ field = s.field.desc() # type: ignore
+ q = q.order_by(field) # type: ignore
+ return q
diff --git a/server/infra/web/__init__.py b/server/infra/web/__init__.py
new file mode 100644
index 0000000..6e1fbe6
--- /dev/null
+++ b/server/infra/web/__init__.py
@@ -0,0 +1,5 @@
+from server.infra.web.description import DescriptionController
+from server.infra.web.seo import SeoController
+from server.infra.web.recognizer import BreedsController
+
+__all__ = ("DescriptionController", "SeoController", "BreedsController")
diff --git a/server/infra/web/description.py b/server/infra/web/description.py
new file mode 100644
index 0000000..37d79bf
--- /dev/null
+++ b/server/infra/web/description.py
@@ -0,0 +1,56 @@
+import inject
+import markdown
+from litestar import (
+ Controller,
+ get,
+)
+from litestar.exceptions import HTTPException
+from litestar.response import Template
+
+from server.modules.descriptions import CharactersService
+from server.modules.recognizer import RecognizerService
+
+
+class DescriptionController(Controller):
+ path = "/"
+
+ @get("/")
+ async def dogs(self) -> Template:
+ return Template(template_name="dogs.html")
+
+ @get("/cats")
+ async def cats(self) -> Template:
+ return Template(template_name="cats.html")
+
+ @get("/contacts")
+ async def contacts(self) -> Template:
+ return Template(template_name="contacts.html")
+
+ @get("/donate")
+ async def donate(self) -> Template:
+ return Template(template_name="donate.html")
+
+ @get("/dogs-characteristics")
+ async def dogs_characteristics(self) -> Template:
+ characters_service: CharactersService = inject.instance(CharactersService)
+ breeds = await characters_service.get_characters()
+ return Template(
+ template_name="dogs-characteristics.html", context={"breeds": breeds}
+ )
+
+ @get("/dogs-characteristics/{name:str}")
+ async def beer_description(self, name: str) -> Template:
+ characters_service: CharactersService = inject.instance(CharactersService)
+ breed = await characters_service.get_character(name)
+ if breed is None:
+ raise HTTPException(status_code=404, detail="Порода не найдена")
+ recognizer_service: RecognizerService = inject.instance(RecognizerService)
+ images = await recognizer_service.images_dogs()
+ return Template(
+ template_name="beers-description.html",
+ context={
+ "text": markdown.markdown(breed.description),
+ "title": breed.name,
+ "images": [f"/static/assets/dog/{name}/{i}" for i in images[name]],
+ },
+ )
diff --git a/server/infra/web/recognizer.py b/server/infra/web/recognizer.py
new file mode 100644
index 0000000..2481bde
--- /dev/null
+++ b/server/infra/web/recognizer.py
@@ -0,0 +1,30 @@
+import inject
+from litestar import (
+ Controller,
+ post,
+)
+from litestar.enums import RequestEncodingType
+from litestar.datastructures import UploadFile
+from litestar.params import Body
+
+from server.modules.recognizer import RecognizerService
+
+
+class BreedsController(Controller):
+ path = "/beerds"
+
+ @post("/dogs")
+ async def beerds_dogs(
+ self, data: UploadFile = Body(media_type=RequestEncodingType.MULTI_PART)
+ ) -> dict:
+ recognizer_service: RecognizerService = inject.instance(RecognizerService)
+ body = await data.read()
+ return await recognizer_service.predict_dog_image(body)
+
+ @post("/cats")
+ async def beerds_cats(
+ self, data: UploadFile = Body(media_type=RequestEncodingType.MULTI_PART)
+ ) -> dict:
+ recognizer_service: RecognizerService = inject.instance(RecognizerService)
+ body = await data.read()
+ return await recognizer_service.predict_cat_image(body)
diff --git a/server/infra/web/seo.py b/server/infra/web/seo.py
new file mode 100644
index 0000000..caf6566
--- /dev/null
+++ b/server/infra/web/seo.py
@@ -0,0 +1,62 @@
+import inject
+from litestar import (
+ Controller,
+ get,
+ MediaType,
+)
+
+from server.modules.descriptions import CharactersService, Breed
+
+
+class SeoController(Controller):
+ @get("/sitemap.xml", media_type=MediaType.XML)
+ async def sitemaps(self) -> bytes:
+ characters_service: CharactersService = inject.instance(CharactersService)
+ breeds: list[Breed] = await characters_service.get_characters()
+ lastmod = "2025-10-04T19:01:03+00:00"
+ beers_url = ""
+ for b in breeds:
+ beers_url += f"""
+
+ https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/dogs-characteristics/{b.alias}
+ {lastmod}
+
+"""
+ return f"""
+
+
+
+
+
+ https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/
+ {lastmod}
+
+
+ https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/cats
+ {lastmod}
+
+
+ https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/donate
+ {lastmod}
+
+
+ https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/dogs-characteristics
+ {lastmod}
+
+{beers_url}
+
+
+""".encode()
+
+ @get("/robots.txt", media_type=MediaType.TEXT)
+ async def robots(self) -> str:
+ return """
+User-agent: *
+Allow: /
+
+Sitemap: https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/sitemap.xml
+"""
diff --git a/server/main.py b/server/main.py
index fccdf5f..99cd273 100644
--- a/server/main.py
+++ b/server/main.py
@@ -1,150 +1,44 @@
+import asyncio
from pathlib import Path
import os
-import markdown
+import inject
from litestar import (
- Controller,
- get,
- post,
- MediaType,
Litestar,
)
-from litestar.enums import RequestEncodingType
-from litestar.datastructures import UploadFile
-from litestar.params import Body
-from litestar.exceptions import HTTPException
from litestar.contrib.jinja import JinjaTemplateEngine
from litestar.template.config import TemplateConfig
-from litestar.response import Template
from litestar.static_files import create_static_files_router
-
-from server.services.descriptions import CharactersService, Breed, CharactersRepository
-from server.services.recognizer import RecognizerService, RecognizerRepository
+from server.config import get_app_config
+from server.infra.web import BreedsController, DescriptionController, SeoController
+from server.infra.db import AsyncDB
+from server.modules.descriptions import CharactersService, CharactersRepository
+from server.modules.recognizer import RecognizerService, RecognizerRepository
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
-recognizer_service = RecognizerService(RecognizerRepository())
-characters_service = CharactersService(CharactersRepository())
+loop = asyncio.new_event_loop()
-class BreedsController(Controller):
- path = "/beerds"
+def inject_config(binder: inject.Binder):
+ """initialization inject_config for server FastApi"""
- @post("/dogs")
- async def beerds_dogs(
- self, data: UploadFile = Body(media_type=RequestEncodingType.MULTI_PART)
- ) -> dict:
- body = await data.read()
- return await recognizer_service.predict_dog_image(body)
-
- @post("/cats")
- async def beerds_cats(
- self, data: UploadFile = Body(media_type=RequestEncodingType.MULTI_PART)
- ) -> dict:
- body = await data.read()
- return await recognizer_service.predict_cat_image(body)
-
-
-class DescriptionController(Controller):
- path = "/"
-
- @get("/")
- async def dogs(self) -> Template:
- return Template(template_name="dogs.html")
-
- @get("/cats")
- async def cats(self) -> Template:
- return Template(template_name="cats.html")
-
- @get("/contacts")
- async def contacts(self) -> Template:
- return Template(template_name="contacts.html")
-
- @get("/donate")
- async def donate(self) -> Template:
- return Template(template_name="donate.html")
-
- @get("/dogs-characteristics")
- async def dogs_characteristics(self) -> Template:
- breeds = await characters_service.get_characters()
- return Template(
- template_name="dogs-characteristics.html", context={"breeds": breeds}
- )
-
- @get("/dogs-characteristics/{name:str}")
- async def beer_description(self, name: str) -> Template:
- breed = await characters_service.get_character(name)
- if breed is None:
- raise HTTPException(status_code=404, detail="Порода не найдена")
- images = await recognizer_service.images_dogs()
- return Template(
- template_name="beers-description.html",
- context={
- "text": markdown.markdown(breed.description),
- "title": breed.name,
- "images": [f"/static/assets/dog/{name}/{i}" for i in images[name]],
- },
- )
-
- @get("/sitemap.xml", media_type=MediaType.XML)
- async def sitemaps(self) -> bytes:
- breeds: list[Breed] = await characters_service.get_characters()
- lastmod = "2025-10-04T19:01:03+00:00"
- beers_url = ""
- for b in breeds:
- beers_url += f"""
-
- https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/dogs-characteristics/{b.alias}
- {lastmod}
-
-"""
- return f"""
-
-
-
-
-
- https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/
- {lastmod}
-
-
- https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/cats
- {lastmod}
-
-
- https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/donate
- {lastmod}
-
-
- https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/dogs-characteristics
- {lastmod}
-
-{beers_url}
-
-
-""".encode()
-
- @get("/robots.txt", media_type=MediaType.TEXT)
- async def robots(self) -> str:
- return """
-User-agent: *
-Allow: /
-
-Sitemap: https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/sitemap.xml
-"""
+ cnf = get_app_config()
+ db = AsyncDB(cnf)
+ loop.run_until_complete(db.connect())
+ binder.bind(RecognizerService, RecognizerService(RecognizerRepository()))
+ binder.bind(CharactersService, CharactersService(CharactersRepository()))
+inject.configure(inject_config)
app = Litestar(
debug=True,
route_handlers=[
BreedsController,
DescriptionController,
+ SeoController,
create_static_files_router(path="/static", directories=["server/static"]),
],
template_config=TemplateConfig(
diff --git a/server/modules/__init__.py b/server/modules/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/server/modules/attachments/__init__.py b/server/modules/attachments/__init__.py
new file mode 100644
index 0000000..9830d62
--- /dev/null
+++ b/server/modules/attachments/__init__.py
@@ -0,0 +1,31 @@
+"""
+Working with media files - uploading, storing, receiving
+"""
+
+from server.modules.attachments.domains.attachments import Attachment
+from server.modules.attachments.repositories.attachments import (
+ AttachmentRepository,
+ DBAttachmentRepository,
+ MockAttachmentRepository,
+)
+from server.modules.attachments.services.attachment import (
+ AtachmentService,
+ LocalStorageDriver,
+ MediaType,
+ MockStorageDriver,
+ S3StorageDriver,
+ StorageDriversType,
+)
+
+__all__ = [
+ "AtachmentService",
+ "Attachment",
+ "AttachmentRepository",
+ "MockAttachmentRepository",
+ "DBAttachmentRepository",
+ "LocalStorageDriver",
+ "MockStorageDriver",
+ "S3StorageDriver",
+ "MediaType",
+ "StorageDriversType",
+]
diff --git a/server/modules/attachments/domains/__init__.py b/server/modules/attachments/domains/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/server/modules/attachments/domains/attachments.py b/server/modules/attachments/domains/attachments.py
new file mode 100644
index 0000000..0d79639
--- /dev/null
+++ b/server/modules/attachments/domains/attachments.py
@@ -0,0 +1,18 @@
+from dataclasses import dataclass
+from datetime import datetime
+
+from dataclasses_ujson.dataclasses_ujson import UJsonMixin # type: ignore
+
+
+@dataclass(frozen=True)
+class Attachment(UJsonMixin):
+ id: str
+ created_at: datetime
+ updated_at: datetime
+ size: int
+ storage_driver_name: str
+ path: str
+ media_type: str
+ created_by: str
+ content_type: str
+ is_deleted: bool = False
diff --git a/server/modules/attachments/repositories/__init__.py b/server/modules/attachments/repositories/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/server/modules/attachments/repositories/attachments.py b/server/modules/attachments/repositories/attachments.py
new file mode 100644
index 0000000..69b235e
--- /dev/null
+++ b/server/modules/attachments/repositories/attachments.py
@@ -0,0 +1,161 @@
+from abc import ABCMeta, abstractmethod
+from datetime import UTC, datetime
+from typing import Tuple
+
+from sqlalchemy import CursorResult, delete, insert, select, update
+
+from server.config import get_app_config
+from server.infra.db import AbstractDB, AbstractSession, AsyncDB, MockDB
+from server.modules.attachments.domains.attachments import Attachment
+
+
+class AttachmentRepository(metaclass=ABCMeta):
+ @abstractmethod
+ async def get_by_id(
+ self, session: AbstractSession, attach_id: list[str]
+ ) -> list[Attachment]:
+ """Get Attachment by ID"""
+ pass
+
+ @abstractmethod
+ async def create(self, data: Attachment):
+ """Create entry in DB"""
+ pass
+
+ @abstractmethod
+ async def delete(self, attach_id: str):
+ """Get Attachment by ID"""
+ pass
+
+ @abstractmethod
+ async def update(self, attach_id: str, **kwargs):
+ pass
+
+ @abstractmethod
+ def db(self) -> AbstractDB:
+ pass
+
+
+class MockAttachmentRepository(AttachmentRepository):
+ _data: dict[str, Attachment]
+
+ def __init__(self):
+ self._data = {
+ "jian4": Attachment(
+ id="jian4",
+ size=0,
+ storage_driver_name="mock",
+ path="jian4",
+ media_type="audio",
+ created_by="created_by",
+ content_type="audio/mp3",
+ ),
+ "zai4": Attachment(
+ id="zai4",
+ size=0,
+ storage_driver_name="mock",
+ path="zai4",
+ media_type="audio",
+ created_by="created_by",
+ content_type="audio/mp3",
+ ),
+ "cheng2": Attachment(
+ id="cheng2",
+ size=0,
+ storage_driver_name="mock",
+ path="cheng2",
+ media_type="audio",
+ created_by="created_by",
+ content_type="audio/mp3",
+ ),
+ "shi4": Attachment(
+ id="shi4",
+ size=0,
+ storage_driver_name="mock",
+ path="shi4",
+ media_type="audio",
+ created_by="created_by",
+ content_type="audio/mp3",
+ ),
+ "nv3": Attachment(
+ id="nv3",
+ size=0,
+ storage_driver_name="mock",
+ path="nv3",
+ media_type="audio",
+ created_by="created_by",
+ content_type="audio/mp3",
+ ),
+ }
+ self._db = MockDB(get_app_config())
+
+ async def get_by_id(
+ self, session: AbstractSession, attach_id: list[str]
+ ) -> list[Attachment]:
+ f: list[Attachment] = []
+ for f_id in attach_id:
+ f_item = self._data.get(f_id)
+ if f_item is None:
+ continue
+ f.append(f_item)
+ return f
+
+ async def create(self, data: Attachment):
+ self._data[data.id] = data
+
+ async def delete(self, attach_id: str):
+ del self._data[attach_id]
+
+ async def update(self, attach_id: str, **kwargs):
+ pass
+
+ def db(self) -> AbstractDB:
+ return self._db
+
+
+class DBAttachmentRepository(AttachmentRepository):
+ _db: AsyncDB
+
+ def __init__(self, db: AsyncDB):
+ self._db = db
+
+ async def get_by_id(
+ self, session: AbstractSession, attach_id: list[str]
+ ) -> list[Attachment]:
+ q = select(Attachment).where(
+ Attachment.id.in_(attach_id) # type: ignore
+ )
+ attachment: list[Attachment] = []
+ result: CursorResult[Tuple[Attachment]] = await session.execute(q) # type: ignore
+ for d in result.all():
+ attachment.append(d[0])
+ return attachment
+
+ async def create(self, data: Attachment):
+ new_dict = data.to_serializable(delete_private=True, time_to_str=False)
+ insert_data = insert(Attachment).values(**new_dict)
+ async with self._db.session_master() as session:
+ async with session.begin():
+ await session.execute(insert_data)
+ await session.commit()
+ return data.id
+
+ async def delete(self, attach_id: str):
+ q = delete(Attachment).where(
+ Attachment.id == attach_id # type: ignore
+ )
+ async with self._db.session_master() as session:
+ async with session.begin():
+ await session.execute(q)
+ await session.commit()
+
+ async def update(self, attach_id: str, **kwargs):
+ kwargs["updated_at"] = datetime.now(UTC)
+ q = update(Attachment).values(kwargs).where(Attachment.id == attach_id) # type: ignore
+ async with self._db.session_master() as session:
+ async with session.begin():
+ await session.execute(q)
+ await session.commit()
+
+ def db(self) -> AbstractDB:
+ return self._db
diff --git a/server/modules/attachments/services/__init__.py b/server/modules/attachments/services/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/server/modules/attachments/services/attachment.py b/server/modules/attachments/services/attachment.py
new file mode 100644
index 0000000..2dccc61
--- /dev/null
+++ b/server/modules/attachments/services/attachment.py
@@ -0,0 +1,349 @@
+import hashlib
+import os.path
+from abc import ABCMeta, abstractmethod
+from datetime import UTC, datetime
+from enum import Enum
+from io import BytesIO
+from pathlib import Path
+from typing import Any, AsyncIterable, AsyncIterator, Optional
+import uuid
+
+import aioboto3 # type: ignore
+import aiofiles
+import magic # type: ignore
+from botocore.client import BaseClient # type: ignore
+from botocore.exceptions import ClientError # type: ignore
+from PIL import Image
+
+from server.config import AppConfig, get_app_config
+from server.infra.db import AbstractSession
+from server.infra.logger import get_logger
+from server.modules.attachments.domains.attachments import Attachment
+from server.modules.attachments.repositories.attachments import AttachmentRepository
+
+
+class StorageDriversType(str, Enum):
+ MOCK = "mock"
+ LOCAL = "local"
+ S3 = "s3"
+
+
+class MediaType(str, Enum):
+ AUDIO = "audio"
+ VIDEO = "video"
+ IMAGE = "image"
+ SVG_IMAGE = "svg_image"
+ OTHER = "other"
+
+
+class StorageDriver(metaclass=ABCMeta):
+ @abstractmethod
+ def get_name(self) -> str:
+ pass
+
+ @abstractmethod
+ async def put(self, data: bytes) -> str:
+ pass
+
+ @abstractmethod
+ async def take(self, path: str) -> Optional[bytes]:
+ pass
+
+ @abstractmethod
+ async def stream(self, path: str) -> AsyncIterable[Any]:
+ pass
+
+ @abstractmethod
+ async def delete(self, path: str):
+ pass
+
+
+class LocalStorageDriver(StorageDriver):
+ _mount_dir: Path
+
+ def __init__(self) -> None:
+ self._mount_dir = Path(get_app_config().fs_local_mount_dir) # type: ignore
+
+ def get_name(self) -> str:
+ return StorageDriversType.LOCAL.value
+
+ async def put(self, data: bytes) -> str:
+ dir_path = self._mount_dir / Path(datetime.now(UTC).strftime("%d"))
+ if not os.path.isdir(dir_path):
+ os.mkdir(dir_path)
+ path = dir_path / Path(hashlib.file_digest(BytesIO(data), "sha256").hexdigest())
+ if os.path.isfile(path) and os.stat(path).st_size == len(data):
+ return str(path)
+ async with aiofiles.open(path, "wb") as f:
+ await f.write(data)
+ return str(path)
+
+ async def take(self, path: str) -> Optional[bytes]:
+ if not os.path.isfile(path):
+ return None
+ async with aiofiles.open(path, "rb") as f:
+ return await f.read()
+
+ async def stream(self, path: str):
+ async with aiofiles.open(path, mode="rb") as f:
+ while chunk := await f.read(1024):
+ yield chunk
+
+ async def delete(self, path: str):
+ if not os.path.isfile(path):
+ return
+ os.remove(path)
+
+
+class MockStorageDriver(StorageDriver):
+ _store: dict[str, bytes]
+
+ def __init__(self) -> None:
+ self._store = {}
+
+ def get_name(self) -> str:
+ return StorageDriversType.MOCK.value
+
+ async def stream(self, path: str) -> AsyncIterable:
+ raise NotImplementedError
+
+ async def put(self, data: bytes) -> str:
+ path = str(uuid.uuid4())
+ self._store[path] = data
+ return path
+
+ async def take(self, path: str) -> Optional[bytes]:
+ return self._store.get(path)
+
+ async def delete(self, path: str):
+ del self._store[path]
+
+
+class S3StorageDriver(StorageDriver):
+ _prefix: str = "pvc-435e5137-052f-43b1-ace2-e350c9d50c76"
+
+ def __init__(self, cnf: AppConfig) -> None:
+ self._chunk_size: int = 69 * 1024
+ self._cnf = cnf
+ self._logger = get_logger()
+ self._session = aioboto3.Session(
+ aws_access_key_id=str(cnf.fs_s3_access_key_id),
+ aws_secret_access_key=str(cnf.fs_s3_access_key),
+ )
+
+ def get_name(self) -> str:
+ return StorageDriversType.S3.value
+
+ async def _client(self) -> BaseClient:
+ return self._session.client("s3", endpoint_url=self._cnf.fs_s3_endpoint)
+
+ def _normalize_path(self, path: str) -> str:
+ return f"{S3StorageDriver._prefix}{path}".replace(
+ self._cnf.fs_local_mount_dir, ""
+ )
+
+ async def put(self, data: bytes) -> str:
+ sign = hashlib.file_digest(BytesIO(data), "sha256").hexdigest()
+ day = datetime.now(UTC).strftime("%d")
+ path = str(Path(S3StorageDriver._prefix) / day / sign)
+
+ async with await self._client() as s3:
+ await s3.upload_fileobj(
+ Fileobj=BytesIO(data),
+ Bucket=self._cnf.fs_s3_bucket,
+ Key=path,
+ ExtraArgs={
+ "ChecksumAlgorithm": "SHA256",
+ "ChecksumSHA256": sign,
+ },
+ )
+ return path.replace(S3StorageDriver._prefix, "")
+
+ async def stream(self, path: str):
+ path = self._normalize_path(path)
+ self._logger.debug(
+ f"stream s3 path {path}, bucket {self._cnf.fs_s3_bucket}, endpoint {self._cnf.fs_s3_endpoint}"
+ )
+
+ try:
+ async with await self._client() as s3:
+ obj = await s3.get_object(Bucket=self._cnf.fs_s3_bucket, Key=path)
+ body = obj["Body"]
+ while chunk := await body.read(self._chunk_size):
+ yield chunk
+ except ClientError as e:
+ if e.response.get("Error", {}).get("Code") != "NoSuchKey":
+ self._logger.error(f"stream client error: {str(e)}, path: {path}")
+ raise FileNotFoundError
+ except Exception as e:
+ self._logger.error(
+ f"stream error: {type(e).__name__} {str(e)}, path: {path}"
+ )
+ raise FileNotFoundError
+
+ async def take(self, path: str) -> Optional[bytes]:
+ buffer = BytesIO()
+ async for chunk in self.stream(path):
+ if chunk:
+ buffer.write(chunk)
+ content = buffer.getvalue()
+ return content if content else None
+
+ async def delete(self, path: str) -> None:
+ async with await self._client() as s3:
+ await s3.delete_object(
+ Bucket=self._cnf.fs_s3_bucket, Key=self._normalize_path(path)
+ )
+
+
+RESIZE_MAX_SIZE = 100_000
+RESIZE_PARAMS = (500, 500)
+
+
+class AtachmentService:
+ _driver: StorageDriver
+ _repository: AttachmentRepository
+ _cnf: AppConfig
+
+ def __init__(self, driver: StorageDriver, attach_repository: AttachmentRepository):
+ self._driver = driver
+ self._repository = attach_repository
+ self._cnf = get_app_config()
+
+ def media_type(self, content_type: str) -> MediaType:
+ if content_type == "":
+ return MediaType.OTHER
+ firt_part = content_type.split("/")[0]
+ match firt_part:
+ case str(MediaType.SVG_IMAGE):
+ return MediaType.SVG_IMAGE
+ case str(MediaType.IMAGE):
+ return MediaType.IMAGE
+ case str(MediaType.AUDIO):
+ return MediaType.AUDIO
+ case str(MediaType.VIDEO):
+ return MediaType.VIDEO
+ case _:
+ return MediaType.OTHER
+
+ def content_type(self, file: bytes) -> str:
+ return magic.from_buffer(file[0:2048], mime=True)
+
+ def extension(self, content_type: str | None) -> str:
+ if not content_type:
+ return "jpg"
+ if len(content_type.split("/")) != 2:
+ return "jpg"
+ return content_type.split("/")[1].split("+")[0]
+
+ def id_from_url(self, url: str) -> str:
+ if ".original" not in url:
+ raise ValueError(f"wrong url: {url}")
+ parts = url.split(".original")[0]
+ return parts.replace("/", "")
+
+ 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)
+ }"
+
+ async def create(self, file: bytes, user_id: str) -> Attachment:
+ path = await self._driver.put(file)
+ content_type = self.content_type(file)
+ attach = Attachment(
+ size=len(file),
+ storage_driver_name=str(self._driver.get_name()),
+ path=path,
+ media_type=self.media_type(content_type),
+ content_type=content_type,
+ created_by=user_id,
+ id=str(uuid.uuid4()),
+ created_at=datetime.now(UTC),
+ updated_at=datetime.now(UTC),
+ )
+ await self._repository.create(attach)
+ return attach
+
+ async def get_info(
+ self, session: AbstractSession | None, attach_id: list[str]
+ ) -> list[Attachment]:
+ if not attach_id:
+ return []
+ if session is not None:
+ return await self._repository.get_by_id(session, attach_id)
+ async with self._repository.db().session_slave() as session:
+ return await self._repository.get_by_id(session, attach_id)
+
+ def get_name(self, attachment: Attachment) -> str:
+ return f"{attachment.id}.{self.extension(attachment.content_type)}"
+
+ async def get_data(
+ self, session: AbstractSession, attach_id: str
+ ) -> Optional[bytes]:
+ file = await self._repository.get_by_id(session, [attach_id])
+ if not file:
+ return None
+ return await self._driver.take(file[0].path)
+
+ async def get_stream(
+ self, session: AbstractSession | None, attach_id: str
+ ) -> AsyncIterator[bytes]:
+ async def _stream_iterator(is_empty: bool):
+ if is_empty:
+ return
+ yield first_chunk
+ async for chunk in stream: # type: ignore
+ yield chunk
+
+ if session:
+ file = await self._repository.get_by_id(session, [attach_id])
+ else:
+ async with self._repository.db().session_slave() as session:
+ file = await self._repository.get_by_id(session, [attach_id])
+ if not file:
+ raise FileNotFoundError
+
+ stream = self._driver.stream(file[0].path)
+ try:
+ first_chunk = await stream.__anext__() # type: ignore
+ except StopAsyncIteration:
+ return _stream_iterator(is_empty=True)
+ return _stream_iterator(is_empty=False)
+
+ async def image_resize(self, session: AbstractSession, attach_id: list[str]):
+ info = await self.get_info(session, attach_id)
+ get_logger().info(
+ f"image_resize {len(info)}",
+ )
+ if not info:
+ return
+ for item in info:
+ if item.media_type != MediaType.IMAGE.value:
+ continue
+ if item.is_deleted:
+ continue
+ data = await self.get_data(session, item.id)
+ if data is None:
+ continue
+ if len(data) <= RESIZE_MAX_SIZE:
+ get_logger().info(
+ f"skip because size: {len(data)}",
+ )
+ continue
+ img = Image.open(BytesIO(data))
+ img.thumbnail(RESIZE_PARAMS)
+ buffer = BytesIO()
+ img.save(buffer, format="JPEG", quality=70)
+ buffer.seek(0)
+ d = buffer.read()
+ if d == 0:
+ return
+ buffer.close()
+ get_logger().info(
+ f"delete:{item.path}",
+ )
+ path = await self._driver.put(d)
+ await self._repository.update(
+ item.id, path=path, content_type="image/jpeg", size=len(d)
+ )
+ await self._driver.delete(item.path)
diff --git a/server/modules/descriptions/__init__.py b/server/modules/descriptions/__init__.py
new file mode 100644
index 0000000..242e02c
--- /dev/null
+++ b/server/modules/descriptions/__init__.py
@@ -0,0 +1,13 @@
+from server.modules.descriptions.repository import (
+ CharactersRepository,
+ ACharactersRepository,
+)
+from server.modules.descriptions.service import CharactersService
+from server.modules.descriptions.domain import Breed
+
+__all__ = (
+ "CharactersRepository",
+ "ACharactersRepository",
+ "CharactersService",
+ "Breed",
+)
diff --git a/server/services/descriptions/domain.py b/server/modules/descriptions/domain.py
similarity index 100%
rename from server/services/descriptions/domain.py
rename to server/modules/descriptions/domain.py
diff --git a/server/services/descriptions/repository/__init__.py b/server/modules/descriptions/repository/__init__.py
similarity index 64%
rename from server/services/descriptions/repository/__init__.py
rename to server/modules/descriptions/repository/__init__.py
index 001ed29..6316855 100644
--- a/server/services/descriptions/repository/__init__.py
+++ b/server/modules/descriptions/repository/__init__.py
@@ -1,4 +1,4 @@
-from server.services.descriptions.repository.repository import (
+from server.modules.descriptions.repository.repository import (
CharactersRepository,
ACharactersRepository,
)
diff --git a/server/services/descriptions/repository/breed_descriptions/австралийский келпи.txt b/server/modules/descriptions/repository/breed_descriptions/австралийский келпи.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/австралийский келпи.txt
rename to server/modules/descriptions/repository/breed_descriptions/австралийский келпи.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/австралийский терьер.txt b/server/modules/descriptions/repository/breed_descriptions/австралийский терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/австралийский терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/австралийский терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/австралийский_шелковистый_терьер.txt b/server/modules/descriptions/repository/breed_descriptions/австралийский_шелковистый_терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/австралийский_шелковистый_терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/австралийский_шелковистый_терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/американская_эскимосская_собака.txt b/server/modules/descriptions/repository/breed_descriptions/американская_эскимосская_собака.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/американская_эскимосская_собака.txt
rename to server/modules/descriptions/repository/breed_descriptions/американская_эскимосская_собака.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/американский_бульдог.txt b/server/modules/descriptions/repository/breed_descriptions/американский_бульдог.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/американский_бульдог.txt
rename to server/modules/descriptions/repository/breed_descriptions/американский_бульдог.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/американский_стаффордширский_терьер.txt b/server/modules/descriptions/repository/breed_descriptions/американский_стаффордширский_терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/американский_стаффордширский_терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/американский_стаффордширский_терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/английский_кокер_спаниель.txt b/server/modules/descriptions/repository/breed_descriptions/английский_кокер_спаниель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/английский_кокер_спаниель.txt
rename to server/modules/descriptions/repository/breed_descriptions/английский_кокер_спаниель.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/английский_сеттер.txt b/server/modules/descriptions/repository/breed_descriptions/английский_сеттер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/английский_сеттер.txt
rename to server/modules/descriptions/repository/breed_descriptions/английский_сеттер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/английский_спрингер-спаниель.txt b/server/modules/descriptions/repository/breed_descriptions/английский_спрингер-спаниель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/английский_спрингер-спаниель.txt
rename to server/modules/descriptions/repository/breed_descriptions/английский_спрингер-спаниель.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/английский_фоксхаунд.txt b/server/modules/descriptions/repository/breed_descriptions/английский_фоксхаунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/английский_фоксхаунд.txt
rename to server/modules/descriptions/repository/breed_descriptions/английский_фоксхаунд.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/аппенцеллер_зенненхунд.txt b/server/modules/descriptions/repository/breed_descriptions/аппенцеллер_зенненхунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/аппенцеллер_зенненхунд.txt
rename to server/modules/descriptions/repository/breed_descriptions/аппенцеллер_зенненхунд.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/афганская_борзая.txt b/server/modules/descriptions/repository/breed_descriptions/афганская_борзая.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/афганская_борзая.txt
rename to server/modules/descriptions/repository/breed_descriptions/афганская_борзая.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/аффенпинчер.txt b/server/modules/descriptions/repository/breed_descriptions/аффенпинчер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/аффенпинчер.txt
rename to server/modules/descriptions/repository/breed_descriptions/аффенпинчер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/басенджи.txt b/server/modules/descriptions/repository/breed_descriptions/басенджи.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/басенджи.txt
rename to server/modules/descriptions/repository/breed_descriptions/басенджи.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/бассет_хаунд.txt b/server/modules/descriptions/repository/breed_descriptions/бассет_хаунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/бассет_хаунд.txt
rename to server/modules/descriptions/repository/breed_descriptions/бассет_хаунд.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/бедлингтон-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/бедлингтон-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/бедлингтон-терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/бедлингтон-терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/бернский_зенненхунд.txt b/server/modules/descriptions/repository/breed_descriptions/бернский_зенненхунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/бернский_зенненхунд.txt
rename to server/modules/descriptions/repository/breed_descriptions/бернский_зенненхунд.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/бигль.txt b/server/modules/descriptions/repository/breed_descriptions/бигль.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/бигль.txt
rename to server/modules/descriptions/repository/breed_descriptions/бигль.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/бладхаунд.txt b/server/modules/descriptions/repository/breed_descriptions/бладхаунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/бладхаунд.txt
rename to server/modules/descriptions/repository/breed_descriptions/бладхаунд.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/бобтейл.txt b/server/modules/descriptions/repository/breed_descriptions/бобтейл.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/бобтейл.txt
rename to server/modules/descriptions/repository/breed_descriptions/бобтейл.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/боксер.txt b/server/modules/descriptions/repository/breed_descriptions/боксер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/боксер.txt
rename to server/modules/descriptions/repository/breed_descriptions/боксер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/большой_швейцарский_зенненхунд.txt b/server/modules/descriptions/repository/breed_descriptions/большой_швейцарский_зенненхунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/большой_швейцарский_зенненхунд.txt
rename to server/modules/descriptions/repository/breed_descriptions/большой_швейцарский_зенненхунд.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/бордер-колли.txt b/server/modules/descriptions/repository/breed_descriptions/бордер-колли.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/бордер-колли.txt
rename to server/modules/descriptions/repository/breed_descriptions/бордер-колли.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/бордер-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/бордер-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/бордер-терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/бордер-терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/бостон-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/бостон-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/бостон-терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/бостон-терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/бретонский_эпаньоль.txt b/server/modules/descriptions/repository/breed_descriptions/бретонский_эпаньоль.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/бретонский_эпаньоль.txt
rename to server/modules/descriptions/repository/breed_descriptions/бретонский_эпаньоль.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/бриар.txt b/server/modules/descriptions/repository/breed_descriptions/бриар.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/бриар.txt
rename to server/modules/descriptions/repository/breed_descriptions/бриар.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/бульмастиф.txt b/server/modules/descriptions/repository/breed_descriptions/бульмастиф.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/бульмастиф.txt
rename to server/modules/descriptions/repository/breed_descriptions/бульмастиф.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/веймаранер.txt b/server/modules/descriptions/repository/breed_descriptions/веймаранер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/веймаранер.txt
rename to server/modules/descriptions/repository/breed_descriptions/веймаранер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/вельш-корги_кардиган.txt b/server/modules/descriptions/repository/breed_descriptions/вельш-корги_кардиган.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/вельш-корги_кардиган.txt
rename to server/modules/descriptions/repository/breed_descriptions/вельш-корги_кардиган.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/вельш-корги_пемброк.txt b/server/modules/descriptions/repository/breed_descriptions/вельш-корги_пемброк.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/вельш-корги_пемброк.txt
rename to server/modules/descriptions/repository/breed_descriptions/вельш-корги_пемброк.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/вельш-спрингер-спаниель.txt b/server/modules/descriptions/repository/breed_descriptions/вельш-спрингер-спаниель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/вельш-спрингер-спаниель.txt
rename to server/modules/descriptions/repository/breed_descriptions/вельш-спрингер-спаниель.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/венгерская_выжла.txt b/server/modules/descriptions/repository/breed_descriptions/венгерская_выжла.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/венгерская_выжла.txt
rename to server/modules/descriptions/repository/breed_descriptions/венгерская_выжла.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/вест-хайленд-уайт-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/вест-хайленд-уайт-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/вест-хайленд-уайт-терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/вест-хайленд-уайт-терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/гаванский_бишон.txt b/server/modules/descriptions/repository/breed_descriptions/гаванский_бишон.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/гаванский_бишон.txt
rename to server/modules/descriptions/repository/breed_descriptions/гаванский_бишон.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/гиеновидная_собака.txt b/server/modules/descriptions/repository/breed_descriptions/гиеновидная_собака.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/гиеновидная_собака.txt
rename to server/modules/descriptions/repository/breed_descriptions/гиеновидная_собака.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/грюнендаль.txt b/server/modules/descriptions/repository/breed_descriptions/грюнендаль.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/грюнендаль.txt
rename to server/modules/descriptions/repository/breed_descriptions/грюнендаль.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/денди-динмонт-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/денди-динмонт-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/денди-динмонт-терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/денди-динмонт-терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/динго.txt b/server/modules/descriptions/repository/breed_descriptions/динго.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/динго.txt
rename to server/modules/descriptions/repository/breed_descriptions/динго.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/дирхаунд.txt b/server/modules/descriptions/repository/breed_descriptions/дирхаунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/дирхаунд.txt
rename to server/modules/descriptions/repository/breed_descriptions/дирхаунд.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/доберман.txt b/server/modules/descriptions/repository/breed_descriptions/доберман.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/доберман.txt
rename to server/modules/descriptions/repository/breed_descriptions/доберман.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/дхоль.txt b/server/modules/descriptions/repository/breed_descriptions/дхоль.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/дхоль.txt
rename to server/modules/descriptions/repository/breed_descriptions/дхоль.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/жесткошёрстный_фокстерьер.txt b/server/modules/descriptions/repository/breed_descriptions/жесткошёрстный_фокстерьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/жесткошёрстный_фокстерьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/жесткошёрстный_фокстерьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/золотистый_ретривер.txt b/server/modules/descriptions/repository/breed_descriptions/золотистый_ретривер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/золотистый_ретривер.txt
rename to server/modules/descriptions/repository/breed_descriptions/золотистый_ретривер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/ирландский_водяной_спаниель.txt b/server/modules/descriptions/repository/breed_descriptions/ирландский_водяной_спаниель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/ирландский_водяной_спаниель.txt
rename to server/modules/descriptions/repository/breed_descriptions/ирландский_водяной_спаниель.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/ирландский_волкодав.txt b/server/modules/descriptions/repository/breed_descriptions/ирландский_волкодав.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/ирландский_волкодав.txt
rename to server/modules/descriptions/repository/breed_descriptions/ирландский_волкодав.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/ирландский_красный_сеттер.txt b/server/modules/descriptions/repository/breed_descriptions/ирландский_красный_сеттер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/ирландский_красный_сеттер.txt
rename to server/modules/descriptions/repository/breed_descriptions/ирландский_красный_сеттер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/ирландский_мягкошёрстный_пшеничный_терьер.txt b/server/modules/descriptions/repository/breed_descriptions/ирландский_мягкошёрстный_пшеничный_терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/ирландский_мягкошёрстный_пшеничный_терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/ирландский_мягкошёрстный_пшеничный_терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/ирландский_терьер.txt b/server/modules/descriptions/repository/breed_descriptions/ирландский_терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/ирландский_терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/ирландский_терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/йоркширский_терьер.txt b/server/modules/descriptions/repository/breed_descriptions/йоркширский_терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/йоркширский_терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/йоркширский_терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/карликовый _пинчер.txt b/server/modules/descriptions/repository/breed_descriptions/карликовый _пинчер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/карликовый _пинчер.txt
rename to server/modules/descriptions/repository/breed_descriptions/карликовый _пинчер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/карликовый_пинчер.txt b/server/modules/descriptions/repository/breed_descriptions/карликовый_пинчер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/карликовый_пинчер.txt
rename to server/modules/descriptions/repository/breed_descriptions/карликовый_пинчер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/кеесхонд.txt b/server/modules/descriptions/repository/breed_descriptions/кеесхонд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/кеесхонд.txt
rename to server/modules/descriptions/repository/breed_descriptions/кеесхонд.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/керн-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/керн-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/керн-терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/керн-терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/керри-блю-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/керри-блю-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/керри-блю-терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/керри-блю-терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/кинг-чарльз-спаниель.txt b/server/modules/descriptions/repository/breed_descriptions/кинг-чарльз-спаниель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/кинг-чарльз-спаниель.txt
rename to server/modules/descriptions/repository/breed_descriptions/кинг-чарльз-спаниель.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/кламбер-спаниель.txt b/server/modules/descriptions/repository/breed_descriptions/кламбер-спаниель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/кламбер-спаниель.txt
rename to server/modules/descriptions/repository/breed_descriptions/кламбер-спаниель.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/кокер-спаниель.txt b/server/modules/descriptions/repository/breed_descriptions/кокер-спаниель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/кокер-спаниель.txt
rename to server/modules/descriptions/repository/breed_descriptions/кокер-спаниель.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/колли.txt b/server/modules/descriptions/repository/breed_descriptions/колли.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/колли.txt
rename to server/modules/descriptions/repository/breed_descriptions/колли.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/комондор.txt b/server/modules/descriptions/repository/breed_descriptions/комондор.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/комондор.txt
rename to server/modules/descriptions/repository/breed_descriptions/комондор.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/континентальный_той-спаниель.txt b/server/modules/descriptions/repository/breed_descriptions/континентальный_той-спаниель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/континентальный_той-спаниель.txt
rename to server/modules/descriptions/repository/breed_descriptions/континентальный_той-спаниель.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/крапчато-голубой_кунхаунд.txt b/server/modules/descriptions/repository/breed_descriptions/крапчато-голубой_кунхаунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/крапчато-голубой_кунхаунд.txt
rename to server/modules/descriptions/repository/breed_descriptions/крапчато-голубой_кунхаунд.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/красный_кунхаунд.txt b/server/modules/descriptions/repository/breed_descriptions/красный_кунхаунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/красный_кунхаунд.txt
rename to server/modules/descriptions/repository/breed_descriptions/красный_кунхаунд.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/ксолоитцкуинтли.txt b/server/modules/descriptions/repository/breed_descriptions/ксолоитцкуинтли.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/ксолоитцкуинтли.txt
rename to server/modules/descriptions/repository/breed_descriptions/ксолоитцкуинтли.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/кувас.txt b/server/modules/descriptions/repository/breed_descriptions/кувас.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/кувас.txt
rename to server/modules/descriptions/repository/breed_descriptions/кувас.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/курцхаар.txt b/server/modules/descriptions/repository/breed_descriptions/курцхаар.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/курцхаар.txt
rename to server/modules/descriptions/repository/breed_descriptions/курцхаар.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/курчавошёрстный_ретривер.txt b/server/modules/descriptions/repository/breed_descriptions/курчавошёрстный_ретривер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/курчавошёрстный_ретривер.txt
rename to server/modules/descriptions/repository/breed_descriptions/курчавошёрстный_ретривер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/лабрадор-ретривер.txt b/server/modules/descriptions/repository/breed_descriptions/лабрадор-ретривер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/лабрадор-ретривер.txt
rename to server/modules/descriptions/repository/breed_descriptions/лабрадор-ретривер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/левретка.txt b/server/modules/descriptions/repository/breed_descriptions/левретка.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/левретка.txt
rename to server/modules/descriptions/repository/breed_descriptions/левретка.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/лейкленд-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/лейкленд-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/лейкленд-терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/лейкленд-терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/леонбергер.txt b/server/modules/descriptions/repository/breed_descriptions/леонбергер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/леонбергер.txt
rename to server/modules/descriptions/repository/breed_descriptions/леонбергер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/лхасский_апсо.txt b/server/modules/descriptions/repository/breed_descriptions/лхасский_апсо.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/лхасский_апсо.txt
rename to server/modules/descriptions/repository/breed_descriptions/лхасский_апсо.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/маламут.txt b/server/modules/descriptions/repository/breed_descriptions/маламут.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/маламут.txt
rename to server/modules/descriptions/repository/breed_descriptions/маламут.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/малинуа.txt b/server/modules/descriptions/repository/breed_descriptions/малинуа.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/малинуа.txt
rename to server/modules/descriptions/repository/breed_descriptions/малинуа.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/малые_бельгийские_собаки.txt b/server/modules/descriptions/repository/breed_descriptions/малые_бельгийские_собаки.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/малые_бельгийские_собаки.txt
rename to server/modules/descriptions/repository/breed_descriptions/малые_бельгийские_собаки.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/мальтийская_болонка.txt b/server/modules/descriptions/repository/breed_descriptions/мальтийская_болонка.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/мальтийская_болонка.txt
rename to server/modules/descriptions/repository/breed_descriptions/мальтийская_болонка.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/миниатюрный_пудель.txt b/server/modules/descriptions/repository/breed_descriptions/миниатюрный_пудель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/миниатюрный_пудель.txt
rename to server/modules/descriptions/repository/breed_descriptions/миниатюрный_пудель.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/миттельшнауцер.txt b/server/modules/descriptions/repository/breed_descriptions/миттельшнауцер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/миттельшнауцер.txt
rename to server/modules/descriptions/repository/breed_descriptions/миттельшнауцер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/мопс.txt b/server/modules/descriptions/repository/breed_descriptions/мопс.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/мопс.txt
rename to server/modules/descriptions/repository/breed_descriptions/мопс.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/немецкая_овчарка.txt b/server/modules/descriptions/repository/breed_descriptions/немецкая_овчарка.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/немецкая_овчарка.txt
rename to server/modules/descriptions/repository/breed_descriptions/немецкая_овчарка.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/немецкий_дог.txt b/server/modules/descriptions/repository/breed_descriptions/немецкий_дог.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/немецкий_дог.txt
rename to server/modules/descriptions/repository/breed_descriptions/немецкий_дог.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/норвежский_серый_элкхунд.txt b/server/modules/descriptions/repository/breed_descriptions/норвежский_серый_элкхунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/норвежский_серый_элкхунд.txt
rename to server/modules/descriptions/repository/breed_descriptions/норвежский_серый_элкхунд.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/норвич-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/норвич-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/норвич-терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/норвич-терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/норфолк-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/норфолк-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/норфолк-терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/норфолк-терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/ньюфаундленд.txt b/server/modules/descriptions/repository/breed_descriptions/ньюфаундленд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/ньюфаундленд.txt
rename to server/modules/descriptions/repository/breed_descriptions/ньюфаундленд.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/оттерхаунд.txt b/server/modules/descriptions/repository/breed_descriptions/оттерхаунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/оттерхаунд.txt
rename to server/modules/descriptions/repository/breed_descriptions/оттерхаунд.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/пекинес.txt b/server/modules/descriptions/repository/breed_descriptions/пекинес.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/пекинес.txt
rename to server/modules/descriptions/repository/breed_descriptions/пекинес.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/пиренейская _горная_собака.txt b/server/modules/descriptions/repository/breed_descriptions/пиренейская _горная_собака.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/пиренейская _горная_собака.txt
rename to server/modules/descriptions/repository/breed_descriptions/пиренейская _горная_собака.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/померанский_шпиц.txt b/server/modules/descriptions/repository/breed_descriptions/померанский_шпиц.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/померанский_шпиц.txt
rename to server/modules/descriptions/repository/breed_descriptions/померанский_шпиц.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/прямошёрстный_ретривер.txt b/server/modules/descriptions/repository/breed_descriptions/прямошёрстный_ретривер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/прямошёрстный_ретривер.txt
rename to server/modules/descriptions/repository/breed_descriptions/прямошёрстный_ретривер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/ризеншнауцер.txt b/server/modules/descriptions/repository/breed_descriptions/ризеншнауцер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/ризеншнауцер.txt
rename to server/modules/descriptions/repository/breed_descriptions/ризеншнауцер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/родезийский риджбек.txt b/server/modules/descriptions/repository/breed_descriptions/родезийский риджбек.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/родезийский риджбек.txt
rename to server/modules/descriptions/repository/breed_descriptions/родезийский риджбек.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/ротвейлер.txt b/server/modules/descriptions/repository/breed_descriptions/ротвейлер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/ротвейлер.txt
rename to server/modules/descriptions/repository/breed_descriptions/ротвейлер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/русская_псовая_борзая.txt b/server/modules/descriptions/repository/breed_descriptions/русская_псовая_борзая.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/русская_псовая_борзая.txt
rename to server/modules/descriptions/repository/breed_descriptions/русская_псовая_борзая.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/русский_той.txt b/server/modules/descriptions/repository/breed_descriptions/русский_той.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/русский_той.txt
rename to server/modules/descriptions/repository/breed_descriptions/русский_той.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/салюки.txt b/server/modules/descriptions/repository/breed_descriptions/салюки.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/салюки.txt
rename to server/modules/descriptions/repository/breed_descriptions/салюки.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/самоед.txt b/server/modules/descriptions/repository/breed_descriptions/самоед.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/самоед.txt
rename to server/modules/descriptions/repository/breed_descriptions/самоед.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/сенбернар.txt b/server/modules/descriptions/repository/breed_descriptions/сенбернар.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/сенбернар.txt
rename to server/modules/descriptions/repository/breed_descriptions/сенбернар.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/сибирский_хаски.txt b/server/modules/descriptions/repository/breed_descriptions/сибирский_хаски.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/сибирский_хаски.txt
rename to server/modules/descriptions/repository/breed_descriptions/сибирский_хаски.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/силихем-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/силихем-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/силихем-терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/силихем-терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/стандартный_пудель.txt b/server/modules/descriptions/repository/breed_descriptions/стандартный_пудель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/стандартный_пудель.txt
rename to server/modules/descriptions/repository/breed_descriptions/стандартный_пудель.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/стаффордширский_бультерьер.txt b/server/modules/descriptions/repository/breed_descriptions/стаффордширский_бультерьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/стаффордширский_бультерьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/стаффордширский_бультерьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/суссекс-спаниель.txt b/server/modules/descriptions/repository/breed_descriptions/суссекс-спаниель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/суссекс-спаниель.txt
rename to server/modules/descriptions/repository/breed_descriptions/суссекс-спаниель.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/схипперке.txt b/server/modules/descriptions/repository/breed_descriptions/схипперке.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/схипперке.txt
rename to server/modules/descriptions/repository/breed_descriptions/схипперке.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/тибетский_мастиф.txt b/server/modules/descriptions/repository/breed_descriptions/тибетский_мастиф.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/тибетский_мастиф.txt
rename to server/modules/descriptions/repository/breed_descriptions/тибетский_мастиф.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/тибетский_терьер.txt b/server/modules/descriptions/repository/breed_descriptions/тибетский_терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/тибетский_терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/тибетский_терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/той_пудель.txt b/server/modules/descriptions/repository/breed_descriptions/той_пудель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/той_пудель.txt
rename to server/modules/descriptions/repository/breed_descriptions/той_пудель.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/триин-уокер_кунхаунд.txt b/server/modules/descriptions/repository/breed_descriptions/триин-уокер_кунхаунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/триин-уокер_кунхаунд.txt
rename to server/modules/descriptions/repository/breed_descriptions/триин-уокер_кунхаунд.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/уиппет.txt b/server/modules/descriptions/repository/breed_descriptions/уиппет.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/уиппет.txt
rename to server/modules/descriptions/repository/breed_descriptions/уиппет.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/фландрский_бувье.txt b/server/modules/descriptions/repository/breed_descriptions/фландрский_бувье.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/фландрский_бувье.txt
rename to server/modules/descriptions/repository/breed_descriptions/фландрский_бувье.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/французский_бульдог.txt b/server/modules/descriptions/repository/breed_descriptions/французский_бульдог.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/французский_бульдог.txt
rename to server/modules/descriptions/repository/breed_descriptions/французский_бульдог.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/цвергшнауцер.txt b/server/modules/descriptions/repository/breed_descriptions/цвергшнауцер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/цвергшнауцер.txt
rename to server/modules/descriptions/repository/breed_descriptions/цвергшнауцер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/чау-чау.txt b/server/modules/descriptions/repository/breed_descriptions/чау-чау.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/чау-чау.txt
rename to server/modules/descriptions/repository/breed_descriptions/чау-чау.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/чесапик-бей-ретривер.txt b/server/modules/descriptions/repository/breed_descriptions/чесапик-бей-ретривер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/чесапик-бей-ретривер.txt
rename to server/modules/descriptions/repository/breed_descriptions/чесапик-бей-ретривер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/чихуахуа.txt b/server/modules/descriptions/repository/breed_descriptions/чихуахуа.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/чихуахуа.txt
rename to server/modules/descriptions/repository/breed_descriptions/чихуахуа.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/чёрно-подпалый_кунхаунд.txt b/server/modules/descriptions/repository/breed_descriptions/чёрно-подпалый_кунхаунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/чёрно-подпалый_кунхаунд.txt
rename to server/modules/descriptions/repository/breed_descriptions/чёрно-подпалый_кунхаунд.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/шелти.txt b/server/modules/descriptions/repository/breed_descriptions/шелти.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/шелти.txt
rename to server/modules/descriptions/repository/breed_descriptions/шелти.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/ши-тцу.txt b/server/modules/descriptions/repository/breed_descriptions/ши-тцу.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/ши-тцу.txt
rename to server/modules/descriptions/repository/breed_descriptions/ши-тцу.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/шиба_ину.txt b/server/modules/descriptions/repository/breed_descriptions/шиба_ину.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/шиба_ину.txt
rename to server/modules/descriptions/repository/breed_descriptions/шиба_ину.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/шотландский_сеттер.txt b/server/modules/descriptions/repository/breed_descriptions/шотландский_сеттер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/шотландский_сеттер.txt
rename to server/modules/descriptions/repository/breed_descriptions/шотландский_сеттер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/шотландский_терьер.txt b/server/modules/descriptions/repository/breed_descriptions/шотландский_терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/шотландский_терьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/шотландский_терьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/энтлебухер_зенненхунд.txt b/server/modules/descriptions/repository/breed_descriptions/энтлебухер_зенненхунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/энтлебухер_зенненхунд.txt
rename to server/modules/descriptions/repository/breed_descriptions/энтлебухер_зенненхунд.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/эрдельтерьер.txt b/server/modules/descriptions/repository/breed_descriptions/эрдельтерьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/эрдельтерьер.txt
rename to server/modules/descriptions/repository/breed_descriptions/эрдельтерьер.txt
diff --git a/server/services/descriptions/repository/breed_descriptions/японский хин.txt b/server/modules/descriptions/repository/breed_descriptions/японский хин.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_descriptions/японский хин.txt
rename to server/modules/descriptions/repository/breed_descriptions/японский хин.txt
diff --git a/server/services/descriptions/repository/breed_signs/австралийский келпи.txt b/server/modules/descriptions/repository/breed_signs/австралийский келпи.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/австралийский келпи.txt
rename to server/modules/descriptions/repository/breed_signs/австралийский келпи.txt
diff --git a/server/services/descriptions/repository/breed_signs/австралийский терьер.txt b/server/modules/descriptions/repository/breed_signs/австралийский терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/австралийский терьер.txt
rename to server/modules/descriptions/repository/breed_signs/австралийский терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/австралийский_шелковистый_терьер.txt b/server/modules/descriptions/repository/breed_signs/австралийский_шелковистый_терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/австралийский_шелковистый_терьер.txt
rename to server/modules/descriptions/repository/breed_signs/австралийский_шелковистый_терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/американская_эскимосская_собака.txt b/server/modules/descriptions/repository/breed_signs/американская_эскимосская_собака.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/американская_эскимосская_собака.txt
rename to server/modules/descriptions/repository/breed_signs/американская_эскимосская_собака.txt
diff --git a/server/services/descriptions/repository/breed_signs/американский_бульдог.txt b/server/modules/descriptions/repository/breed_signs/американский_бульдог.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/американский_бульдог.txt
rename to server/modules/descriptions/repository/breed_signs/американский_бульдог.txt
diff --git a/server/services/descriptions/repository/breed_signs/американский_стаффордширский_терьер.txt b/server/modules/descriptions/repository/breed_signs/американский_стаффордширский_терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/американский_стаффордширский_терьер.txt
rename to server/modules/descriptions/repository/breed_signs/американский_стаффордширский_терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/английский_сеттер.txt b/server/modules/descriptions/repository/breed_signs/английский_сеттер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/английский_сеттер.txt
rename to server/modules/descriptions/repository/breed_signs/английский_сеттер.txt
diff --git a/server/services/descriptions/repository/breed_signs/английский_спрингер-спаниель.txt b/server/modules/descriptions/repository/breed_signs/английский_спрингер-спаниель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/английский_спрингер-спаниель.txt
rename to server/modules/descriptions/repository/breed_signs/английский_спрингер-спаниель.txt
diff --git a/server/services/descriptions/repository/breed_signs/английский_фоксхаунд.txt b/server/modules/descriptions/repository/breed_signs/английский_фоксхаунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/английский_фоксхаунд.txt
rename to server/modules/descriptions/repository/breed_signs/английский_фоксхаунд.txt
diff --git a/server/services/descriptions/repository/breed_signs/аппенцеллер_зенненхунд.txt b/server/modules/descriptions/repository/breed_signs/аппенцеллер_зенненхунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/аппенцеллер_зенненхунд.txt
rename to server/modules/descriptions/repository/breed_signs/аппенцеллер_зенненхунд.txt
diff --git a/server/services/descriptions/repository/breed_signs/аффенпинчер.txt b/server/modules/descriptions/repository/breed_signs/аффенпинчер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/аффенпинчер.txt
rename to server/modules/descriptions/repository/breed_signs/аффенпинчер.txt
diff --git a/server/services/descriptions/repository/breed_signs/басенджи.txt b/server/modules/descriptions/repository/breed_signs/басенджи.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/басенджи.txt
rename to server/modules/descriptions/repository/breed_signs/басенджи.txt
diff --git a/server/services/descriptions/repository/breed_signs/бассет_хаунд.txt b/server/modules/descriptions/repository/breed_signs/бассет_хаунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/бассет_хаунд.txt
rename to server/modules/descriptions/repository/breed_signs/бассет_хаунд.txt
diff --git a/server/services/descriptions/repository/breed_signs/бедлингтон-терьер.txt b/server/modules/descriptions/repository/breed_signs/бедлингтон-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/бедлингтон-терьер.txt
rename to server/modules/descriptions/repository/breed_signs/бедлингтон-терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/бигль.txt b/server/modules/descriptions/repository/breed_signs/бигль.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/бигль.txt
rename to server/modules/descriptions/repository/breed_signs/бигль.txt
diff --git a/server/services/descriptions/repository/breed_signs/бобтейл.txt b/server/modules/descriptions/repository/breed_signs/бобтейл.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/бобтейл.txt
rename to server/modules/descriptions/repository/breed_signs/бобтейл.txt
diff --git a/server/services/descriptions/repository/breed_signs/боксер.txt b/server/modules/descriptions/repository/breed_signs/боксер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/боксер.txt
rename to server/modules/descriptions/repository/breed_signs/боксер.txt
diff --git a/server/services/descriptions/repository/breed_signs/большой_швейцарский_зенненхунд.txt b/server/modules/descriptions/repository/breed_signs/большой_швейцарский_зенненхунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/большой_швейцарский_зенненхунд.txt
rename to server/modules/descriptions/repository/breed_signs/большой_швейцарский_зенненхунд.txt
diff --git a/server/services/descriptions/repository/breed_signs/бордер-колли.txt b/server/modules/descriptions/repository/breed_signs/бордер-колли.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/бордер-колли.txt
rename to server/modules/descriptions/repository/breed_signs/бордер-колли.txt
diff --git a/server/services/descriptions/repository/breed_signs/бордер-терьер.txt b/server/modules/descriptions/repository/breed_signs/бордер-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/бордер-терьер.txt
rename to server/modules/descriptions/repository/breed_signs/бордер-терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/бостон-терьер.txt b/server/modules/descriptions/repository/breed_signs/бостон-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/бостон-терьер.txt
rename to server/modules/descriptions/repository/breed_signs/бостон-терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/бретонский_эпаньоль.txt b/server/modules/descriptions/repository/breed_signs/бретонский_эпаньоль.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/бретонский_эпаньоль.txt
rename to server/modules/descriptions/repository/breed_signs/бретонский_эпаньоль.txt
diff --git a/server/services/descriptions/repository/breed_signs/бриар.txt b/server/modules/descriptions/repository/breed_signs/бриар.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/бриар.txt
rename to server/modules/descriptions/repository/breed_signs/бриар.txt
diff --git a/server/services/descriptions/repository/breed_signs/бульмастиф.txt b/server/modules/descriptions/repository/breed_signs/бульмастиф.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/бульмастиф.txt
rename to server/modules/descriptions/repository/breed_signs/бульмастиф.txt
diff --git a/server/services/descriptions/repository/breed_signs/веймаранер.txt b/server/modules/descriptions/repository/breed_signs/веймаранер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/веймаранер.txt
rename to server/modules/descriptions/repository/breed_signs/веймаранер.txt
diff --git a/server/services/descriptions/repository/breed_signs/вельш-корги_кардиган.txt b/server/modules/descriptions/repository/breed_signs/вельш-корги_кардиган.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/вельш-корги_кардиган.txt
rename to server/modules/descriptions/repository/breed_signs/вельш-корги_кардиган.txt
diff --git a/server/services/descriptions/repository/breed_signs/вельш-корги_пемброк.txt b/server/modules/descriptions/repository/breed_signs/вельш-корги_пемброк.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/вельш-корги_пемброк.txt
rename to server/modules/descriptions/repository/breed_signs/вельш-корги_пемброк.txt
diff --git a/server/services/descriptions/repository/breed_signs/вельш-спрингер-спаниель.txt b/server/modules/descriptions/repository/breed_signs/вельш-спрингер-спаниель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/вельш-спрингер-спаниель.txt
rename to server/modules/descriptions/repository/breed_signs/вельш-спрингер-спаниель.txt
diff --git a/server/services/descriptions/repository/breed_signs/венгерская_выжла.txt b/server/modules/descriptions/repository/breed_signs/венгерская_выжла.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/венгерская_выжла.txt
rename to server/modules/descriptions/repository/breed_signs/венгерская_выжла.txt
diff --git a/server/services/descriptions/repository/breed_signs/вест-хайленд-уайт-терьер.txt b/server/modules/descriptions/repository/breed_signs/вест-хайленд-уайт-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/вест-хайленд-уайт-терьер.txt
rename to server/modules/descriptions/repository/breed_signs/вест-хайленд-уайт-терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/гаванский_бишон.txt b/server/modules/descriptions/repository/breed_signs/гаванский_бишон.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/гаванский_бишон.txt
rename to server/modules/descriptions/repository/breed_signs/гаванский_бишон.txt
diff --git a/server/services/descriptions/repository/breed_signs/гиеновидная_собака.txt b/server/modules/descriptions/repository/breed_signs/гиеновидная_собака.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/гиеновидная_собака.txt
rename to server/modules/descriptions/repository/breed_signs/гиеновидная_собака.txt
diff --git a/server/services/descriptions/repository/breed_signs/грюнендаль.txt b/server/modules/descriptions/repository/breed_signs/грюнендаль.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/грюнендаль.txt
rename to server/modules/descriptions/repository/breed_signs/грюнендаль.txt
diff --git a/server/services/descriptions/repository/breed_signs/денди-динмонт-терьер.txt b/server/modules/descriptions/repository/breed_signs/денди-динмонт-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/денди-динмонт-терьер.txt
rename to server/modules/descriptions/repository/breed_signs/денди-динмонт-терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/динго.txt b/server/modules/descriptions/repository/breed_signs/динго.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/динго.txt
rename to server/modules/descriptions/repository/breed_signs/динго.txt
diff --git a/server/services/descriptions/repository/breed_signs/дирхаунд.txt b/server/modules/descriptions/repository/breed_signs/дирхаунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/дирхаунд.txt
rename to server/modules/descriptions/repository/breed_signs/дирхаунд.txt
diff --git a/server/services/descriptions/repository/breed_signs/доберман.txt b/server/modules/descriptions/repository/breed_signs/доберман.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/доберман.txt
rename to server/modules/descriptions/repository/breed_signs/доберман.txt
diff --git a/server/services/descriptions/repository/breed_signs/дхоль.txt b/server/modules/descriptions/repository/breed_signs/дхоль.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/дхоль.txt
rename to server/modules/descriptions/repository/breed_signs/дхоль.txt
diff --git a/server/services/descriptions/repository/breed_signs/жесткошёрстный_фокстерьер.txt b/server/modules/descriptions/repository/breed_signs/жесткошёрстный_фокстерьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/жесткошёрстный_фокстерьер.txt
rename to server/modules/descriptions/repository/breed_signs/жесткошёрстный_фокстерьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/золотистый_ретривер.txt b/server/modules/descriptions/repository/breed_signs/золотистый_ретривер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/золотистый_ретривер.txt
rename to server/modules/descriptions/repository/breed_signs/золотистый_ретривер.txt
diff --git a/server/services/descriptions/repository/breed_signs/ирландский_волкодав.txt b/server/modules/descriptions/repository/breed_signs/ирландский_волкодав.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/ирландский_волкодав.txt
rename to server/modules/descriptions/repository/breed_signs/ирландский_волкодав.txt
diff --git a/server/services/descriptions/repository/breed_signs/ирландский_красный_сеттер.txt b/server/modules/descriptions/repository/breed_signs/ирландский_красный_сеттер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/ирландский_красный_сеттер.txt
rename to server/modules/descriptions/repository/breed_signs/ирландский_красный_сеттер.txt
diff --git a/server/services/descriptions/repository/breed_signs/ирландский_мягкошёрстный_пшеничный_терьер.txt b/server/modules/descriptions/repository/breed_signs/ирландский_мягкошёрстный_пшеничный_терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/ирландский_мягкошёрстный_пшеничный_терьер.txt
rename to server/modules/descriptions/repository/breed_signs/ирландский_мягкошёрстный_пшеничный_терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/ирландский_терьер.txt b/server/modules/descriptions/repository/breed_signs/ирландский_терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/ирландский_терьер.txt
rename to server/modules/descriptions/repository/breed_signs/ирландский_терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/йоркширский_терьер.txt b/server/modules/descriptions/repository/breed_signs/йоркширский_терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/йоркширский_терьер.txt
rename to server/modules/descriptions/repository/breed_signs/йоркширский_терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/карликовый _пинчер.txt b/server/modules/descriptions/repository/breed_signs/карликовый _пинчер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/карликовый _пинчер.txt
rename to server/modules/descriptions/repository/breed_signs/карликовый _пинчер.txt
diff --git a/server/services/descriptions/repository/breed_signs/кеесхонд.txt b/server/modules/descriptions/repository/breed_signs/кеесхонд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/кеесхонд.txt
rename to server/modules/descriptions/repository/breed_signs/кеесхонд.txt
diff --git a/server/services/descriptions/repository/breed_signs/керн-терьер.txt b/server/modules/descriptions/repository/breed_signs/керн-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/керн-терьер.txt
rename to server/modules/descriptions/repository/breed_signs/керн-терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/керри-блю-терьер.txt b/server/modules/descriptions/repository/breed_signs/керри-блю-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/керри-блю-терьер.txt
rename to server/modules/descriptions/repository/breed_signs/керри-блю-терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/кинг-чарльз-спаниель.txt b/server/modules/descriptions/repository/breed_signs/кинг-чарльз-спаниель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/кинг-чарльз-спаниель.txt
rename to server/modules/descriptions/repository/breed_signs/кинг-чарльз-спаниель.txt
diff --git a/server/services/descriptions/repository/breed_signs/кламбер-спаниель.txt b/server/modules/descriptions/repository/breed_signs/кламбер-спаниель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/кламбер-спаниель.txt
rename to server/modules/descriptions/repository/breed_signs/кламбер-спаниель.txt
diff --git a/server/services/descriptions/repository/breed_signs/кокер-спаниель.txt b/server/modules/descriptions/repository/breed_signs/кокер-спаниель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/кокер-спаниель.txt
rename to server/modules/descriptions/repository/breed_signs/кокер-спаниель.txt
diff --git a/server/services/descriptions/repository/breed_signs/колли.txt b/server/modules/descriptions/repository/breed_signs/колли.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/колли.txt
rename to server/modules/descriptions/repository/breed_signs/колли.txt
diff --git a/server/services/descriptions/repository/breed_signs/комондор.txt b/server/modules/descriptions/repository/breed_signs/комондор.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/комондор.txt
rename to server/modules/descriptions/repository/breed_signs/комондор.txt
diff --git a/server/services/descriptions/repository/breed_signs/континентальный_той-спаниель.txt b/server/modules/descriptions/repository/breed_signs/континентальный_той-спаниель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/континентальный_той-спаниель.txt
rename to server/modules/descriptions/repository/breed_signs/континентальный_той-спаниель.txt
diff --git a/server/services/descriptions/repository/breed_signs/крапчато-голубой_кунхаунд.txt b/server/modules/descriptions/repository/breed_signs/крапчато-голубой_кунхаунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/крапчато-голубой_кунхаунд.txt
rename to server/modules/descriptions/repository/breed_signs/крапчато-голубой_кунхаунд.txt
diff --git a/server/services/descriptions/repository/breed_signs/красный_кунхаунд.txt b/server/modules/descriptions/repository/breed_signs/красный_кунхаунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/красный_кунхаунд.txt
rename to server/modules/descriptions/repository/breed_signs/красный_кунхаунд.txt
diff --git a/server/services/descriptions/repository/breed_signs/ксолоитцкуинтли.txt b/server/modules/descriptions/repository/breed_signs/ксолоитцкуинтли.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/ксолоитцкуинтли.txt
rename to server/modules/descriptions/repository/breed_signs/ксолоитцкуинтли.txt
diff --git a/server/services/descriptions/repository/breed_signs/кувас.txt b/server/modules/descriptions/repository/breed_signs/кувас.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/кувас.txt
rename to server/modules/descriptions/repository/breed_signs/кувас.txt
diff --git a/server/services/descriptions/repository/breed_signs/курцхаар.txt b/server/modules/descriptions/repository/breed_signs/курцхаар.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/курцхаар.txt
rename to server/modules/descriptions/repository/breed_signs/курцхаар.txt
diff --git a/server/services/descriptions/repository/breed_signs/курчавошёрстный_ретривер.txt b/server/modules/descriptions/repository/breed_signs/курчавошёрстный_ретривер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/курчавошёрстный_ретривер.txt
rename to server/modules/descriptions/repository/breed_signs/курчавошёрстный_ретривер.txt
diff --git a/server/services/descriptions/repository/breed_signs/лабрадор-ретривер.txt b/server/modules/descriptions/repository/breed_signs/лабрадор-ретривер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/лабрадор-ретривер.txt
rename to server/modules/descriptions/repository/breed_signs/лабрадор-ретривер.txt
diff --git a/server/services/descriptions/repository/breed_signs/левретка.txt b/server/modules/descriptions/repository/breed_signs/левретка.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/левретка.txt
rename to server/modules/descriptions/repository/breed_signs/левретка.txt
diff --git a/server/services/descriptions/repository/breed_signs/лейкленд-терьер.txt b/server/modules/descriptions/repository/breed_signs/лейкленд-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/лейкленд-терьер.txt
rename to server/modules/descriptions/repository/breed_signs/лейкленд-терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/леонбергер.txt b/server/modules/descriptions/repository/breed_signs/леонбергер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/леонбергер.txt
rename to server/modules/descriptions/repository/breed_signs/леонбергер.txt
diff --git a/server/services/descriptions/repository/breed_signs/лхасский_апсо.txt b/server/modules/descriptions/repository/breed_signs/лхасский_апсо.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/лхасский_апсо.txt
rename to server/modules/descriptions/repository/breed_signs/лхасский_апсо.txt
diff --git a/server/services/descriptions/repository/breed_signs/маламут.txt b/server/modules/descriptions/repository/breed_signs/маламут.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/маламут.txt
rename to server/modules/descriptions/repository/breed_signs/маламут.txt
diff --git a/server/services/descriptions/repository/breed_signs/малинуа.txt b/server/modules/descriptions/repository/breed_signs/малинуа.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/малинуа.txt
rename to server/modules/descriptions/repository/breed_signs/малинуа.txt
diff --git a/server/services/descriptions/repository/breed_signs/малые_бельгийские_собаки.txt b/server/modules/descriptions/repository/breed_signs/малые_бельгийские_собаки.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/малые_бельгийские_собаки.txt
rename to server/modules/descriptions/repository/breed_signs/малые_бельгийские_собаки.txt
diff --git a/server/services/descriptions/repository/breed_signs/мальтийская_болонка.txt b/server/modules/descriptions/repository/breed_signs/мальтийская_болонка.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/мальтийская_болонка.txt
rename to server/modules/descriptions/repository/breed_signs/мальтийская_болонка.txt
diff --git a/server/services/descriptions/repository/breed_signs/миниатюрный_пудель.txt b/server/modules/descriptions/repository/breed_signs/миниатюрный_пудель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/миниатюрный_пудель.txt
rename to server/modules/descriptions/repository/breed_signs/миниатюрный_пудель.txt
diff --git a/server/services/descriptions/repository/breed_signs/миттельшнауцер.txt b/server/modules/descriptions/repository/breed_signs/миттельшнауцер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/миттельшнауцер.txt
rename to server/modules/descriptions/repository/breed_signs/миттельшнауцер.txt
diff --git a/server/services/descriptions/repository/breed_signs/мопс.txt b/server/modules/descriptions/repository/breed_signs/мопс.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/мопс.txt
rename to server/modules/descriptions/repository/breed_signs/мопс.txt
diff --git a/server/services/descriptions/repository/breed_signs/немецкая_овчарка.txt b/server/modules/descriptions/repository/breed_signs/немецкая_овчарка.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/немецкая_овчарка.txt
rename to server/modules/descriptions/repository/breed_signs/немецкая_овчарка.txt
diff --git a/server/services/descriptions/repository/breed_signs/немецкий_дог.txt b/server/modules/descriptions/repository/breed_signs/немецкий_дог.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/немецкий_дог.txt
rename to server/modules/descriptions/repository/breed_signs/немецкий_дог.txt
diff --git a/server/services/descriptions/repository/breed_signs/норвежский_серый_элкхунд.txt b/server/modules/descriptions/repository/breed_signs/норвежский_серый_элкхунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/норвежский_серый_элкхунд.txt
rename to server/modules/descriptions/repository/breed_signs/норвежский_серый_элкхунд.txt
diff --git a/server/services/descriptions/repository/breed_signs/норвич-терьер.txt b/server/modules/descriptions/repository/breed_signs/норвич-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/норвич-терьер.txt
rename to server/modules/descriptions/repository/breed_signs/норвич-терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/норфолк-терьер.txt b/server/modules/descriptions/repository/breed_signs/норфолк-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/норфолк-терьер.txt
rename to server/modules/descriptions/repository/breed_signs/норфолк-терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/ньюфаундленд.txt b/server/modules/descriptions/repository/breed_signs/ньюфаундленд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/ньюфаундленд.txt
rename to server/modules/descriptions/repository/breed_signs/ньюфаундленд.txt
diff --git a/server/services/descriptions/repository/breed_signs/оттерхаунд.txt b/server/modules/descriptions/repository/breed_signs/оттерхаунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/оттерхаунд.txt
rename to server/modules/descriptions/repository/breed_signs/оттерхаунд.txt
diff --git a/server/services/descriptions/repository/breed_signs/пекинес.txt b/server/modules/descriptions/repository/breed_signs/пекинес.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/пекинес.txt
rename to server/modules/descriptions/repository/breed_signs/пекинес.txt
diff --git a/server/services/descriptions/repository/breed_signs/пиренейская _горная_собака.txt b/server/modules/descriptions/repository/breed_signs/пиренейская _горная_собака.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/пиренейская _горная_собака.txt
rename to server/modules/descriptions/repository/breed_signs/пиренейская _горная_собака.txt
diff --git a/server/services/descriptions/repository/breed_signs/поденко_ибиценко.txt b/server/modules/descriptions/repository/breed_signs/поденко_ибиценко.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/поденко_ибиценко.txt
rename to server/modules/descriptions/repository/breed_signs/поденко_ибиценко.txt
diff --git a/server/services/descriptions/repository/breed_signs/померанский_шпиц.txt b/server/modules/descriptions/repository/breed_signs/померанский_шпиц.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/померанский_шпиц.txt
rename to server/modules/descriptions/repository/breed_signs/померанский_шпиц.txt
diff --git a/server/services/descriptions/repository/breed_signs/прямошёрстный_ретривер.txt b/server/modules/descriptions/repository/breed_signs/прямошёрстный_ретривер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/прямошёрстный_ретривер.txt
rename to server/modules/descriptions/repository/breed_signs/прямошёрстный_ретривер.txt
diff --git a/server/services/descriptions/repository/breed_signs/ризеншнауцер.txt b/server/modules/descriptions/repository/breed_signs/ризеншнауцер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/ризеншнауцер.txt
rename to server/modules/descriptions/repository/breed_signs/ризеншнауцер.txt
diff --git a/server/services/descriptions/repository/breed_signs/родезийский риджбек.txt b/server/modules/descriptions/repository/breed_signs/родезийский риджбек.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/родезийский риджбек.txt
rename to server/modules/descriptions/repository/breed_signs/родезийский риджбек.txt
diff --git a/server/services/descriptions/repository/breed_signs/ротвейлер.txt b/server/modules/descriptions/repository/breed_signs/ротвейлер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/ротвейлер.txt
rename to server/modules/descriptions/repository/breed_signs/ротвейлер.txt
diff --git a/server/services/descriptions/repository/breed_signs/русская_псовая_борзая.txt b/server/modules/descriptions/repository/breed_signs/русская_псовая_борзая.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/русская_псовая_борзая.txt
rename to server/modules/descriptions/repository/breed_signs/русская_псовая_борзая.txt
diff --git a/server/services/descriptions/repository/breed_signs/русский_той.txt b/server/modules/descriptions/repository/breed_signs/русский_той.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/русский_той.txt
rename to server/modules/descriptions/repository/breed_signs/русский_той.txt
diff --git a/server/services/descriptions/repository/breed_signs/салюки.txt b/server/modules/descriptions/repository/breed_signs/салюки.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/салюки.txt
rename to server/modules/descriptions/repository/breed_signs/салюки.txt
diff --git a/server/services/descriptions/repository/breed_signs/самоед.txt b/server/modules/descriptions/repository/breed_signs/самоед.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/самоед.txt
rename to server/modules/descriptions/repository/breed_signs/самоед.txt
diff --git a/server/services/descriptions/repository/breed_signs/сенбернар.txt b/server/modules/descriptions/repository/breed_signs/сенбернар.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/сенбернар.txt
rename to server/modules/descriptions/repository/breed_signs/сенбернар.txt
diff --git a/server/services/descriptions/repository/breed_signs/сибирский_хаски.txt b/server/modules/descriptions/repository/breed_signs/сибирский_хаски.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/сибирский_хаски.txt
rename to server/modules/descriptions/repository/breed_signs/сибирский_хаски.txt
diff --git a/server/services/descriptions/repository/breed_signs/силихем-терьер.txt b/server/modules/descriptions/repository/breed_signs/силихем-терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/силихем-терьер.txt
rename to server/modules/descriptions/repository/breed_signs/силихем-терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/стандартный_пудель.txt b/server/modules/descriptions/repository/breed_signs/стандартный_пудель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/стандартный_пудель.txt
rename to server/modules/descriptions/repository/breed_signs/стандартный_пудель.txt
diff --git a/server/services/descriptions/repository/breed_signs/стаффордширский_бультерьер.txt b/server/modules/descriptions/repository/breed_signs/стаффордширский_бультерьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/стаффордширский_бультерьер.txt
rename to server/modules/descriptions/repository/breed_signs/стаффордширский_бультерьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/суссекс-спаниель.txt b/server/modules/descriptions/repository/breed_signs/суссекс-спаниель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/суссекс-спаниель.txt
rename to server/modules/descriptions/repository/breed_signs/суссекс-спаниель.txt
diff --git a/server/services/descriptions/repository/breed_signs/схипперке.txt b/server/modules/descriptions/repository/breed_signs/схипперке.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/схипперке.txt
rename to server/modules/descriptions/repository/breed_signs/схипперке.txt
diff --git a/server/services/descriptions/repository/breed_signs/тибетский_мастиф.txt b/server/modules/descriptions/repository/breed_signs/тибетский_мастиф.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/тибетский_мастиф.txt
rename to server/modules/descriptions/repository/breed_signs/тибетский_мастиф.txt
diff --git a/server/services/descriptions/repository/breed_signs/тибетский_терьер.txt b/server/modules/descriptions/repository/breed_signs/тибетский_терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/тибетский_терьер.txt
rename to server/modules/descriptions/repository/breed_signs/тибетский_терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/той_пудель.txt b/server/modules/descriptions/repository/breed_signs/той_пудель.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/той_пудель.txt
rename to server/modules/descriptions/repository/breed_signs/той_пудель.txt
diff --git a/server/services/descriptions/repository/breed_signs/триин-уокер_кунхаунд.txt b/server/modules/descriptions/repository/breed_signs/триин-уокер_кунхаунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/триин-уокер_кунхаунд.txt
rename to server/modules/descriptions/repository/breed_signs/триин-уокер_кунхаунд.txt
diff --git a/server/services/descriptions/repository/breed_signs/уиппет.txt b/server/modules/descriptions/repository/breed_signs/уиппет.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/уиппет.txt
rename to server/modules/descriptions/repository/breed_signs/уиппет.txt
diff --git a/server/services/descriptions/repository/breed_signs/фландрский_бувье.txt b/server/modules/descriptions/repository/breed_signs/фландрский_бувье.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/фландрский_бувье.txt
rename to server/modules/descriptions/repository/breed_signs/фландрский_бувье.txt
diff --git a/server/services/descriptions/repository/breed_signs/французский_бульдог.txt b/server/modules/descriptions/repository/breed_signs/французский_бульдог.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/французский_бульдог.txt
rename to server/modules/descriptions/repository/breed_signs/французский_бульдог.txt
diff --git a/server/services/descriptions/repository/breed_signs/цвергшнауцер.txt b/server/modules/descriptions/repository/breed_signs/цвергшнауцер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/цвергшнауцер.txt
rename to server/modules/descriptions/repository/breed_signs/цвергшнауцер.txt
diff --git a/server/services/descriptions/repository/breed_signs/чау-чау.txt b/server/modules/descriptions/repository/breed_signs/чау-чау.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/чау-чау.txt
rename to server/modules/descriptions/repository/breed_signs/чау-чау.txt
diff --git a/server/services/descriptions/repository/breed_signs/чесапик-бей-ретривер.txt b/server/modules/descriptions/repository/breed_signs/чесапик-бей-ретривер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/чесапик-бей-ретривер.txt
rename to server/modules/descriptions/repository/breed_signs/чесапик-бей-ретривер.txt
diff --git a/server/services/descriptions/repository/breed_signs/чихуахуа.txt b/server/modules/descriptions/repository/breed_signs/чихуахуа.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/чихуахуа.txt
rename to server/modules/descriptions/repository/breed_signs/чихуахуа.txt
diff --git a/server/services/descriptions/repository/breed_signs/чёрно-подпалый_кунхаунд.txt b/server/modules/descriptions/repository/breed_signs/чёрно-подпалый_кунхаунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/чёрно-подпалый_кунхаунд.txt
rename to server/modules/descriptions/repository/breed_signs/чёрно-подпалый_кунхаунд.txt
diff --git a/server/services/descriptions/repository/breed_signs/шелти.txt b/server/modules/descriptions/repository/breed_signs/шелти.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/шелти.txt
rename to server/modules/descriptions/repository/breed_signs/шелти.txt
diff --git a/server/services/descriptions/repository/breed_signs/ши-тцу.txt b/server/modules/descriptions/repository/breed_signs/ши-тцу.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/ши-тцу.txt
rename to server/modules/descriptions/repository/breed_signs/ши-тцу.txt
diff --git a/server/services/descriptions/repository/breed_signs/шиба_ину.txt b/server/modules/descriptions/repository/breed_signs/шиба_ину.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/шиба_ину.txt
rename to server/modules/descriptions/repository/breed_signs/шиба_ину.txt
diff --git a/server/services/descriptions/repository/breed_signs/шотландский_сеттер.txt b/server/modules/descriptions/repository/breed_signs/шотландский_сеттер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/шотландский_сеттер.txt
rename to server/modules/descriptions/repository/breed_signs/шотландский_сеттер.txt
diff --git a/server/services/descriptions/repository/breed_signs/шотландский_терьер.txt b/server/modules/descriptions/repository/breed_signs/шотландский_терьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/шотландский_терьер.txt
rename to server/modules/descriptions/repository/breed_signs/шотландский_терьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/энтлебухер_зенненхунд.txt b/server/modules/descriptions/repository/breed_signs/энтлебухер_зенненхунд.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/энтлебухер_зенненхунд.txt
rename to server/modules/descriptions/repository/breed_signs/энтлебухер_зенненхунд.txt
diff --git a/server/services/descriptions/repository/breed_signs/эрдельтерьер.txt b/server/modules/descriptions/repository/breed_signs/эрдельтерьер.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/эрдельтерьер.txt
rename to server/modules/descriptions/repository/breed_signs/эрдельтерьер.txt
diff --git a/server/services/descriptions/repository/breed_signs/японский хин.txt b/server/modules/descriptions/repository/breed_signs/японский хин.txt
similarity index 100%
rename from server/services/descriptions/repository/breed_signs/японский хин.txt
rename to server/modules/descriptions/repository/breed_signs/японский хин.txt
diff --git a/server/services/descriptions/repository/repository.py b/server/modules/descriptions/repository/repository.py
similarity index 50%
rename from server/services/descriptions/repository/repository.py
rename to server/modules/descriptions/repository/repository.py
index 9b248b3..aa7d51c 100644
--- a/server/services/descriptions/repository/repository.py
+++ b/server/modules/descriptions/repository/repository.py
@@ -3,7 +3,8 @@ from pathlib import Path
from aiocache import cached, Cache # type: ignore
-from server.services.descriptions.domain import Breed
+from server.infra.db import AsyncDB
+from server.modules.descriptions.domain import Breed
class ACharactersRepository(metaclass=ABCMeta):
@@ -21,7 +22,42 @@ class CharactersRepository(ACharactersRepository):
@cached(ttl=60, cache=Cache.MEMORY)
async def get_characters(self) -> list[Breed]:
- breed_dir = Path("server/services/descriptions/repository/breed_descriptions")
+ breed_dir = Path("server/modules/descriptions/repository/breed_descriptions")
+ breeds: list[Breed] = []
+
+ # Идем по каждому текстовому файлу с описанием породы
+ for breed_file in breed_dir.glob("*.txt"):
+ breed_name = breed_file.stem # имя файла без расширения - название породы
+ description = breed_file.read_text(
+ encoding="utf-8"
+ ) # читаем описание из файла
+ breeds.append(
+ Breed(
+ name=breed_name.replace("_", " "),
+ alias=breed_file.stem,
+ description=description.strip(),
+ )
+ )
+ breeds.sort(key=lambda b: b.name)
+ return breeds
+
+ async def get_character(self, alias: str) -> Breed | None:
+ breeds = await self.get_characters()
+ data = [b for b in breeds if b.alias == alias]
+ if len(data) == 0:
+ return None
+ return data[0]
+
+
+class PGCharactersRepository(ACharactersRepository):
+ _db: AsyncDB
+
+ def __init__(self, db: AsyncDB):
+ self._db = db
+
+ @cached(ttl=60, cache=Cache.MEMORY)
+ async def get_characters(self) -> list[Breed]:
+ breed_dir = Path("server/modules/descriptions/repository/breed_descriptions")
breeds: list[Breed] = []
# Идем по каждому текстовому файлу с описанием породы
diff --git a/server/services/descriptions/service.py b/server/modules/descriptions/service.py
similarity index 75%
rename from server/services/descriptions/service.py
rename to server/modules/descriptions/service.py
index 33d0ad2..d0bac29 100644
--- a/server/services/descriptions/service.py
+++ b/server/modules/descriptions/service.py
@@ -1,5 +1,5 @@
-from server.services.descriptions.domain import Breed
-from server.services.descriptions.repository import ACharactersRepository
+from server.modules.descriptions.domain import Breed
+from server.modules.descriptions.repository import ACharactersRepository
class CharactersService:
diff --git a/server/modules/rate/domain/__init__.py b/server/modules/rate/domain/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/server/modules/rate/repository/__init__.py b/server/modules/rate/repository/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/server/modules/rate/service/__init__.py b/server/modules/rate/service/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/server/services/recognizer/__init__.py b/server/modules/recognizer/__init__.py
similarity index 53%
rename from server/services/recognizer/__init__.py
rename to server/modules/recognizer/__init__.py
index 2a7f6b1..279b8b1 100644
--- a/server/services/recognizer/__init__.py
+++ b/server/modules/recognizer/__init__.py
@@ -1,7 +1,7 @@
-from server.services.recognizer.repository import (
+from server.modules.recognizer.repository import (
RecognizerRepository,
ARecognizerRepository,
)
-from server.services.recognizer.service import RecognizerService
+from server.modules.recognizer.service import RecognizerService
__all__ = ("RecognizerRepository", "ARecognizerRepository", "RecognizerService")
diff --git a/server/modules/recognizer/domain.py b/server/modules/recognizer/domain.py
new file mode 100644
index 0000000..e69de29
diff --git a/server/services/recognizer/repository/__init__.py b/server/modules/recognizer/repository/__init__.py
similarity index 64%
rename from server/services/recognizer/repository/__init__.py
rename to server/modules/recognizer/repository/__init__.py
index 6f6143f..5c7799a 100644
--- a/server/services/recognizer/repository/__init__.py
+++ b/server/modules/recognizer/repository/__init__.py
@@ -1,4 +1,4 @@
-from server.services.recognizer.repository.repository import (
+from server.modules.recognizer.repository.repository import (
RecognizerRepository,
ARecognizerRepository,
)
diff --git a/server/services/recognizer/repository/meta/images.json b/server/modules/recognizer/repository/meta/images.json
similarity index 100%
rename from server/services/recognizer/repository/meta/images.json
rename to server/modules/recognizer/repository/meta/images.json
diff --git a/server/services/recognizer/repository/meta/labels_cats.json b/server/modules/recognizer/repository/meta/labels_cats.json
similarity index 100%
rename from server/services/recognizer/repository/meta/labels_cats.json
rename to server/modules/recognizer/repository/meta/labels_cats.json
diff --git a/server/services/recognizer/repository/meta/labels_dogs.json b/server/modules/recognizer/repository/meta/labels_dogs.json
similarity index 100%
rename from server/services/recognizer/repository/meta/labels_dogs.json
rename to server/modules/recognizer/repository/meta/labels_dogs.json
diff --git a/server/services/recognizer/repository/repository.py b/server/modules/recognizer/repository/repository.py
similarity index 77%
rename from server/services/recognizer/repository/repository.py
rename to server/modules/recognizer/repository/repository.py
index 45bf6f6..0be0291 100644
--- a/server/services/recognizer/repository/repository.py
+++ b/server/modules/recognizer/repository/repository.py
@@ -29,18 +29,18 @@ class RecognizerRepository(ARecognizerRepository):
@cached(ttl=60, cache=Cache.MEMORY)
async def images_dogs(self) -> dict:
- with open("server/services/recognizer/repository/meta/images.json", "r") as f:
+ with open("server/modules/recognizer/repository/meta/images.json", "r") as f:
return ujson.loads(f.read())["dog"]
@cached(ttl=60, cache=Cache.MEMORY)
async def images_cats(self) -> dict:
- with open("server/services/recognizer/repository/meta/images.json", "r") as f:
+ with open("server/modules/recognizer/repository/meta/images.json", "r") as f:
return ujson.loads(f.read())["cat"]
@lru_cache
def labels_cats(self) -> dict:
with open(
- "server/services/recognizer/repository/meta/labels_cats.json", "r"
+ "server/modules/recognizer/repository/meta/labels_cats.json", "r"
) as f:
data_labels = f.read()
return ujson.loads(data_labels)
@@ -48,7 +48,7 @@ class RecognizerRepository(ARecognizerRepository):
@lru_cache
def labels_dogs(self) -> dict:
with open(
- "server/services/recognizer/repository/meta/labels_dogs.json", "r"
+ "server/modules/recognizer/repository/meta/labels_dogs.json", "r"
) as f:
data_labels = f.read()
return ujson.loads(data_labels)
diff --git a/server/services/recognizer/service.py b/server/modules/recognizer/service.py
similarity index 93%
rename from server/services/recognizer/service.py
rename to server/modules/recognizer/service.py
index 59d6737..6d22305 100644
--- a/server/services/recognizer/service.py
+++ b/server/modules/recognizer/service.py
@@ -8,7 +8,7 @@ os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
import torch
from torchvision import transforms # type: ignore
-from server.services.recognizer.repository import ARecognizerRepository
+from server.modules.recognizer.repository import ARecognizerRepository
TorchModel = NewType("TorchModel", torch.nn.Module)
@@ -40,7 +40,7 @@ class RecognizerService:
predicted_data = self._predict(image, DOG_MODEL)
results = {}
images = []
- description = {}
+ description: dict[str, list] = {}
images_dogs = await self._repository.images_dogs()
for d in predicted_data:
predicted_idx, probabilities = d
@@ -55,7 +55,9 @@ class RecognizerService:
],
}
)
- description.setdefault(name, []).append(f"/dogs-characteristics/{name.replace(" ", "_")}")
+ description.setdefault(name, []).append(
+ f"/dogs-characteristics/{name.replace(' ', '_')}"
+ )
results[probabilities] = name
return {
"results": results,
diff --git a/server/services/descriptions/__init__.py b/server/services/descriptions/__init__.py
deleted file mode 100644
index 9df84b7..0000000
--- a/server/services/descriptions/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from server.services.descriptions.repository import (
- CharactersRepository,
- ACharactersRepository,
-)
-from server.services.descriptions.service import CharactersService
-from server.services.descriptions.domain import Breed
-
-__all__ = (
- "CharactersRepository",
- "ACharactersRepository",
- "CharactersService",
- "Breed",
-)
diff --git a/server/templates/base.html b/server/templates/base.html
index 7ecd5af..4bbb1af 100644
--- a/server/templates/base.html
+++ b/server/templates/base.html
@@ -45,6 +45,6 @@
{% block form %}{% endblock %}