built routes for creation of char
This commit is contained in:
@@ -1,8 +1,15 @@
|
||||
from flask import Blueprint, g, jsonify, current_app
|
||||
from flask import Blueprint, g, request, jsonify, current_app
|
||||
from typing import cast
|
||||
from app.utils.typed_flask import CoCFlask
|
||||
from dataclasses import asdict
|
||||
|
||||
# from app.services.appwrite_client import AppWriteClient
|
||||
from app.utils.typed_flask import CoCFlask
|
||||
from app.utils.session_user import SessionUser, import_g_session
|
||||
from app.game.generators.entity_factory import build_char
|
||||
from app.services.appwrite_db import AppwriteTables
|
||||
|
||||
from app.utils.logging import get_logger
|
||||
|
||||
logging = get_logger(__file__)
|
||||
|
||||
# type cast flask to my custom flask app so the app.api methods are available in the IDE / typed correctly.
|
||||
app = cast(CoCFlask,current_app)
|
||||
@@ -10,8 +17,36 @@ app = cast(CoCFlask,current_app)
|
||||
# blueprint def
|
||||
char_bp = Blueprint("char", __name__, url_prefix="/char")
|
||||
|
||||
# return CURRENT USER
|
||||
# {"user":g.appwrite_user}
|
||||
|
||||
@char_bp.route("/", methods=["GET", "POST"])
|
||||
def char():
|
||||
return app.api.ok({"user":g.appwrite_user})
|
||||
@char_bp.route("/new", methods=["POST"])
|
||||
def new():
|
||||
api_user = import_g_session(g.appwrite_user)
|
||||
|
||||
data = request.get_json(silent=True)
|
||||
|
||||
name = data.get("name")
|
||||
origin_story = data.get("origin_story")
|
||||
race_id = data.get("race_id")
|
||||
profession_id = data.get("profession_id")
|
||||
|
||||
try:
|
||||
player = build_char(name=name,origin_story=origin_story,race_id=race_id,profession_id=profession_id)
|
||||
player_dict = asdict(player)
|
||||
uuid = player.uuid
|
||||
|
||||
tablesdb = AppwriteTables()
|
||||
tablesdb.save_character_for_user_id(api_user.id,player_dict)
|
||||
|
||||
|
||||
logging.info(f"Created char {uuid} for {api_user.id} - {api_user.name} - {api_user.email}")
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Unable to create char for user: {api_user.id} due to {e}")
|
||||
player_dict = {}
|
||||
|
||||
uuid = player_dict.get("uuid",{})
|
||||
print(f"Returned {uuid}")
|
||||
return app.api.ok(uuid)
|
||||
|
||||
@@ -51,6 +51,9 @@ PATH_THEMES = _load_path_themes(themes_filename)
|
||||
|
||||
# ----------------- Generator -----------------
|
||||
def generate_abilities_direct_damage(class_name: str,path: str,level: int, primary_stat:str , per_tier: int = 2,content_version: int = 1) -> List[Ability]:
|
||||
if path not in PATH_THEMES:
|
||||
return []
|
||||
|
||||
theme = PATH_THEMES[path]
|
||||
rng = random.Random(_stable_seed(class_name, path, level, per_tier, version=content_version))
|
||||
spells: List[Ability] = []
|
||||
|
||||
@@ -13,24 +13,25 @@ dice = Dice()
|
||||
|
||||
progression = DEFAULT_LEVEL_PROGRESSION
|
||||
|
||||
def build_char(name:str, origin_story:str, race_id:str, profession_id:str,ability_pathway:str,level:int=1) -> Entity:
|
||||
def build_char(name:str, origin_story:str, race_id:str, profession_id:str,ability_pathway:str="",level:int=1) -> Entity:
|
||||
|
||||
races = RaceRepository()
|
||||
professions = ProfessionRepository()
|
||||
|
||||
race = races.get(race_id)
|
||||
profession = professions.get(profession_id)
|
||||
profession.ability_paths
|
||||
|
||||
e = Entity(
|
||||
uuid = str(uuid.uuid4()),
|
||||
name = name,
|
||||
origin_story = origin_story,
|
||||
race =race,
|
||||
ability_pathway=ability_pathway,
|
||||
profession = profession
|
||||
)
|
||||
|
||||
if ability_pathway != "":
|
||||
e.ability_pathway=ability_pathway
|
||||
|
||||
# apply race ability scores
|
||||
for stat, delta in vars(race.ability_scores).items():
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ def set_level(entity:Entity, target_level: int, prog: LevelProgression) -> None:
|
||||
|
||||
# entity get's a random number of spells based on the number of levels gained
|
||||
skills_per_level = calculate_skills_gained(current,target_level)
|
||||
|
||||
|
||||
skills = newly_unlocked_abilities(class_name=entity.profession.name,
|
||||
path=entity.ability_pathway,
|
||||
level=target_level,
|
||||
|
||||
102
app/services/appwrite_db.py
Normal file
102
app/services/appwrite_db.py
Normal file
@@ -0,0 +1,102 @@
|
||||
from __future__ import annotations
|
||||
import os
|
||||
from dataclasses import dataclass, asdict
|
||||
from enum import StrEnum
|
||||
from typing import Final, Optional
|
||||
from flask import current_app
|
||||
|
||||
from appwrite.client import Client
|
||||
from appwrite.services.tables_db import TablesDB
|
||||
from appwrite.query import Query
|
||||
from appwrite.id import ID
|
||||
|
||||
from app.game.models.entities import Entity
|
||||
|
||||
from app.utils.logging import get_logger
|
||||
from app.utils.settings import get_settings, Environment
|
||||
|
||||
settings = get_settings()
|
||||
logger = get_logger(__file__)
|
||||
|
||||
|
||||
class Env(StrEnum):
|
||||
PROD = "prod"
|
||||
DEV = "dev"
|
||||
|
||||
# --- Database schemas (strongly-typed namespaces) ----------------------------
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Database:
|
||||
"""Schema for a single database: each attribute is a table name (or ID)."""
|
||||
id: str
|
||||
characters: str
|
||||
inventory: str
|
||||
# add more tables here as you grow your schema
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Databases:
|
||||
"""Top-level namespace exposing prod/dev as attributes."""
|
||||
prod: Database
|
||||
dev: Database
|
||||
|
||||
DB: Final[Databases] = Databases(
|
||||
prod=Database(
|
||||
id="SETME", # actual DB / ID
|
||||
characters="SETME", # actual table / ID
|
||||
inventory="inventory",
|
||||
),
|
||||
dev=Database(
|
||||
id="69041f9600177b675485",
|
||||
characters="69050f830024afb0d253",
|
||||
inventory="inventory",
|
||||
),
|
||||
)
|
||||
|
||||
class AppwriteTables:
|
||||
|
||||
def __init__(self):
|
||||
print()
|
||||
self.client = (Client()
|
||||
.set_endpoint(settings.appwrite_endpoint)
|
||||
.set_project(settings.appwrite_project_id)
|
||||
.set_key(settings.appwrite_api_key)
|
||||
)
|
||||
self.tables_db = TablesDB(self.client)
|
||||
self.env = Env.DEV
|
||||
if settings.env == Environment.PROD:
|
||||
self.env = Env.PROD
|
||||
|
||||
@property
|
||||
def db(self) -> Database:
|
||||
# Gives autocompletion for .character, .users, etc.
|
||||
return DB.prod if self.env is Env.PROD else DB.dev
|
||||
|
||||
def get_characters_for_user_id(self, user_id: str) -> Optional[dict]:
|
||||
|
||||
try:
|
||||
result = self.tables_db.list_rows(
|
||||
self.db.id,
|
||||
self.db.characters,
|
||||
[
|
||||
Query.equal('player_id', [str(user_id)]),
|
||||
]
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Unable to list rows for char. User id: {user_id}")
|
||||
return {}
|
||||
|
||||
return result.get("rows",{})
|
||||
|
||||
def save_character_for_user_id(self, user_id:str, player_dict:dict):
|
||||
result = self.tables_db.create_row(
|
||||
database_id = self.db.id,
|
||||
table_id = self.db.characters,
|
||||
row_id = ID.unique(),
|
||||
data = {
|
||||
"player_id": str(user_id),
|
||||
"char_data": str(player_dict),
|
||||
},
|
||||
)
|
||||
print(result)
|
||||
return result
|
||||
|
||||
37
app/utils/session_user.py
Normal file
37
app/utils/session_user.py
Normal file
@@ -0,0 +1,37 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import Optional, cast
|
||||
|
||||
|
||||
@dataclass
|
||||
class SessionUser:
|
||||
id: str = ""
|
||||
registered_on: str = ""
|
||||
name: str = ""
|
||||
email: str = ""
|
||||
email_verified: bool = False
|
||||
phone: str = ""
|
||||
phone_verified: bool = False
|
||||
mfa: bool = False
|
||||
|
||||
|
||||
@property
|
||||
def is_authenticated(self) -> bool:
|
||||
return True
|
||||
|
||||
@property
|
||||
def email_verification(self) -> bool:
|
||||
return self.email_verified
|
||||
|
||||
@property
|
||||
def phone_verification(self) -> bool:
|
||||
return self.phone_verification
|
||||
|
||||
def import_g_session(g_session:dict) -> SessionUser:
|
||||
u = SessionUser(
|
||||
id=g_session.get("$id"),
|
||||
name=g_session.get("name"),
|
||||
registered_on=g_session.get("registration"),
|
||||
email=g_session.get("email"),
|
||||
email_verified=g_session.get("emailVerification")
|
||||
)
|
||||
return u
|
||||
Reference in New Issue
Block a user