Add docstrings
This commit is contained in:
+17
@@ -30,6 +30,7 @@ _rabbit_worker: Optional[RabbitWorker] = None
|
|||||||
|
|
||||||
|
|
||||||
def get_rabbit_worker() -> RabbitWorker:
|
def get_rabbit_worker() -> RabbitWorker:
|
||||||
|
"""Returns a singleton instance of the RabbitWorker."""
|
||||||
global _rabbit_worker
|
global _rabbit_worker
|
||||||
if _rabbit_worker is None:
|
if _rabbit_worker is None:
|
||||||
_rabbit_worker = RabbitWorker()
|
_rabbit_worker = RabbitWorker()
|
||||||
@@ -38,6 +39,7 @@ def get_rabbit_worker() -> RabbitWorker:
|
|||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
async def lifespan(app: FastAPI):
|
async def lifespan(app: FastAPI):
|
||||||
|
"""Manages application startup and shutdown events, such as database index creation and cleanup."""
|
||||||
await mongo_worker.create_indexes()
|
await mongo_worker.create_indexes()
|
||||||
if DEV_MODE:
|
if DEV_MODE:
|
||||||
logger.warning("⚠️ DEV_MODE is enabled — docs are exposed and Telegram initData auth is DISABLED")
|
logger.warning("⚠️ DEV_MODE is enabled — docs are exposed and Telegram initData auth is DISABLED")
|
||||||
@@ -92,6 +94,7 @@ MODERATION_SECRET = os.getenv("MODERATION_SECRET", "change-me-in-production")
|
|||||||
async def verify_moderation_secret(
|
async def verify_moderation_secret(
|
||||||
x_moderation_secret: str = Header(..., alias="X-Moderation-Secret"),
|
x_moderation_secret: str = Header(..., alias="X-Moderation-Secret"),
|
||||||
) -> str:
|
) -> str:
|
||||||
|
"""Verifies the moderation secret provided in the request headers."""
|
||||||
if not secrets.compare_digest(x_moderation_secret, MODERATION_SECRET):
|
if not secrets.compare_digest(x_moderation_secret, MODERATION_SECRET):
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_403_FORBIDDEN,
|
status_code=status.HTTP_403_FORBIDDEN,
|
||||||
@@ -103,6 +106,7 @@ async def verify_moderation_secret(
|
|||||||
async def check_user(
|
async def check_user(
|
||||||
user_id: int,
|
user_id: int,
|
||||||
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
||||||
|
"""Checks if a user exists in the database by their user_id."""
|
||||||
result = await mongo.check_user(user_id)
|
result = await mongo.check_user(user_id)
|
||||||
return BaseResponse(result=result)
|
return BaseResponse(result=result)
|
||||||
|
|
||||||
@@ -111,6 +115,7 @@ async def get_user(
|
|||||||
user_id: int,
|
user_id: int,
|
||||||
response: Response,
|
response: Response,
|
||||||
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
||||||
|
"""Retrieves a user's details by their user_id."""
|
||||||
if await mongo.check_user(user_id):
|
if await mongo.check_user(user_id):
|
||||||
result = await mongo.get_user(user_id)
|
result = await mongo.get_user(user_id)
|
||||||
return BaseResponse(result=result)
|
return BaseResponse(result=result)
|
||||||
@@ -124,6 +129,7 @@ async def add_user(
|
|||||||
response: Response,
|
response: Response,
|
||||||
auth_user_id: Optional[int] = Depends(get_current_user_id),
|
auth_user_id: Optional[int] = Depends(get_current_user_id),
|
||||||
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
||||||
|
"""Registers a new user in the database if they do not already exist."""
|
||||||
user_id = auth_user_id if auth_user_id is not None else new_user.user_id
|
user_id = auth_user_id if auth_user_id is not None else new_user.user_id
|
||||||
if user_id is None:
|
if user_id is None:
|
||||||
raise HTTPException(status_code=422, detail="user_id is required")
|
raise HTTPException(status_code=422, detail="user_id is required")
|
||||||
@@ -145,6 +151,7 @@ async def get_card(
|
|||||||
card_id: int,
|
card_id: int,
|
||||||
response: Response,
|
response: Response,
|
||||||
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
||||||
|
"""Retrieves a card's details by its card_id."""
|
||||||
card = await mongo.get_card(card_id)
|
card = await mongo.get_card(card_id)
|
||||||
if card:
|
if card:
|
||||||
return BaseResponse(result=card)
|
return BaseResponse(result=card)
|
||||||
@@ -158,6 +165,7 @@ async def get_random_cards(
|
|||||||
user_id: Optional[int] = None,
|
user_id: Optional[int] = None,
|
||||||
auth_user_id: Optional[int] = Depends(get_current_user_id),
|
auth_user_id: Optional[int] = Depends(get_current_user_id),
|
||||||
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
||||||
|
"""Fetches a set of random active cards that the user has not yet visited."""
|
||||||
resolved_user_id = auth_user_id if auth_user_id is not None else user_id
|
resolved_user_id = auth_user_id if auth_user_id is not None else user_id
|
||||||
if resolved_user_id is None:
|
if resolved_user_id is None:
|
||||||
raise HTTPException(status_code=422, detail="user_id is required")
|
raise HTTPException(status_code=422, detail="user_id is required")
|
||||||
@@ -182,6 +190,7 @@ async def add_card(
|
|||||||
response: Response,
|
response: Response,
|
||||||
auth_user_id: Optional[int] = Depends(get_current_user_id),
|
auth_user_id: Optional[int] = Depends(get_current_user_id),
|
||||||
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
||||||
|
"""Adds a new card to the database and sends it for moderation."""
|
||||||
author_id = auth_user_id if auth_user_id is not None else new_card.author_id
|
author_id = auth_user_id if auth_user_id is not None else new_card.author_id
|
||||||
if author_id is None:
|
if author_id is None:
|
||||||
raise HTTPException(status_code=422, detail="author_id is required")
|
raise HTTPException(status_code=422, detail="author_id is required")
|
||||||
@@ -201,6 +210,7 @@ async def card_accept(
|
|||||||
card_id: int,
|
card_id: int,
|
||||||
response: Response,
|
response: Response,
|
||||||
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
||||||
|
"""Accepts a card after moderation, making it active and visible to users."""
|
||||||
result = await mongo.accept_card(card_id)
|
result = await mongo.accept_card(card_id)
|
||||||
if result.error:
|
if result.error:
|
||||||
response.status_code = status.HTTP_404_NOT_FOUND
|
response.status_code = status.HTTP_404_NOT_FOUND
|
||||||
@@ -211,6 +221,7 @@ async def card_reject(
|
|||||||
card_id: int,
|
card_id: int,
|
||||||
response: Response,
|
response: Response,
|
||||||
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
||||||
|
"""Rejects a card during moderation and removes it from the database."""
|
||||||
result = await mongo.reject_card(card_id)
|
result = await mongo.reject_card(card_id)
|
||||||
if result.error:
|
if result.error:
|
||||||
response.status_code = status.HTTP_404_NOT_FOUND
|
response.status_code = status.HTTP_404_NOT_FOUND
|
||||||
@@ -222,6 +233,7 @@ async def select_choice(
|
|||||||
response: Response,
|
response: Response,
|
||||||
auth_user_id: Optional[int] = Depends(get_current_user_id),
|
auth_user_id: Optional[int] = Depends(get_current_user_id),
|
||||||
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
||||||
|
"""Records a user's choice (A or B) for a specific card."""
|
||||||
user_id = auth_user_id if auth_user_id is not None else choice_data.user_id
|
user_id = auth_user_id if auth_user_id is not None else choice_data.user_id
|
||||||
if user_id is None:
|
if user_id is None:
|
||||||
raise HTTPException(status_code=422, detail="user_id is required")
|
raise HTTPException(status_code=422, detail="user_id is required")
|
||||||
@@ -250,6 +262,7 @@ async def like_card(
|
|||||||
response: Response,
|
response: Response,
|
||||||
auth_user_id: Optional[int] = Depends(get_current_user_id),
|
auth_user_id: Optional[int] = Depends(get_current_user_id),
|
||||||
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
||||||
|
"""Adds a like to a specific card from a user."""
|
||||||
user_id = auth_user_id if auth_user_id is not None else like_data.user_id
|
user_id = auth_user_id if auth_user_id is not None else like_data.user_id
|
||||||
if user_id is None:
|
if user_id is None:
|
||||||
raise HTTPException(status_code=422, detail="user_id is required")
|
raise HTTPException(status_code=422, detail="user_id is required")
|
||||||
@@ -265,6 +278,7 @@ async def dislike_card(
|
|||||||
response: Response,
|
response: Response,
|
||||||
auth_user_id: Optional[int] = Depends(get_current_user_id),
|
auth_user_id: Optional[int] = Depends(get_current_user_id),
|
||||||
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
||||||
|
"""Adds a dislike to a specific card from a user."""
|
||||||
user_id = auth_user_id if auth_user_id is not None else dislike_data.user_id
|
user_id = auth_user_id if auth_user_id is not None else dislike_data.user_id
|
||||||
if user_id is None:
|
if user_id is None:
|
||||||
raise HTTPException(status_code=422, detail="user_id is required")
|
raise HTTPException(status_code=422, detail="user_id is required")
|
||||||
@@ -281,6 +295,7 @@ async def comment(
|
|||||||
response: Response,
|
response: Response,
|
||||||
auth_user_id: Optional[int] = Depends(get_current_user_id),
|
auth_user_id: Optional[int] = Depends(get_current_user_id),
|
||||||
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
||||||
|
"""Adds a comment to a specific card after passing basic moderation."""
|
||||||
author_id = auth_user_id if auth_user_id is not None else comment_info.author_id
|
author_id = auth_user_id if auth_user_id is not None else comment_info.author_id
|
||||||
if author_id is None:
|
if author_id is None:
|
||||||
raise HTTPException(status_code=422, detail="author_id is required")
|
raise HTTPException(status_code=422, detail="author_id is required")
|
||||||
@@ -302,6 +317,7 @@ async def get_comments(
|
|||||||
card_id: int,
|
card_id: int,
|
||||||
response: Response,
|
response: Response,
|
||||||
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
mongo: MongoWorker = Depends(lambda: mongo_worker),) -> BaseResponse:
|
||||||
|
"""Retrieves all comments for a specific card."""
|
||||||
result = await mongo.get_comments(card_id)
|
result = await mongo.get_comments(card_id)
|
||||||
if result.error:
|
if result.error:
|
||||||
response.status_code = status.HTTP_404_NOT_FOUND
|
response.status_code = status.HTTP_404_NOT_FOUND
|
||||||
@@ -310,6 +326,7 @@ async def get_comments(
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
|
"""Starts the Uvicorn web server running the FastAPI application."""
|
||||||
config = uvicorn.Config("main:app", host="0.0.0.0", port=5000, log_level="warning")
|
config = uvicorn.Config("main:app", host="0.0.0.0", port=5000, log_level="warning")
|
||||||
server = uvicorn.Server(config)
|
server = uvicorn.Server(config)
|
||||||
await server.serve()
|
await server.serve()
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ from logger import logger
|
|||||||
|
|
||||||
|
|
||||||
class MongoWorker:
|
class MongoWorker:
|
||||||
|
"""Worker class for handling all MongoDB database operations."""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
"""Initializes the MongoDB connection and sets up collection references."""
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
self.client = motor.motor_asyncio.AsyncIOMotorClient(
|
self.client = motor.motor_asyncio.AsyncIOMotorClient(
|
||||||
host=os.getenv('MONGO_HOST'),
|
host=os.getenv('MONGO_HOST'),
|
||||||
@@ -46,11 +48,13 @@ class MongoWorker:
|
|||||||
|
|
||||||
|
|
||||||
async def check_user(self, user_id: int) -> bool:
|
async def check_user(self, user_id: int) -> bool:
|
||||||
|
"""Checks if a user exists in the database by their user_id."""
|
||||||
document = await self.users_data.find_one({"user_id": user_id}, {"_id": 1})
|
document = await self.users_data.find_one({"user_id": user_id}, {"_id": 1})
|
||||||
return document is not None
|
return document is not None
|
||||||
|
|
||||||
async def add_user(
|
async def add_user(
|
||||||
self, user_id: int, username: str, first_name: str, last_name: str, photo_url: str) -> User:
|
self, user_id: int, username: str, first_name: str, last_name: str, photo_url: str) -> User:
|
||||||
|
"""Creates a new user record in the database."""
|
||||||
new_user = User(
|
new_user = User(
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
username=username,
|
username=username,
|
||||||
@@ -64,6 +68,7 @@ class MongoWorker:
|
|||||||
return new_user
|
return new_user
|
||||||
|
|
||||||
async def get_user(self, user_id: int) -> User:
|
async def get_user(self, user_id: int) -> User:
|
||||||
|
"""Retrieves a user's details from the database."""
|
||||||
document = await self.users_data.find_one({"user_id": user_id})
|
document = await self.users_data.find_one({"user_id": user_id})
|
||||||
return User.model_validate(document)
|
return User.model_validate(document)
|
||||||
|
|
||||||
@@ -80,6 +85,7 @@ class MongoWorker:
|
|||||||
|
|
||||||
|
|
||||||
async def get_visited_cards(self, user_id: int) -> BaseResponse:
|
async def get_visited_cards(self, user_id: int) -> BaseResponse:
|
||||||
|
"""Retrieves the set of card IDs that a user has already visited."""
|
||||||
document = await self.visited_data.find_one({"user_id": user_id})
|
document = await self.visited_data.find_one({"user_id": user_id})
|
||||||
if not document:
|
if not document:
|
||||||
if await self.check_user(user_id):
|
if await self.check_user(user_id):
|
||||||
@@ -88,6 +94,7 @@ class MongoWorker:
|
|||||||
return BaseResponse(result=Visited.model_validate(document))
|
return BaseResponse(result=Visited.model_validate(document))
|
||||||
|
|
||||||
async def update_visited_cards(self, user_id: int, visited_card_id: int) -> Visited:
|
async def update_visited_cards(self, user_id: int, visited_card_id: int) -> Visited:
|
||||||
|
"""Adds a specific card ID to the user's set of visited cards."""
|
||||||
updated = await self.visited_data.find_one_and_update(
|
updated = await self.visited_data.find_one_and_update(
|
||||||
{"user_id": user_id},
|
{"user_id": user_id},
|
||||||
{"$addToSet": {"cards_visited": visited_card_id}},
|
{"$addToSet": {"cards_visited": visited_card_id}},
|
||||||
@@ -131,6 +138,7 @@ class MongoWorker:
|
|||||||
|
|
||||||
|
|
||||||
async def get_card(self, card_id: int) -> Optional[Card]:
|
async def get_card(self, card_id: int) -> Optional[Card]:
|
||||||
|
"""Retrieves a card's details from the database by its card_id."""
|
||||||
document = await self.game_data.find_one({"card_id": card_id})
|
document = await self.game_data.find_one({"card_id": card_id})
|
||||||
if document:
|
if document:
|
||||||
return Card.model_validate(document)
|
return Card.model_validate(document)
|
||||||
@@ -153,11 +161,13 @@ class MongoWorker:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def filter_cards(self, random_cards: list[Card], cards_visited: set) -> tuple[list[Card], list[int]]:
|
def filter_cards(self, random_cards: list[Card], cards_visited: set) -> tuple[list[Card], list[int]]:
|
||||||
|
"""Filters a list of random cards to exclude those already visited by the user."""
|
||||||
filtered_cards = [card for card in random_cards if card.card_id not in cards_visited]
|
filtered_cards = [card for card in random_cards if card.card_id not in cards_visited]
|
||||||
filtered_cards_id = [card.card_id for card in filtered_cards]
|
filtered_cards_id = [card.card_id for card in filtered_cards]
|
||||||
return filtered_cards, filtered_cards_id
|
return filtered_cards, filtered_cards_id
|
||||||
|
|
||||||
async def add_card_by_api(self, choice_A: str, choice_B: str, author_id: int) -> Card:
|
async def add_card_by_api(self, choice_A: str, choice_B: str, author_id: int) -> Card:
|
||||||
|
"""Creates a new card in the database with data received from the API."""
|
||||||
new_card = Card(
|
new_card = Card(
|
||||||
card_id=await self.get_and_update_counter(counter_name="card"),
|
card_id=await self.get_and_update_counter(counter_name="card"),
|
||||||
choice_A=choice_A,
|
choice_A=choice_A,
|
||||||
@@ -170,6 +180,7 @@ class MongoWorker:
|
|||||||
return new_card
|
return new_card
|
||||||
|
|
||||||
async def add_card_by_base_model(self, new_card: Card) -> Optional[Card]:
|
async def add_card_by_base_model(self, new_card: Card) -> Optional[Card]:
|
||||||
|
"""Inserts a Card model directly into the database."""
|
||||||
new_card.card_id = await self.get_and_update_counter(counter_name="card")
|
new_card.card_id = await self.get_and_update_counter(counter_name="card")
|
||||||
try:
|
try:
|
||||||
await self.game_data.insert_one(new_card.model_dump())
|
await self.game_data.insert_one(new_card.model_dump())
|
||||||
@@ -204,6 +215,7 @@ class MongoWorker:
|
|||||||
return BaseResponse(result=f"Card {card_id} rejected and deleted")
|
return BaseResponse(result=f"Card {card_id} rejected and deleted")
|
||||||
|
|
||||||
async def select_choice(self, card_id: int, choice: str) -> BaseResponse:
|
async def select_choice(self, card_id: int, choice: str) -> BaseResponse:
|
||||||
|
"""Increments the vote count for the selected choice (A or B) and total votes on a card."""
|
||||||
if choice == "A":
|
if choice == "A":
|
||||||
count_field = "count_choice_A"
|
count_field = "count_choice_A"
|
||||||
elif choice == "B":
|
elif choice == "B":
|
||||||
@@ -221,6 +233,7 @@ class MongoWorker:
|
|||||||
|
|
||||||
|
|
||||||
async def like_card(self, card_id: int, user_id: int) -> BaseResponse:
|
async def like_card(self, card_id: int, user_id: int) -> BaseResponse:
|
||||||
|
"""Atomically adds a like to a card and records the user's like action."""
|
||||||
if not await self.check_user(user_id):
|
if not await self.check_user(user_id):
|
||||||
return BaseResponse(result="User doesn't exist", error=True)
|
return BaseResponse(result="User doesn't exist", error=True)
|
||||||
|
|
||||||
@@ -256,6 +269,7 @@ class MongoWorker:
|
|||||||
return BaseResponse(result=True, error=False)
|
return BaseResponse(result=True, error=False)
|
||||||
|
|
||||||
async def dislike_card(self, card_id: int, user_id: int) -> BaseResponse:
|
async def dislike_card(self, card_id: int, user_id: int) -> BaseResponse:
|
||||||
|
"""Atomically adds a dislike to a card and records the user's dislike action."""
|
||||||
if not await self.check_user(user_id):
|
if not await self.check_user(user_id):
|
||||||
return BaseResponse(result="User doesn't exist", error=True)
|
return BaseResponse(result="User doesn't exist", error=True)
|
||||||
|
|
||||||
@@ -289,6 +303,7 @@ class MongoWorker:
|
|||||||
|
|
||||||
|
|
||||||
async def add_comment(self, user_id: int, card_id: int, comment_text: str) -> BaseResponse:
|
async def add_comment(self, user_id: int, card_id: int, comment_text: str) -> BaseResponse:
|
||||||
|
"""Adds a new comment to a card and links it to the user."""
|
||||||
if not await self.check_user(user_id):
|
if not await self.check_user(user_id):
|
||||||
return BaseResponse(result="User doesn't exist", error=True)
|
return BaseResponse(result="User doesn't exist", error=True)
|
||||||
if not await self.get_card(card_id):
|
if not await self.get_card(card_id):
|
||||||
@@ -315,6 +330,7 @@ class MongoWorker:
|
|||||||
return BaseResponse(result=new_comment)
|
return BaseResponse(result=new_comment)
|
||||||
|
|
||||||
async def get_comments(self, card_id: int) -> BaseResponse:
|
async def get_comments(self, card_id: int) -> BaseResponse:
|
||||||
|
"""Retrieves all comments associated with a specific card_id."""
|
||||||
if not await self.get_card(card_id):
|
if not await self.get_card(card_id):
|
||||||
return BaseResponse(result="Card doesn't exist", error=True)
|
return BaseResponse(result="Card doesn't exist", error=True)
|
||||||
comments = await self.comments_data.find({"card_id": card_id}).sort("creation_date", -1).to_list(length=None)
|
comments = await self.comments_data.find({"card_id": card_id}).sort("creation_date", -1).to_list(length=None)
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ from logger import logger
|
|||||||
|
|
||||||
|
|
||||||
class RabbitWorker:
|
class RabbitWorker:
|
||||||
|
"""Handles RabbitMQ connections and message publishing/consuming for moderation."""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
"""Initializes the RabbitWorker with connection credentials from environment variables."""
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
self.url = (
|
self.url = (
|
||||||
f"amqp://{os.getenv('RABBIT_USER')}:{os.getenv('RABBIT_PASS')}"
|
f"amqp://{os.getenv('RABBIT_USER')}:{os.getenv('RABBIT_PASS')}"
|
||||||
@@ -21,6 +23,7 @@ class RabbitWorker:
|
|||||||
logger.info("RabbitWorker connection established.")
|
logger.info("RabbitWorker connection established.")
|
||||||
|
|
||||||
async def send_to_moderation(self, card: Card) -> None:
|
async def send_to_moderation(self, card: Card) -> None:
|
||||||
|
"""Publishes a card to the 'moderation' RabbitMQ queue."""
|
||||||
logger.debug("Preparing to send card {} to moderation queue...", card.card_id)
|
logger.debug("Preparing to send card {} to moderation queue...", card.card_id)
|
||||||
connection = await aio_pika.connect_robust(self.url)
|
connection = await aio_pika.connect_robust(self.url)
|
||||||
async with connection:
|
async with connection:
|
||||||
@@ -40,6 +43,12 @@ class RabbitWorker:
|
|||||||
self,
|
self,
|
||||||
callback: Callable[[Card], Awaitable[None]],
|
callback: Callable[[Card], Awaitable[None]],
|
||||||
) -> None:
|
) -> None:
|
||||||
|
"""
|
||||||
|
Consumes messages from the 'moderation' queue and processes them using the provided callback.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
callback: An async function that takes a Card object and processes it.
|
||||||
|
"""
|
||||||
connection = await aio_pika.connect_robust(self.url)
|
connection = await aio_pika.connect_robust(self.url)
|
||||||
async with connection:
|
async with connection:
|
||||||
channel = await connection.channel()
|
channel = await connection.channel()
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ async def call_moderation_api(action: str, card_id: int) -> dict:
|
|||||||
# ── Callback button handlers ───────────────────────────────
|
# ── Callback button handlers ───────────────────────────────
|
||||||
@dp.callback_query(F.data.startswith("accept:"))
|
@dp.callback_query(F.data.startswith("accept:"))
|
||||||
async def on_accept(callback: CallbackQuery) -> None:
|
async def on_accept(callback: CallbackQuery) -> None:
|
||||||
|
"""Handles the 'Accept' inline button click for a card."""
|
||||||
if not callback.data or not isinstance(callback.message, Message):
|
if not callback.data or not isinstance(callback.message, Message):
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -138,6 +139,7 @@ async def on_accept(callback: CallbackQuery) -> None:
|
|||||||
|
|
||||||
@dp.callback_query(F.data.startswith("reject:"))
|
@dp.callback_query(F.data.startswith("reject:"))
|
||||||
async def on_reject(callback: CallbackQuery) -> None:
|
async def on_reject(callback: CallbackQuery) -> None:
|
||||||
|
"""Handles the 'Reject' inline button click for a card."""
|
||||||
if not callback.data or not isinstance(callback.message, Message):
|
if not callback.data or not isinstance(callback.message, Message):
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -162,6 +164,7 @@ _rabbit_task: asyncio.Task | None = None
|
|||||||
|
|
||||||
@dp.startup()
|
@dp.startup()
|
||||||
async def on_startup() -> None:
|
async def on_startup() -> None:
|
||||||
|
"""Starts the RabbitMQ consumer task when the bot starts."""
|
||||||
global _rabbit_task
|
global _rabbit_task
|
||||||
_rabbit_task = asyncio.create_task(
|
_rabbit_task = asyncio.create_task(
|
||||||
rabbit.consume_moderation(send_card_to_admin)
|
rabbit.consume_moderation(send_card_to_admin)
|
||||||
@@ -171,6 +174,7 @@ async def on_startup() -> None:
|
|||||||
|
|
||||||
@dp.shutdown()
|
@dp.shutdown()
|
||||||
async def on_shutdown() -> None:
|
async def on_shutdown() -> None:
|
||||||
|
"""Cancels the RabbitMQ consumer task when the bot shuts down."""
|
||||||
if _rabbit_task:
|
if _rabbit_task:
|
||||||
_rabbit_task.cancel()
|
_rabbit_task.cancel()
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user