mirror of
https://gitea.tendokyu.moe/Hay1tsme/artemis.git
synced 2026-10-10 02:38:12 +03:00
basic campaign support
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
from typing import List, Optional
|
||||
|
||||
import bcrypt
|
||||
from sqlalchemy import Column, Table
|
||||
from sqlalchemy import Column, Table, ForeignKey, UniqueConstraint
|
||||
from sqlalchemy.dialects.mysql import insert
|
||||
from sqlalchemy.engine import Row
|
||||
from sqlalchemy.sql import func, select
|
||||
from sqlalchemy.types import TIMESTAMP, Integer, String
|
||||
from sqlalchemy.sql import func, select, and_, or_
|
||||
from sqlalchemy.types import TIMESTAMP, Integer, String, BIGINT, INTEGER
|
||||
from datetime import datetime
|
||||
|
||||
from core.data.schema.base import BaseData, metadata
|
||||
from core.data.schema.base import BaseData, metadata, campaign, campaign_game
|
||||
|
||||
aime_user: Table = Table(
|
||||
"aime_user",
|
||||
@@ -23,6 +24,18 @@ aime_user: Table = Table(
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
campaign_progress: Table = Table(
|
||||
"campaign_progress",
|
||||
metadata,
|
||||
Column("id", BIGINT, nullable=False, primary_key=True, autoincrement=True),
|
||||
Column("user_id", Integer, ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False),
|
||||
Column("campaign_id", INTEGER, ForeignKey("campaign.id", ondelete="cascade", onupdate="cascade"), nullable=False),
|
||||
Column("is_participating", INTEGER, nullable=False, server_default="0"),
|
||||
Column("progress", INTEGER, nullable=False, server_default="0"),
|
||||
UniqueConstraint("campaign_id", "user_id", name="campaign_progress_uk"),
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
class UserData(BaseData):
|
||||
async def create_user(
|
||||
self,
|
||||
@@ -136,3 +149,81 @@ class UserData(BaseData):
|
||||
|
||||
result = await self.execute(sql)
|
||||
return result is not None
|
||||
|
||||
async def get_user_campaign_progress_by_campaign(self, user_id: int, campaign_id: int) -> Optional[Row]:
|
||||
result = await self.execute(campaign_progress
|
||||
.join(campaign, campaign_progress.c.campaign_id == campaign.c.id)
|
||||
.select(and_(campaign_progress.c.user_id == user_id, campaign_progress.c.campaign_id == campaign_id)))
|
||||
|
||||
if result is not None:
|
||||
return result.fetchone()
|
||||
|
||||
async def get_user_all_campaign_progress(self, user_id: int) -> Optional[List[Row]]:
|
||||
result = await self.execute(campaign_progress
|
||||
.join(campaign, campaign_progress.c.campaign_id == campaign.c.id)
|
||||
.select(campaign_progress.c.user_id == user_id))
|
||||
|
||||
if result is not None:
|
||||
return result.fetchall()
|
||||
|
||||
async def get_user_active_campaign_progress(self, user_id: int) -> Optional[List[Row]]:
|
||||
# distrib_end_date instead of end_date to give the games time to distribute the rewards
|
||||
result = await self.execute(campaign_progress
|
||||
.join(campaign, campaign_progress.c.campaign_id == campaign.c.id)
|
||||
.select(and_(campaign_progress.c.user_id == user_id, and_(
|
||||
or_(campaign.c.start_date >= datetime.now(), campaign.c.start_date == None),
|
||||
or_(campaign.c.distrib_end_date < datetime.now(), campaign.c.distrib_end_date == None),
|
||||
))))
|
||||
|
||||
if result is not None:
|
||||
return result.fetchall()
|
||||
|
||||
async def get_user_all_campaign_progress_by_game(self, user_id: int, game_id: str) -> Optional[List[Row]]:
|
||||
result = await self.execute(campaign_progress
|
||||
.join(campaign, campaign_progress.c.campaign_id == campaign.c.id)
|
||||
.join(campaign_game, campaign_progress.c.campaign_id == campaign_game.c.campaign_id)
|
||||
.select(and_(campaign_progress.c.user_id == user_id, campaign_game.c.game_id == game_id)))
|
||||
|
||||
if result is not None:
|
||||
return result.fetchall()
|
||||
|
||||
async def get_user_active_campaign_progress_by_game(self, user_id: int, game_id: str) -> Optional[List[Row]]:
|
||||
result = await self.execute(campaign_progress
|
||||
.join(campaign, campaign_progress.c.campaign_id == campaign.c.id)
|
||||
.join(campaign_game, campaign_progress.c.campaign_id == campaign_game.c.campaign_id)
|
||||
.select(and_(and_(campaign_progress.c.user_id == user_id, campaign_game.c.game_id == game_id), and_(
|
||||
or_(campaign.c.start_date >= datetime.now(), campaign.c.start_date == None),
|
||||
or_(campaign.c.distrib_end_date < datetime.now(), campaign.c.distrib_end_date == None),
|
||||
))))
|
||||
|
||||
if result is not None:
|
||||
return result.fetchall()
|
||||
|
||||
async def set_user_campaign_is_participating(self, user_id: int, campaign_id: int, is_participating: bool) -> Optional[bool]:
|
||||
sql = insert(campaign_progress).values(
|
||||
user_id = user_id,
|
||||
campaign_id = campaign_id,
|
||||
is_participating = is_participating
|
||||
)
|
||||
|
||||
conflict = sql.on_duplicate_key_update(is_participating = is_participating)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
self.logger.error(f"Failed to update campaign participation status for user {user_id} on campaign {campaign_id}!")
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
async def set_user_campaign_progress(self, user_id: int, campaign_id: int, progress: int) -> Optional[bool]:
|
||||
sql = insert(campaign_progress).values(
|
||||
user_id = user_id,
|
||||
campaign_id = campaign_id,
|
||||
is_participating = 1,
|
||||
progress = progress
|
||||
)
|
||||
|
||||
conflict = sql.on_duplicate_key_update(progress = progress)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
self.logger.error(f"Failed to update campaign progress for user {user_id} on campaign {campaign_id} to {progress}!")
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
Reference in New Issue
Block a user