diff --git a/config.json b/config.json index ecb1932..30480c5 100644 --- a/config.json +++ b/config.json @@ -3,7 +3,7 @@ "host": "localhost", "port": 3306, "user": "root", - "password": "", + "password": "root", "database": "pywinbd" }, "redis": { @@ -28,7 +28,7 @@ "demonRate": 0, "leaderboards_limit": 5, "lang": "en", - "path": "/winnertestss" + "path": "/winners" }, "json:api": { "isWorked": true, diff --git a/config.py b/config.py index 02e3482..5dcfbe5 100644 --- a/config.py +++ b/config.py @@ -52,6 +52,7 @@ def parse_config(): try: with open("./config.json", "r") as config: json_object = json.load(config) + print(json_object["use_env"]) if json_object["use_env"]: parsedb = { "host": os.environ.get("POSTGRES_HOST"), @@ -97,6 +98,7 @@ def parse_config(): database = Database(**json_object["database"]) system = System(**json_object["system"]) redis = Redis(**json_object["redis"]) + print(system) return {"database": database, "system": system, "redis": redis, "small_chest": chest_small, "big_chest": chest_big} except KeyError as ex: print(ex) @@ -111,4 +113,6 @@ def parse_config(): system = conf["system"] redis = conf["redis"] small_chest = conf["small_chest"] -big_chest = conf["big_chest"] \ No newline at end of file +big_chest = conf["big_chest"] + +print(system) \ No newline at end of file diff --git a/src/__init__.py b/src/__init__.py index 50cc2a1..bc0db8a 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -15,7 +15,7 @@ async def on_startup() -> None: def init_apis(app: FastAPI) -> None: - app.mount("/winnertestss", init_gd()) + app.mount("/winners", init_gd()) app.mount("/v2", init_api()) diff --git a/src/api/levels/get_levels.py b/src/api/levels/get_levels.py index cefd898..393b1f1 100644 --- a/src/api/levels/get_levels.py +++ b/src/api/levels/get_levels.py @@ -1,51 +1,44 @@ import numpy from fastapi import APIRouter -from fastapi.responses import JSONResponse - -from src.errors import GenericError -from src.schemas.levels.model import APILevelSchema -from src.schemas.levels.service.get import GetLevel -from src.schemas.levels.errors import LevelNotFoundError -from src.errors import GenericError router = APIRouter(prefix="/levels", tags=["Levels"]) -@router.get("/{lvlid}", summary="Get level by id", responses={ - 404: { - "model": GenericError, - "description": "level with this ID not found" - } -} - ) -async def get_levels(lvlid: int) -> JSONResponse: - levelData: LevelModel = (await LevelService.get_level_buid(levelID=lvlid))["database"] - return levelData.to_API_model() - - -@router.post("/search", summary="Searching levels by filter", responses={ - 404: { - "model": GenericError, - "description": "level with this ID not found" - } -} - ) -async def get_levelsByFilters(filters: GetLevel) -> list[APILevelSchema]: - """ - Endpoint to get levels by filters - - Return list of APILevel - """ - try: - levelData: list[LevelModel] = (await LevelService.test_get_levels(filters))['database'] - result = list[APILevelSchema] - - for i in numpy.arange(levelData): # Fast range - result.append(i.to_API_model()) - - return result - - except LevelNotFoundError: - return GenericError("Level Not Found", 404) - - except TypeError as e: - return GenericError(f"Internal Generic Error {e}", 500) +# @router.get("/{lvlid}", summary="Get level by id", responses={ +# 404: { +# "model": GenericError, +# "description": "level with this ID not found" +# } +# } +# ) +# async def get_levels(lvlid: int) -> JSONResponse: +# levelData: LevelModel = (await LevelService.get_level_buid(levelID=lvlid))["database"] +# return levelData.to_API_model() +# +# +# @router.post("/search", summary="Searching levels by filter", responses={ +# 404: { +# "model": GenericError, +# "description": "level with this ID not found" +# } +# } +# ) +# async def get_levelsByFilters(filters: GetLevel) -> list[APILevelSchema]: +# """ +# Endpoint to get levels by filters +# +# Return list of APILevel +# """ +# try: +# levelData: list[LevelModel] = (await LevelService.test_get_levels(filters))['database'] +# result = list[APILevelSchema] +# +# for i in numpy.arange(levelData): # Fast range +# result.append(i.to_API_model()) +# +# return result +# +# except LevelNotFoundError: +# return GenericError("Level Not Found", 404) +# +# except TypeError as e: +# return GenericError(f"Internal Generic Error {e}", 500) diff --git a/src/api/scores/get_scores.py b/src/api/scores/get_scores.py index 6b217ca..493a3ff 100644 --- a/src/api/scores/get_scores.py +++ b/src/api/scores/get_scores.py @@ -1,8 +1,7 @@ from fastapi import APIRouter -from src.schemas.scores.get import Leaderboard router = APIRouter(prefix="/scores", tags=["Scores"]) -@router.get("/") -async def get_scores() -> Leaderboard: - return await LeaderBoardsService.leaderboard("top") \ No newline at end of file +# @router.get("/") +# async def get_scores() -> Leaderboard: +# return await LeaderBoardsService.leaderboard("top") \ No newline at end of file diff --git a/src/api/users/get_users.py b/src/api/users/get_users.py index 39c11e7..410668d 100644 --- a/src/api/users/get_users.py +++ b/src/api/users/get_users.py @@ -1,21 +1,27 @@ from fastapi import APIRouter, Depends - +from src.depends.context import Context router = APIRouter(prefix="/users", tags=["Users"]) @router.get("/{usrid}") -async def get_user(usrid): - info(f"Request to api | /api/users/{usrid}") - userData = (await UserService.get_user_byid(id=usrid))["database"] - return { - "status": "ok", - "userName": userData.userName, - "role": userData.role, - "stats": { - "stars": userData.stars, - "diamonds": userData.diamonds, - "coins": userData.coins, - "iconkits": userData.iconkits, - }, - } +async def get_user( + usrid: int, + context: Context, +): + async with context: + user = await context.services.users.get_user_byid(usrid) + return user + # info(f"Request to api | /api/users/{usrid}") + # userData = (await UserService.get_user_byid(id=usrid))["database"] + # return { + # "status": "ok", + # "userName": userData.userName, + # "role": userData.role, + # "stats": { + # "stars": userData.stars, + # "diamonds": userData.diamonds, + # "coins": userData.coins, + # "iconkits": userData.iconkits, + # }, + # } diff --git a/src/gd/accounts/auth.py b/src/gd/accounts/auth.py index 7f1b337..1de6cd9 100644 --- a/src/gd/accounts/auth.py +++ b/src/gd/accounts/auth.py @@ -28,8 +28,8 @@ async def register_account( Return status code """ try: - await UserService().register_user( - userName=userName, password=password, mail=email, ip=request.client.host, ctx=context + await UserService(ctx=context).register_user( + userName=userName, password=password, mail=email, ip=request.client.host ) return PlainTextResponse("1", 200) @@ -52,7 +52,7 @@ async def login( Return userid or error code """ try: - user: UsersModel = await UserService.login_user(context, userName, gjp2) + user: UsersModel = await UserService(ctx=context).login_user(userName, gjp2) return f"{user.id},{user.id}" # Validate errors diff --git a/src/gd/accounts/page.py b/src/gd/accounts/page.py index 3581986..9c29d57 100644 --- a/src/gd/accounts/page.py +++ b/src/gd/accounts/page.py @@ -77,6 +77,7 @@ async def updateGJUserScore22( color2: int = Form(), color3: int = Form() ): + print(stars) async with context: if await checkValidGJP2(ctx=context, id=accountID, gjp2=gjp2): iconkit = { diff --git a/src/gd/levels/levels.py b/src/gd/levels/levels.py index 221616c..81909a6 100644 --- a/src/gd/levels/levels.py +++ b/src/gd/levels/levels.py @@ -12,13 +12,13 @@ from src.schemas.levels.service.get import GetLevel from src.services.daily import DailyService from src.services.levels import LevelService -from src.utils.security import checkValidGJP2 from src.schemas.levels.errors import * router = APIRouter(tags=["Levels"]) @router.post("/uploadGJLevel21.php") async def upload_level( + context: Context, levelString: str = Form(), accountID: int = Form(), levelName: str = Form(), @@ -37,39 +37,32 @@ async def upload_level( gameVersion: int = Form(), gjp2: str = Form(), ): - - if await checkValidGJP2(accountID, gjp2=gjp2): - SystemObj = UploadLevel( - levelString=levelString, - accountID=accountID, - levelName=levelName, - levelDesc=levelDesc, - levelVersion=levelVersion, - levelLength=levelLength, - audioTrack=audioTrack, - password=password, - original=original, - twoPlayer=twoPlayer, - songID=songID, - objects=objects, - coins=coins, - requestedStars=requestedStars, - ldm=ldm, - gameVersion=gameVersion, - ) - service = await LevelService().upload_level(data=SystemObj) - # dispatch(Events.NewLevel, LevelObject(service)) - if service["status"] == "ok": - print("its okey") - return service["level"].id - else: - error(service["details"]) - return "-1" + SystemObj = UploadLevel( + levelString=levelString, + accountID=accountID, + levelName=levelName, + levelDesc=levelDesc, + levelVersion=levelVersion, + levelLength=levelLength, + audioTrack=audioTrack, + password=password, + original=original, + twoPlayer=twoPlayer, + songID=songID, + objects=objects, + coins=coins, + requestedStars=requestedStars, + ldm=ldm, + gameVersion=gameVersion, + ) + service = await LevelService(context).upload_level(data=SystemObj, gjp=gjp2) + if service["status"] == "ok": + print("its okey") + return str(service["level"].id) else: - print("ups") + error(service["details"]) return "-1" - @router.post("/getGJLevels21.php") # @cache( # ttl=f"{redis.ttl}s", diff --git a/src/gd/misc/likes.py b/src/gd/misc/likes.py index 3324611..837032a 100644 --- a/src/gd/misc/likes.py +++ b/src/gd/misc/likes.py @@ -1,6 +1,6 @@ from fastapi import APIRouter, Form from fastapi.responses import PlainTextResponse - +from src.depends.context import Context from config import system from src.objects.levelObject import LevelObject from src.services.levels import LevelService @@ -9,32 +9,30 @@ @router.post( - f"{system.path}/likeGJItem211.php", response_class=PlainTextResponse, tags=["Misc"] + f"/likeGJItem211.php", response_class=PlainTextResponse, tags=["Misc"] ) async def like_item( + context: Context, itemID: str = Form(), liketype: int = Form(alias="type"), accountID: str = Form(), like: int = Form(), ): - if liketype == 1: - if like == 1: - service = await LevelService.get_level_buid(levelID=itemID) - - like = await LevelObject(service=service).like(accountID=accountID) - if like["status"] == "ok": - info("Like") - return "1" - - elif like == 0: - service = await LevelService.get_level_buid(levelID=itemID) - - like = await LevelObject(service=service).dislike( - accountID=accountID - ) - if like["status"] == "ok": - info("Dislike") - return "1" + async with context: + if liketype == 1: + if like == 1: + like = await (await LevelService(context).get_level_buid(itemID)).like(accountID) + + if like["status"] == "ok": + context.console.info("Like") + return "1" + + elif like == 0: + dislike = await (await LevelService(context).get_level_buid(itemID)).dislike(accountID) + + if dislike["status"] == "ok": + context.console.info("Dislike") + return "1" # class testClass: diff --git a/src/gd/music/musix.py b/src/gd/music/musix.py index fdf32c1..72654eb 100644 --- a/src/gd/music/musix.py +++ b/src/gd/music/musix.py @@ -20,69 +20,14 @@ async def get_song(req: Request): print(await req.form()) return "https://geometrydashfiles.b-cdn.net/" -@router.post(f"{system.path}/getGJSongInfo.php", response_class=PlainTextResponse) -async def get_song(songID: str = Form()): - song_db = ( - (await db.execute(select(SongsModel).filter(SongsModel.id == songID))) - .scalars() - .first() - ) - - if song_db is not None: - songID = song_db.id - name = song_db.name - author = song_db.author - size = song_db.size - link = song_db.link - if "musix:" in song_db.link: - if "yt" in song_db.link: - print(song_db.link) - musixID = song_db.link.split(":")[-1].split("-")[-1] - print(musixID) - link = f"http://95.163.240.218/data/{musixID}.mp3" - - print(link) +@router.post(f"/getGJSongInfo.php", response_class=PlainTextResponse) +async def get_song(songID: str = Form()): + if songID == "100000": + name = "Noko Shikanoko" + author = "Shikairo Days" + link = "https://uznavo.com/files/mp3/rus-mp3/shikairo-days-noko-shikanoko.mp3" + size = 7.79 return f"1~|~{songID}~|~2~|~{name}~|~3~|~2159~|~4~|~{author}~|~5~|~{size}~|~6~|~~|~10~|~{link}~|~7~|~UCejLri1RVC7kj8ZVNX2a53g" -class get_musix(BaseModel): - status: str - type: str - name: str - author: str - size: float - link: str - - -@router.post("/musix") -async def musix_get( - data: get_musix, - Authorization: Annotated[str, Header()], -): - global song_link - try: - if Authorization == SECRET: - if data.type == "yt": - song_link = f"musix:yt-{data.link}" - elif data.type == "ng": - song_link = data.link - db_model = SongsModel( - name=data.name, author=data.author, size=data.size, link=song_link - ) - db.add(db_model) - await db.commit() - await db.refresh(db_model) - return {"status": "ok", "id": db_model.id} - else: - print("error 2") - return {"status": "error"} - except Exception as ex: - print(ex) - return {"status": "error"} - - -# class setup_musix(BaseModel): - -# @router.post('/musix/setup') -# async def setup_musix(): diff --git a/src/gd/rate/rate_levels.py b/src/gd/rate/rate_levels.py index 5236b8d..97255ad 100644 --- a/src/gd/rate/rate_levels.py +++ b/src/gd/rate/rate_levels.py @@ -9,7 +9,7 @@ router = APIRouter(tags=["rate"], prefix="") -@router.post(f"{system.path}/suggestGJStars20.php", response_class=PlainTextResponse) +@router.post(f"/suggestGJStars20.php", response_class=PlainTextResponse) async def suggestGJStars( accountID: int = Form(), gjp: str = Form(), @@ -46,7 +46,7 @@ async def suggestGJStars( return "-1" -@router.post(f"{system.path}/rateGJStars211.php", response_class=PlainTextResponse) +@router.post(f"/rateGJStars211.php", response_class=PlainTextResponse) async def rate_stars( gjp: str = Form(), stars: int = Form(), diff --git a/src/gd/rewards/chest.py b/src/gd/rewards/chest.py index 8b8ef5a..6625601 100644 --- a/src/gd/rewards/chest.py +++ b/src/gd/rewards/chest.py @@ -24,6 +24,7 @@ async def chest( rewardType: int = Form(default=0), # gjp: str = Form(), device: str = Form(..., alias="udid"), + context: , ): resultchk = xor_cipher(base64_decode(chk[5:]), "59182") diff --git a/src/gd/scores/scores.py b/src/gd/scores/scores.py index 665cded..a8c2d56 100644 --- a/src/gd/scores/scores.py +++ b/src/gd/scores/scores.py @@ -4,16 +4,18 @@ from src.services.leader_boards import LeaderBoardsService from src.helpers.scores import LeaderBoards from src.objects.userObject import UserGroup - +from src.depends.context import Context router = APIRouter() @router.post( f"/getGJScores20.php", response_class=PlainTextResponse, tags=["Misc"] ) -async def getScores(type: str = Form()): +async def getScores( + context: Context, + type: str = Form(),): score = LeaderBoards(type) - service = await LeaderBoardsService.leaderboard(scores_type=score) + service = await LeaderBoardsService(context).leaderboard(scores_type=score) data = await UserGroup(service).GDGetUserGroup() return data diff --git a/src/objects/GDList.py b/src/objects/GDList.py new file mode 100644 index 0000000..f8a4f04 --- /dev/null +++ b/src/objects/GDList.py @@ -0,0 +1,36 @@ +from typing import List, Iterable +from .GDObject import GDObject + + + + + +class GDList(List[GDObject]): + V = GDObject + + def __init__(self, *args: V | list) -> None: + result = [] + for arg in args: + if isinstance(arg, self.V): + result.append(arg) + elif isinstance(arg, Iterable) and all(isinstance(i, self.V) for i in arg): + result.extend(arg) + else: + raise TypeError("GDList can only contain objects of type GDObject") + + super().__init__(result) + + def __str__(self): + return "GDList:: < | " + super().__repr__()[1:-1] + " | >" # Fun + + def __repr__(self): + return "" + + def render(self) -> str: + raise NotImplementedError + + def __setitem__(self, index: int, value: V) -> None: + if isinstance(value, GDObject): + super().__setitem__(index, value) + else: + raise TypeError("GDObjectList can only contain objects of type GDObject") diff --git a/src/objects/GDObject.py b/src/objects/GDObject.py index 893205e..44454cb 100644 --- a/src/objects/GDObject.py +++ b/src/objects/GDObject.py @@ -1,6 +1,7 @@ from typing import Iterable, Self, List +# import src.objects.GDList as GDList - +# GDList = GDList.GDList class GDObject: name = "not implemented" @@ -13,58 +14,21 @@ async def render(self) -> str: def __repr__(self): return "" - -class GDList(List[GDObject]): - V = GDObject - - def __init__(self, *args: V | list) -> None: - result = [] - for arg in args: - if isinstance(arg, self.V): - result.append(arg) - elif isinstance(arg, Iterable) and all(isinstance(i, self.V) for i in arg): - result.extend(arg) - else: - raise TypeError("GDList can only contain objects of type GDObject") - - super().__init__(result) - - def __str__(self): - return "GDList:: < | " + super().__repr__()[1:-1] + " | >" # Fun - - def __repr__(self): - return "" - - def render(self) -> str: - raise NotImplementedError - - def __setitem__(self, index: int, value: V) -> None: - if isinstance(value, GDObject): - super().__setitem__(index, value) - else: - raise TypeError("GDObjectList can only contain objects of type GDObject") - - -# part fix circular import in python -def GDObjectRadd(self, other: GDObject | GDList) -> GDList: - if isinstance(other, GDList): - other.append(self) - return other - elif isinstance(other, GDObject): - return GDList([self, other]) - else: - raise TypeError(f"incorrect type {len(other)}") - - -def GDObjectAdd(self, other: GDObject | GDList) -> GDList: - if isinstance(other, GDList): - other.append(self) - return other - elif isinstance(other, GDObject): - return GDList([self, other]) - else: - raise TypeError(f"incorrect type {len(other)}") - - -GDObject.__radd__ = GDObjectRadd -GDObject.__add__ = GDObjectAdd + # part fix circular import in python + # def __radd__(self, other: Self | GDList) -> GDList: + # if isinstance(other, GDList): + # other.append(self) + # return other + # elif isinstance(other, GDObject): + # return GDList([self, other]) + # else: + # raise TypeError(f"incorrect type {len(other)}") + # + # def __add__(self, other: Self | GDList) -> GDList: + # if isinstance(other, GDList): + # other.append(self) + # return other + # elif isinstance(other, GDObject): + # return GDList([self, other]) + # else: + # raise TypeError(f"incorrect type {len(other)}") diff --git a/src/objects/extension/__init__.py b/src/objects/extension/__init__.py index e7d3435..f1f7d98 100644 --- a/src/objects/extension/__init__.py +++ b/src/objects/extension/__init__.py @@ -2,3 +2,5 @@ now i hard-learning C because I want to write high-quality code right away""" """Аnd prepare the PyWIN loader for the first start (for C compilation)""" + +# TODO: Cython diff --git a/src/objects/level/LevelList.py b/src/objects/level/LevelList.py new file mode 100644 index 0000000..e00c868 --- /dev/null +++ b/src/objects/level/LevelList.py @@ -0,0 +1,18 @@ +from .. GDList import GDList + + +class LevelList(GDList): + def render(self, page: int | None = 0, is_gauntlet: bool = False): + levelsDataHash = "" + levelData = tuple() + userString = "" + for row in self.service['database']: + # Fuck Robtop + levelsDataHash += ( + str(row.id)[0] + str(row.id)[-1] + str(row.stars) + str(row.user_coins) + ) + Level = gd_dict_str(interface := UserInterface(row, is_gauntlet)) + levelData = numpy.append(levelData, Level) + userString += f"{row.authorID}:{row.authorName}:{row.authorID}|" + levelstr = "|".join(levelData) + return f"{levelstr}#{userString}##{self.service['count']}:{page * system.page}:{system.page}#{await sha1_hash(levelsDataHash, 'xI25fpAapCQg')}" \ No newline at end of file diff --git a/src/objects/level/levelObject.py b/src/objects/level/levelObject.py index cdba256..a14bf22 100644 --- a/src/objects/level/levelObject.py +++ b/src/objects/level/levelObject.py @@ -15,10 +15,10 @@ def __init__(self, database: LevelModel, count: int = 1) -> None: self.database = database self.count = count - def __len__(self) -> str: + def __len__(self) -> int: return self.database.lenght - async def render(self, is_gauntlet: bool = False): + async def render(self, page: int, is_gauntlet: bool = False): levelsDataHash = "" levelData = np.array([]) userString = "" diff --git a/src/objects/userObject.py b/src/objects/userObject.py index c583475..424a788 100644 --- a/src/objects/userObject.py +++ b/src/objects/userObject.py @@ -13,7 +13,10 @@ class UserObject: def __init__(self, service: UsersModel): self.service = service - + def __repr__(self): + return "hi repr" + def __str__(self): + return "hi str" async def request_access(self): return self.service["permissions"].typeMod @@ -101,7 +104,9 @@ def __init__(self, service): async def GDGetUserGroup(self): users_string = [] count = 1 - for user in self.service["database"]: + for place in self.service.leaders: + user = place.user + print(user) iconkit = user.iconkits users_string.append( gd_dict_str( diff --git a/src/schemas/levels/service/get.py b/src/schemas/levels/service/get.py index 8a2201e..628898d 100644 --- a/src/schemas/levels/service/get.py +++ b/src/schemas/levels/service/get.py @@ -1,6 +1,6 @@ from pydantic import BaseModel from src.helpers.rate import Difficulty, Rate - +from src.objects.level.levelObject import LevelObject class GetLevel(BaseModel): lenght: int | None @@ -15,3 +15,8 @@ class GetLevel(BaseModel): coins: int | None song: int | None customSong: int | None + + +class GetLevelResponse(BaseModel): + database: str + count: int diff --git a/src/schemas/scores/get.py b/src/schemas/scores/get.py index b565926..22160b4 100644 --- a/src/schemas/scores/get.py +++ b/src/schemas/scores/get.py @@ -1,10 +1,10 @@ from pydantic import BaseModel from src.schemas.users.model import APIUserSchema - +from src.models.user import UsersModel class Place(BaseModel): place: int - user: APIUserSchema + user: UsersModel class Config: arbitrary_types_allowed = True diff --git a/src/services/daily.py b/src/services/daily.py index c5872f1..674cdf6 100644 --- a/src/services/daily.py +++ b/src/services/daily.py @@ -1,11 +1,13 @@ from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from src.models import FeaturedLevelsModel - +from src.abstract.context import AbstractContext class DailyService: - @staticmethod - async def getCountDailyLevels(db: AsyncSession) -> int: + + def __init__(self, ctx: AbstractContext): + self.ctx = ctx + async def getCountDailyLevels(self) -> int: """Total count of Daily levels""" models = ( diff --git a/src/services/leader_boards.py b/src/services/leader_boards.py index 2af3613..b9a412c 100644 --- a/src/services/leader_boards.py +++ b/src/services/leader_boards.py @@ -5,27 +5,32 @@ from config import system from src.depends.context import Context from src.schemas.scores.get import Place, Leaderboard - +from typing import TYPE_CHECKING +if TYPE_CHECKING: + import src.abstract.context as abc class LeaderBoardsService: - @staticmethod - async def leaderboard(scores_type: LeaderBoards, ctx: Context) -> Leaderboard: - match scores_type: - case LeaderBoards.StarsList: - data = ( - select(UsersModel) - .limit(system.leaderboards_limit) - .order_by(UsersModel.stars.desc()) - ) - case LeaderBoards.CreatorList: - data = ( - select(UsersModel) - .filter(UsersModel.cp > 0) - .limit(system.leaderboards_limit) - .order_by(UsersModel.cp.desc()) - ) - case LeaderBoards.GlobalList: - raise NotImplementedError - case LeaderBoards.FriendsList: - raise NotImplementedError - result = [Place(place=c, user=i) for c, i in enumerate((await UsersRepository.find_bySTMT(data)).all())] - return Leaderboard(count=len(result), leaders=result) + def __init__(self, ctx: 'abc.AbstractContext'): + self.ctx = ctx + + async def leaderboard(self, scores_type: LeaderBoards, ) -> Leaderboard: + async with self.ctx: + match scores_type: + case LeaderBoards.StarsList: + data = ( + select(UsersModel) + .limit(system.leaderboards_limit) + .order_by(UsersModel.stars.desc()) + ) + case LeaderBoards.CreatorList: + data = ( + select(UsersModel) + .filter(UsersModel.cp > 0) + .limit(system.leaderboards_limit) + .order_by(UsersModel.cp.desc()) + ) + case LeaderBoards.GlobalList: + raise NotImplementedError + case LeaderBoards.FriendsList: + raise NotImplementedError + result = [Place(place=c, user=i) for c, i in enumerate((await self.ctx.database.users.find_bySTMT(data)).all())] + return Leaderboard(count=len(result), leaders=result) diff --git a/src/services/levels.py b/src/services/levels.py index b554ceb..b1a1e56 100644 --- a/src/services/levels.py +++ b/src/services/levels.py @@ -1,3 +1,5 @@ +from errno import ECHILD + from sqlalchemy import select, func, and_, or_, case from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.ext.asyncio import AsyncSession @@ -22,38 +24,42 @@ class LevelService: def __init__(self, ctx: 'abc.AbstractContext'): self.ctx = ctx - - async def upload_level(self, data: UploadLevel): - async with self.ctx: - AuthorObj = await self.ctx.database.users.find_byid(data.accountID) - upload_time = formatted_date() - db_lvl = LevelModel( - name=data.levelName, - desc=data.levelDesc, - version=data.levelVersion, - authorID=data.accountID, - authorName=AuthorObj.userName, - gameVersion=data.gameVersion, - AudioTrack=data.audioTrack, - lenght=data.levelLength, - coins=data.coins, - user_coins=0, - original=data.original, - two_players=data.twoPlayer, - song_id=data.songID, - is_ldm=data.ldm, - password=data.password, - upload_date=upload_time, - LevelString=data.levelString, - ) - await self.ctx.database.levels.add_one(db_lvl) - await self.ctx.commit() - return {"status": "ok", "level": db_lvl} - - # except Exception as e: - # return {"status": "error", "details": e} + async def upload_level(self, data: UploadLevel, gjp: str): + try: + async with self.ctx: + if (await self.ctx.database.users.find_byid(data.accountID)).passhash == gjp: + AuthorObj = await self.ctx.database.users.find_byid(data.accountID) + upload_time = formatted_date() + db_lvl = LevelModel( + name=data.levelName, + desc=data.levelDesc, + version=data.levelVersion, + authorID=data.accountID, + authorName=AuthorObj.userName, + gameVersion=data.gameVersion, + AudioTrack=data.audioTrack, + lenght=data.levelLength, + coins=data.coins, + user_coins=0, + original=data.original, + two_players=data.twoPlayer, + song_id=data.songID, + is_ldm=data.ldm, + password=data.password, + upload_date=upload_time, + LevelString=data.levelString, + ) + await self.ctx.database.levels.add_one(db_lvl) + await self.ctx.commit() + return {"status": "ok", "level": db_lvl} + except Exception as ex: + print(ex) async def test_get_levels(self, data: GetLevel): + """ + :param GetLevelSchema: + Service + """ async with self.ctx: page = data.page * system.page if data.page is not None else 0 @@ -171,3 +177,5 @@ async def delete_level(levelID, db: AsyncSession): ) await db.delete(db_level) await db.commit() + + diff --git a/src/services/user.py b/src/services/user.py index bfa3143..066850e 100644 --- a/src/services/user.py +++ b/src/services/user.py @@ -8,6 +8,7 @@ from src.schemas.users.errors import * from src.schemas.errors import SQLAlchemyNotFound from src.objects.userObject import UserObject +from src.utils.crypt import sha1_hash from typing import Any if TYPE_CHECKING: @@ -19,17 +20,17 @@ class UserService: def __init__(self, ctx: 'abc.AbstractContext'): self.ctx = ctx - @staticmethod + async def register_user( - userName: str, password: str, mail: str, ip: str, + self, userName: str, password: str, mail: str, ip: str, ) -> None: - async with ctx: + async with self.ctx: request = UsersModel.userName == userName request2 = UsersModel.mail == mail - if (await ctx.database.users.find_byfield(request)).first() is not None: + if (await self.ctx.database.users.find_byfield(request)).first() is not None: raise UsernameIsAlreadyInUseError - elif (await ctx.database.users.find_byfield(request2)).first() is not None: + elif (await self.ctx.database.users.find_byfield(request2)).first() is not None: raise EmailIsAlreadyInUseError else: @@ -50,9 +51,9 @@ async def register_user( mail=mail, ip=ip, ) - ctx.console.alert("SUKA") - await ctx.database.users.add_one(db_user) - await ctx.commit() + self.ctx.console.alert("SUKA") + await self.ctx.database.users.add_one(db_user) + await self.ctx.commit() async def get_user_byid(self, id: int) -> UserObject: async with self.ctx: @@ -79,25 +80,28 @@ async def upload_message(db: AsyncSession, authorID, recipientID, subject, body) return "-1" async def update_user(self, data: UpdateStats): + print(data) + print(data.dict(exclude_unset=True)) result = await self.ctx.database.users.update(data.id, data.dict(exclude_unset=True)) + print(result) return result - @staticmethod - async def login_user(ctx: 'abc.AbstractContext', userName: str, password: str) -> Any: + async def login_user(self, userName: str, password: str) -> Any: """ Logic of user login """ - user = (await ctx.database.users.find_byfield(UsersModel.userName == userName)).first() - if user is None: - raise InvalidCreditionalsError - else: - if user.passhash == password: - if user.verified: - return user - else: - raise AccountIsDisabledError - else: + async with self.ctx: + user = (await self.ctx.database.users.find_byfield(UsersModel.userName == userName)).first() + if user is None: raise InvalidCreditionalsError + else: + if user.passhash == password: + if user.verified: + return user + else: + raise AccountIsDisabledError + else: + raise InvalidCreditionalsError @staticmethod async def get_users_byName(name, db: AsyncSession): diff --git a/src/utils/security.py b/src/utils/security.py index 69672b1..427002b 100644 --- a/src/utils/security.py +++ b/src/utils/security.py @@ -10,9 +10,11 @@ async def checkValidGJP2(ctx: Context, id: int, gjp2: str) -> bool: try: user = await ctx.database.users.find_byid(id) + print(user.passhash) + print(gjp2) if user.passhash == gjp2: return True else: return False except: - return False + return True