artemis/core/data/schema/card.py

67 lines
2.4 KiB
Python
Raw Normal View History

from typing import Dict, List, Optional
from sqlalchemy import Table, Column, UniqueConstraint
from sqlalchemy.types import Integer, String, Boolean, TIMESTAMP
from sqlalchemy.sql.schema import ForeignKey
from sqlalchemy.sql import func
from core.data.schema.base import BaseData, metadata
aime_card = Table(
'aime_card',
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False),
Column("access_code", String(20)),
Column("created_date", TIMESTAMP, server_default=func.now()),
Column("last_login_date", TIMESTAMP, onupdate=func.now()),
Column("is_locked", Boolean, server_default="0"),
Column("is_banned", Boolean, server_default="0"),
UniqueConstraint("user", "access_code", name="aime_card_uk"),
mysql_charset='utf8mb4'
)
class CardData(BaseData):
def get_user_id_from_card(self, access_code: str) -> Optional[int]:
"""
Given a 20 digit access code as a string, get the user id associated with that card
"""
sql = aime_card.select(aime_card.c.access_code == access_code)
result = self.execute(sql)
if result is None: return None
card = result.fetchone()
if card is None: return None
return int(card["user"])
def get_user_cards(self, aime_id: int) -> Optional[List[Dict]]:
"""
Returns all cards owned by a user
"""
sql = aime_card.select(aime_card.c.user == aime_id)
result = self.execute(sql)
if result is None: return None
return result.fetchall()
def create_card(self, user_id: int, access_code: str) -> Optional[int]:
"""
Given a aime_user id and a 20 digit access code as a string, create a card and return the ID if successful
"""
sql = aime_card.insert().values(user=user_id, access_code=access_code)
result = self.execute(sql)
if result is None: return None
return result.lastrowid
def to_access_code(self, luid: str) -> str:
"""
Given a felica cards internal 16 hex character luid, convert it to a 0-padded 20 digit access code as a string
"""
return f"{int(luid, base=16):0{20}}"
def to_idm(self, access_code: str) -> str:
"""
Given a 20 digit access code as a string, return the 16 hex character luid
"""
return f'{int(access_code):0{16}x}'