mirror of
https://github.com/revanced/revanced-polling-api.git
synced 2025-04-29 22:24:26 +02:00
feat: add ballot casting endpoint
This commit is contained in:
parent
0b45044649
commit
641bf689a4
36
app/controllers/Ballot.py
Normal file
36
app/controllers/Ballot.py
Normal 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
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
Loading…
x
Reference in New Issue
Block a user