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 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.
|
# 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)
|
app = cast(CoCFlask,current_app)
|
||||||
@@ -10,8 +17,36 @@ app = cast(CoCFlask,current_app)
|
|||||||
# blueprint def
|
# blueprint def
|
||||||
char_bp = Blueprint("char", __name__, url_prefix="/char")
|
char_bp = Blueprint("char", __name__, url_prefix="/char")
|
||||||
|
|
||||||
|
# return CURRENT USER
|
||||||
|
# {"user":g.appwrite_user}
|
||||||
|
|
||||||
@char_bp.route("/", methods=["GET", "POST"])
|
@char_bp.route("/new", methods=["POST"])
|
||||||
def char():
|
def new():
|
||||||
return app.api.ok({"user":g.appwrite_user})
|
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 -----------------
|
# ----------------- 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]:
|
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]
|
theme = PATH_THEMES[path]
|
||||||
rng = random.Random(_stable_seed(class_name, path, level, per_tier, version=content_version))
|
rng = random.Random(_stable_seed(class_name, path, level, per_tier, version=content_version))
|
||||||
spells: List[Ability] = []
|
spells: List[Ability] = []
|
||||||
|
|||||||
@@ -13,24 +13,25 @@ dice = Dice()
|
|||||||
|
|
||||||
progression = DEFAULT_LEVEL_PROGRESSION
|
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()
|
races = RaceRepository()
|
||||||
professions = ProfessionRepository()
|
professions = ProfessionRepository()
|
||||||
|
|
||||||
race = races.get(race_id)
|
race = races.get(race_id)
|
||||||
profession = professions.get(profession_id)
|
profession = professions.get(profession_id)
|
||||||
profession.ability_paths
|
|
||||||
|
|
||||||
e = Entity(
|
e = Entity(
|
||||||
uuid = str(uuid.uuid4()),
|
uuid = str(uuid.uuid4()),
|
||||||
name = name,
|
name = name,
|
||||||
origin_story = origin_story,
|
origin_story = origin_story,
|
||||||
race =race,
|
race =race,
|
||||||
ability_pathway=ability_pathway,
|
|
||||||
profession = profession
|
profession = profession
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if ability_pathway != "":
|
||||||
|
e.ability_pathway=ability_pathway
|
||||||
|
|
||||||
# apply race ability scores
|
# apply race ability scores
|
||||||
for stat, delta in vars(race.ability_scores).items():
|
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
|
# 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_per_level = calculate_skills_gained(current,target_level)
|
||||||
|
|
||||||
skills = newly_unlocked_abilities(class_name=entity.profession.name,
|
skills = newly_unlocked_abilities(class_name=entity.profession.name,
|
||||||
path=entity.ability_pathway,
|
path=entity.ability_pathway,
|
||||||
level=target_level,
|
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