feat: add ballot casting endpoint

This commit is contained in:
Alexandre Teles 2022-11-17 02:57:58 -03:00
parent 0b45044649
commit 641bf689a4
6 changed files with 52 additions and 101 deletions

36
app/controllers/Ballot.py Normal file
View File

@ -0,0 +1,36 @@
from redis import asyncio as aioredis
import app.utils.Logger as Logger
from app.dependencies import load_config
from app.utils.RedisConnector import RedisConnector
config: dict = load_config()
class Ballot:
"""Implements a ballot for ReVanced Polling API."""
redis = RedisConnector.connect(config['tokens']['database'])
BallotLogger = Logger.BallotLogger()
async def store(self, discord_hashed_id: str, ballot: str) -> bool:
"""Store a ballot.
Args:
discord_hashed_id (str): Discord hashed ID of the voter
ballot (dict): Ballot to store
Returns:
bool: True if the ballot was stored successfully, False otherwise
"""
stored: bool = False
try:
await self.redis.set(name=discord_hashed_id, value=ballot, nx=True)
await self.BallotLogger.log("STORE_BALLOT", None, discord_hashed_id)
stored = True
except aioredis.RedisError as e:
await self.BallotLogger.log("STORE_BALLOT", e)
raise e
return stored

View File

@ -1,8 +1,4 @@
from time import sleep
from redis import asyncio as aioredis
import uvloop
import app.utils.Logger as Logger
from app.dependencies import load_config
from app.utils.RedisConnector import RedisConnector

View File

@ -1,5 +1,4 @@
import os
import toml
import binascii
from redis import Redis
@ -30,6 +29,7 @@ from app.routers import root
from app.routers import auth
from app.routers import items
from app.routers import ping
from app.routers import ballot
"""Implements an API for our polling app"""
@ -64,6 +64,7 @@ app.add_middleware(SlowAPIMiddleware)
app.include_router(root.router)
app.include_router(items.router)
app.include_router(ballot.router)
app.include_router(auth.router)
app.include_router(ping.router)

View File

@ -1,5 +1,4 @@
from pydantic import BaseModel
from app.models.BallotFields import BallotFields
class BallotModel(BaseModel):
"""Implements the fields for the ballots.
@ -8,5 +7,4 @@ class BallotModel(BaseModel):
BaseModel (pydantic.BaseModel): BaseModel from pydantic
"""
discord_id_hash: str
ballot: str
vote: str

View File

@ -3,33 +3,6 @@ import app.models.ResponseFields as ResponseFields
"""Implements pydantic models and model generator for the API's responses."""
class ToolsResponseModel(BaseModel):
"""Implements the JSON response model for the /tools endpoint.
Args:
BaseModel (pydantic.BaseModel): BaseModel from pydantic
"""
tools: list[ ResponseFields.ToolsResponseFields ]
class PatchesResponseModel(BaseModel):
"""Implements the JSON response model for the /patches endpoint.
Args:
BaseModel (pydantic.BaseModel): BaseModel from pydantic
"""
__root__: list[ ResponseFields.PatchesResponseFields ]
class ContributorsResponseModel(BaseModel):
"""Implements the JSON response model for the /contributors endpoint.
Args:
BaseModel (pydantic.BaseModel): BaseModel from pydantic
"""
repositories: list[ ResponseFields.ContributorsResponseFields ]
class PingResponseModel(BaseModel):
"""Implements the JSON response model for the /heartbeat endpoint.
@ -40,26 +13,6 @@ class PingResponseModel(BaseModel):
status: int
detail: str
class ClientDeletedResponse(BaseModel):
"""Implements the response fields for deleted clients.
Args:
BaseModel (pydantic.BaseModel): BaseModel from pydantic
"""
id: str
deleted: bool
class ClientSecretUpdatedResponse(BaseModel):
"""Implements the response fields for updated client secrets.
Args:
BaseModel (pydantic.BaseModel): BaseModel from pydantic
"""
id: str
secret: str
class ClientAuthTokenResponse(BaseModel):
"""Implements the response fields for client auth tokens.
@ -68,36 +21,6 @@ class ClientAuthTokenResponse(BaseModel):
"""
access_token: str
class ClientTokenRefreshResponse(BaseModel):
"""Implements the response fields for client token refresh.
Args:
BaseModel (pydantic.BaseModel): BaseModel from pydantic
"""
access_token: str
class ClientStatusResponse(BaseModel):
"""Implements the response fields for client status.
Args:
BaseModel (pydantic.BaseModel): BaseModel from pydantic
"""
id: str
active: bool
class ChangelogsResponseModel(BaseModel):
"""Implements the JSON response model for the /changelogs endpoint.
Args:
BaseModel (pydantic.BaseModel): BaseModel from pydantic
"""
repository: str
path: str
commits: list[ ResponseFields.ChangelogsResponseFields ]
class RevokedTokenResponse(BaseModel):
"""Implements the response fields for token invalidation.
@ -107,3 +30,12 @@ class RevokedTokenResponse(BaseModel):
"""
revoked: bool
class BallotCastedResponse(BaseModel):
"""Implements the response fields for ballot casted.
Args:
BaseModel (pydantic.BaseModel): BaseModel from pydantic
"""
casted: bool

View File

@ -51,28 +51,16 @@ class UserLogger:
else:
logger.info(f"[User] REDIS {operation} {key} - OK")
class AnnouncementsLogger:
class BallotLogger:
async def log(self, operation: str, result: RedisError | None = None, key: str = "") -> None:
"""Logs internal cache operations
"""Logs ballot operations
Args:
operation (str): Operation name
key (str): Key used in the operation
"""
if type(result) is RedisError:
logger.error(f"[ANNOUNCEMENT] REDIS {operation} - Failed with error: {result}")
logger.error(f"[BALLOT] REDIS {operation} - Failed with error: {result}")
else:
logger.info(f"[ANNOUNCEMENT] REDIS {operation} {key} - OK")
logger.info(f"[BALLOT] REDIS {operation} {key} - OK")
class MirrorsLogger:
async def log(self, operation: str, result: RedisError | None = None, key: str = "") -> None:
"""Logs internal cache operations
Args:
operation (str): Operation name
key (str): Key used in the operation
"""
if type(result) is RedisError:
logger.error(f"[MIRRORS] REDIS {operation} - Failed with error: {result}")
else:
logger.info(f"[MIRRORS] REDIS {operation} {key} - OK")