Skip to content
Merged
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set dotenv-load := true

COMMON_URL := 'https://raw.githubusercontent.com/esclient/tools/refs/heads/main/python/common.just'

PROTO_TAG := 'v0.1.1'
PROTO_TAG := 'v0.1.2'
PROTO_NAME := 'mod.proto'
TMP_DIR := '.proto'
OUT_DIR := 'src/modservice/grpc'
Expand Down
41 changes: 24 additions & 17 deletions src/modservice/grpc/mod_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 37 additions & 4 deletions src/modservice/grpc/mod_pb2.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import datetime

from google.protobuf import timestamp_pb2 as _timestamp_pb2
from google.protobuf.internal import containers as _containers
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from collections.abc import Iterable as _Iterable, Mapping as _Mapping
from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union

DESCRIPTOR: _descriptor.FileDescriptor
Expand All @@ -16,6 +21,34 @@ MOD_STATUS_UPLOADED: ModStatus
MOD_STATUS_BANNED: ModStatus
MOD_STATUS_HIDDEN: ModStatus

class GetModsRequest(_message.Message):
__slots__ = ()
def __init__(self) -> None: ...

class GetModsResponse(_message.Message):
__slots__ = ("mods",)
MODS_FIELD_NUMBER: _ClassVar[int]
mods: _containers.RepeatedCompositeFieldContainer[Mod]
def __init__(self, mods: _Optional[_Iterable[_Union[Mod, _Mapping]]] = ...) -> None: ...

class Mod(_message.Message):
__slots__ = ("id", "author_id", "title", "description", "version", "status", "created_at")
ID_FIELD_NUMBER: _ClassVar[int]
AUTHOR_ID_FIELD_NUMBER: _ClassVar[int]
TITLE_FIELD_NUMBER: _ClassVar[int]
DESCRIPTION_FIELD_NUMBER: _ClassVar[int]
VERSION_FIELD_NUMBER: _ClassVar[int]
STATUS_FIELD_NUMBER: _ClassVar[int]
CREATED_AT_FIELD_NUMBER: _ClassVar[int]
id: int
author_id: int
title: str
description: str
version: int
status: ModStatus
created_at: _timestamp_pb2.Timestamp
def __init__(self, id: _Optional[int] = ..., author_id: _Optional[int] = ..., title: _Optional[str] = ..., description: _Optional[str] = ..., version: _Optional[int] = ..., status: _Optional[_Union[ModStatus, str]] = ..., created_at: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ...) -> None: ...

class SetStatusRequest(_message.Message):
__slots__ = ("mod_id", "status")
MOD_ID_FIELD_NUMBER: _ClassVar[int]
Expand All @@ -31,16 +64,16 @@ class SetStatusResponse(_message.Message):
def __init__(self, success: bool = ...) -> None: ...

class CreateModRequest(_message.Message):
__slots__ = ("mod_title", "author_id", "filename", "description")
MOD_TITLE_FIELD_NUMBER: _ClassVar[int]
__slots__ = ("title", "author_id", "filename", "description")
TITLE_FIELD_NUMBER: _ClassVar[int]
AUTHOR_ID_FIELD_NUMBER: _ClassVar[int]
FILENAME_FIELD_NUMBER: _ClassVar[int]
DESCRIPTION_FIELD_NUMBER: _ClassVar[int]
mod_title: str
title: str
author_id: int
filename: str
description: str
def __init__(self, mod_title: _Optional[str] = ..., author_id: _Optional[int] = ..., filename: _Optional[str] = ..., description: _Optional[str] = ...) -> None: ...
def __init__(self, title: _Optional[str] = ..., author_id: _Optional[int] = ..., filename: _Optional[str] = ..., description: _Optional[str] = ...) -> None: ...

class CreateModResponse(_message.Message):
__slots__ = ("mod_id", "upload_url", "s3_key")
Expand Down
43 changes: 43 additions & 0 deletions src/modservice/grpc/mod_pb2_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ def __init__(self, channel):
request_serializer=mod__pb2.GetModDownloadLinkRequest.SerializeToString,
response_deserializer=mod__pb2.GetModDownloadLinkResponse.FromString,
_registered_method=True)
self.GetMods = channel.unary_unary(
'/mod.ModService/GetMods',
request_serializer=mod__pb2.GetModsRequest.SerializeToString,
response_deserializer=mod__pb2.GetModsResponse.FromString,
_registered_method=True)


class ModServiceServicer(object):
Expand All @@ -72,6 +77,12 @@ def GetModDownloadLink(self, request, context):
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')

def GetMods(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')


def add_ModServiceServicer_to_server(servicer, server):
rpc_method_handlers = {
Expand All @@ -90,6 +101,11 @@ def add_ModServiceServicer_to_server(servicer, server):
request_deserializer=mod__pb2.GetModDownloadLinkRequest.FromString,
response_serializer=mod__pb2.GetModDownloadLinkResponse.SerializeToString,
),
'GetMods': grpc.unary_unary_rpc_method_handler(
servicer.GetMods,
request_deserializer=mod__pb2.GetModsRequest.FromString,
response_serializer=mod__pb2.GetModsResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'mod.ModService', rpc_method_handlers)
Expand Down Expand Up @@ -181,3 +197,30 @@ def GetModDownloadLink(request,
timeout,
metadata,
_registered_method=True)

@staticmethod
def GetMods(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(
request,
target,
'/mod.ModService/GetMods',
mod__pb2.GetModsRequest.SerializeToString,
mod__pb2.GetModsResponse.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)
2 changes: 1 addition & 1 deletion src/modservice/handler/create_mod.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def CreateMod(
) -> mod_pb2.CreateModResponse:
# Создаем мод
mod_id, s3_key, upload_url = service.create_mod(
request.mod_title,
request.title,
request.author_id,
request.description,
)
Expand Down
35 changes: 35 additions & 0 deletions src/modservice/handler/get_mods.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import grpc

from modservice.grpc import mod_pb2
from modservice.service.service import ModService


def GetMods(
service: ModService,
request: mod_pb2.GetModsRequest, # noqa: ARG001
context: grpc.ServicerContext, # noqa: ARG001
) -> mod_pb2.GetModsResponse:
mods_data = service.get_mods()

mods = []
for mod_data in mods_data:
mod = mod_pb2.Mod(
id=mod_data["id"],
author_id=mod_data["author_id"],
title=mod_data["title"],
description=mod_data["description"],
version=mod_data["version"],
status=mod_data["status"],
created_at=mod_data["created_at"]
if mod_data.get("created_at")
else None,
# TODO: Раскомментировать когда добавятся в БД и proto:
# avatar_url=mod_data.get("avatar_url", ""),
# download_count=mod_data.get("download_count", 0),
# rating=mod_data.get("rating", 0.0),
# tags=mod_data.get("tags", []),
# updated_at=mod_data["updated_at"] if mod_data.get("updated_at") else None,
)
mods.append(mod)

return mod_pb2.GetModsResponse(mods=mods)
8 changes: 8 additions & 0 deletions src/modservice/handler/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from modservice.handler.get_mod_download_link import (
GetDownloadLink as _get_mod_download_link,
)
from modservice.handler.get_mods import GetMods as _get_mods
from modservice.handler.set_status import SetStatus as _set_status
from modservice.service.service import ModService

Expand Down Expand Up @@ -33,3 +34,10 @@ def SetStatus(
context: grpc.ServicerContext,
) -> mod_pb2.SetStatusResponse:
return _set_status(self._service, request, context)

def GetMods(
self,
request: mod_pb2.GetModsRequest,
context: grpc.ServicerContext,
) -> mod_pb2.GetModsResponse:
return _get_mods(self._service, request, context)
4 changes: 2 additions & 2 deletions src/modservice/repository/create_mod.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

def create_mod(
db_pool: ThreadedConnectionPool,
mod_title: str, # noqa: ARG001
title: str, # noqa: ARG001
author_id: int, # noqa: ARG001
description: str, # noqa: ARG001
) -> int:
Expand All @@ -18,7 +18,7 @@ def create_mod(
""",
(
author_id,
mod_title,
title,
description,
1,
),
Expand Down
52 changes: 52 additions & 0 deletions src/modservice/repository/get_mods.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from typing import Any

from psycopg2.pool import ThreadedConnectionPool


def get_mods(
db_pool: ThreadedConnectionPool,
) -> list[dict[str, Any]]:
conn = db_pool.getconn()
try:
with conn.cursor() as cursor:
# NOTE: Поля для будущего добавления в БД:
# - avatar_url
# - download_count
# - rating
# - tags
# - updated_at
cursor.execute(
"""
SELECT
id,
author_id,
title,
description,
version,
s3_key,
status,
created_at
FROM mods
ORDER BY created_at DESC
"""
)

results = cursor.fetchall()

mods = []
for row in results:
mod = {
"id": row[0],
"author_id": row[1],
"title": row[2],
"description": row[3],
"version": row[4],
"s3_key": row[5],
"status": row[6],
"created_at": row[7],
}
mods.append(mod)

return mods
finally:
db_pool.putconn(conn)
2 changes: 1 addition & 1 deletion src/modservice/repository/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

@dataclass
class Mod:
mod_title: str
title: str
author_id: int
filename: str
description: str
12 changes: 10 additions & 2 deletions src/modservice/repository/repository.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from typing import Any

from psycopg2.pool import ThreadedConnectionPool

from modservice.repository.create_mod import create_mod as _create_mod
from modservice.repository.get_mod_s3_key import (
get_mod_s3_key as _get_mod_s3_key,
)
from modservice.repository.get_mods import get_mods as _get_mods
from modservice.repository.insert_s3_key import insert_s3_key as _insert_s3_key
from modservice.repository.set_status import set_status as _set_status

Expand All @@ -14,11 +17,11 @@ def __init__(self, db_pool: ThreadedConnectionPool):

def create_mod(
self,
mod_title: str,
title: str,
author_id: int,
description: str,
) -> int:
return _create_mod(self._db_pool, mod_title, author_id, description)
return _create_mod(self._db_pool, title, author_id, description)

def insert_s3_key(
self,
Expand All @@ -32,3 +35,8 @@ def get_mod_s3_key(self, mod_id: int) -> str:

def set_status(self, mod_id: int, status: str) -> bool:
return _set_status(self._db_pool, mod_id, status)

def get_mods(
self,
) -> list[dict[str, Any]]:
return _get_mods(self._db_pool)
4 changes: 2 additions & 2 deletions src/modservice/service/create_mod.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
def create_mod(
repo: ModRepository,
s3_service: S3Service,
mod_title: str,
title: str,
author_id: int,
description: str,
) -> tuple[int, str, str]:
mod_id = repo.create_mod(mod_title, author_id, description)
mod_id = repo.create_mod(title, author_id, description)

s3_key = repo.insert_s3_key(mod_id, author_id)

Expand Down
Loading
Loading