Initial tansition to SQLAlchemy on the Game Table resource

This commit is contained in:
iamBadgers
2026-04-22 22:16:27 -07:00
parent a0bc0f0feb
commit b6cef4f3c1
9 changed files with 75 additions and 51 deletions

3
.gitignore vendored
View File

@@ -1,2 +1,3 @@
# Created by venv; see https://docs.python.org/3/library/venv.html i# Created by venv; see https://docs.python.org/3/library/venv.html
venv venv
__pycache__

View File

@@ -3,8 +3,10 @@ blinker==1.9.0
certifi==2026.2.25 certifi==2026.2.25
charset-normalizer==3.4.6 charset-normalizer==3.4.6
click==8.3.1 click==8.3.1
docker @ git+https://github.com/docker/docker-py@main docker @ git+https://github.com/docker/docker-py@df3f8e2abc5a03de482e37214dddef9e0cee1bb1
Flask==3.1.3 Flask==3.1.3
Flask-SQLAlchemy==3.1.1
greenlet==3.4.0
idna==3.11 idna==3.11
itsdangerous==2.2.0 itsdangerous==2.2.0
Jinja2==3.1.6 Jinja2==3.1.6
@@ -15,5 +17,7 @@ pathspec==1.0.4
platformdirs==4.9.4 platformdirs==4.9.4
pytokens==0.4.1 pytokens==0.4.1
requests==2.33.0 requests==2.33.0
SQLAlchemy==2.0.49
typing_extensions==4.15.0
urllib3==2.6.3 urllib3==2.6.3
Werkzeug==3.1.6 Werkzeug==3.1.6

View File

@@ -40,7 +40,7 @@ def delete_container(docker_id) -> bool:
container = client.containers.get(docker_id) container = client.containers.get(docker_id)
container.remove() container.remove()
return True return True
except docker.errors.NotFound, docker.errors.APIError: except (docker.errors.NotFound, docker.errors.APIError):
return False return False
@@ -50,7 +50,7 @@ def stop_container(docker_id) -> bool:
container = client.containers.get(docker_id) container = client.containers.get(docker_id)
container.kill() container.kill()
return True return True
except docker.errors.NotFound, docker.errors.APIError: except (docker.errors.NotFound, docker.errors.APIError):
return False return False
@@ -66,7 +66,7 @@ def start_foundry_container(table: GameTable, key: KeyTable):
if table.docker_id != None and table.docker_id != 0: if table.docker_id != None and table.docker_id != 0:
try: try:
container = client.containers.get(table.docker_id) container = client.containers.get(table.docker_id)
except docker.errors.NotFound, docker.errors.NullResource: except (docker.errors.NotFound, docker.errors.NullResource):
container = None container = None
if container: if container:

View File

@@ -33,11 +33,11 @@ CREATE TABLE IF NOT EXISTS "game_keys" (
""" """
_user_table_create = """ _user_table_create = """
CREATE TABLE IF NOT EXISTS "" ( CREATE TABLE IF NOT EXISTS "users" (
"id": INTEGER NOT NULL, "id" INTEGER NOT NULL,
"username": TEXT NOT NULL, "username" TEXT NOT NULL,
"hash": TEXT NOT NULL, "hash" TEXT NOT NULL,
PRIMARY KEY ("ID) PRIMARY KEY ("id")
); );
""" """
@@ -55,7 +55,7 @@ class SmartCursor:
curosr: Cursor curosr: Cursor
autoClose: bool autoClose: bool
def __init__(self, cursor: Cursor = None, connection: Connectoin = None): def __init__(self, cursor: Cursor = None, connection: Connection = None):
self.cursor = cursor self.cursor = cursor
self.connection = connection self.connection = connection
self.autoClose = False self.autoClose = False

25
src/game_table_model.py Normal file
View File

@@ -0,0 +1,25 @@
from main import db
class GameTable(db.Model):
__tablename__ = "game_tables"
game_table_id = db.Column(db.Integer, primary_key=True)
game_table_name = db.Column(db.String(30))
game_table_link = db.Column(db.String(30), unique=True)
active = db.Column(db.Boolean)
version = db.Column(db.Integer)
docker_id = db.Column(db.Integer)
def __repr__(self):
return f"<Game Table {self.game_table_name}>"
def to_dict(self):
return {
"table_id": self.game_table_id,
"table_name": self.game_table_name,
"table_link": self.game_table_link,
"active": self.active,
"version": self.version,
}

View File

@@ -4,7 +4,7 @@ from database import SmartCursor
class KeyTable: class KeyTable:
key: str key: str
game_table_id: number game_table_id: int
key_file: str key_file: str
created: bool created: bool
updated: bool updated: bool

View File

@@ -2,19 +2,27 @@ from flask import Flask, g, jsonify, request
import sqlite3 import sqlite3
import container_managment import container_managment
from database import SmartCursor, get_db, init_db from database import SmartCursor, get_db, init_db
import tables
import os import os
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app(): def create_app():
app = Flask(__name__) app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:////data/tables.db"
db.init_app(app)
@app.teardown_appcontext @app.teardown_appcontext
def close_connection(exception): def close_connection(exception):
db = getattr(g, "_database", None) db = getattr(g, "_database", None)
if db is not None: if db is not None:
db.close() db.close()
import tables
app.register_blueprint(tables.tables, url_prefix="/api") app.register_blueprint(tables.tables, url_prefix="/api")
with app.app_context(): with app.app_context():
@@ -24,4 +32,4 @@ def create_app():
if __name__ == "__main__": if __name__ == "__main__":
create_app.run(debug=True) create_app().run(debug=True)

View File

@@ -4,14 +4,15 @@ from key_tables import KeyService, KeyTable
import container_managment import container_managment
import random import random
from database import get_db, SmartCursor from database import get_db, SmartCursor
from game_table_model import GameTable
import game_table_model
from main import db as potato
tables = Blueprint("tables_api", __name__) tables = Blueprint("tables_api", __name__)
@tables.route("/tables", methods=["POST"]) @tables.route("/tables", methods=["POST"])
def create_table(): def create_table():
db = get_db()
with SmartCursor(connection=db) as smartCursor:
table = GameTable( table = GameTable(
game_table_id=0, game_table_id=0,
game_table_name=request.get_json()["table_name"], game_table_name=request.get_json()["table_name"],
@@ -20,47 +21,32 @@ def create_table():
active=False, active=False,
docker_id=None, docker_id=None,
) )
table.commit(smartCursor) potato.session.add(table)
db.commit() potato.session.commit()
return jsonify(table.toJson()), 200 return jsonify(table.to_dict())
@tables.route("/tables/<table_id>") @tables.route("/tables/<table_id>")
def get_table(table_id): def get_table(table_id):
gameService = GameService(get_db()) table = GameTable.query.get_or_404(table_id)
table = gameService.read_by_id(table_id) current_app.logger.info(table)
return jsonify(table.toJson()) return jsonify(table.to_dict())
@tables.route("/tables/<int:table_id>", methods=["POST"]) @tables.route("/tables/<int:table_id>", methods=["POST"])
def update_table(table_id): def update_table(table_id):
db = get_db() table = GameTable.query.get_or_404(table_id)
gameService = GameService(db)
table = gameService.read_by_id(table_id)
table.game_table_name = request.get_json()["table_name"] table.game_table_name = request.get_json()["table_name"]
table.game_table_link = request.get_json()["table_link"] table.game_table_link = request.get_json()["table_link"]
table.version = request.get_json()["version"] table.version = request.get_json()["version"]
with SmartCursor(connection=db) as smartCursor: potato.session.commit()
table.commit(smartCursor)
db.commit()
return table.toJson(), 200
@tables.route("tables/<table_id>", methods=["DELETE"]) @tables.route("tables/<table_id>", methods=["DELETE"])
def delete_table(table_id): def delete_table(table_id):
db = get_db() table = GameTable.query.get_or_404(table_id)
gameService = GameService(db) potato.session.delete(table)
table = gameService.read_by_id(table_id) potato.session.commit()
if table == None:
return jsonify({}), 404
container_managment.delete_container(table.docker_id)
table.delete()
with SmartCursor(connection=db) as smartCursor:
table.commit(smartCursor)
db.commit()
return jsonify({}), 200
@tables.route("/tables/active") @tables.route("/tables/active")

View File

@@ -59,7 +59,7 @@ class UserService:
return [] return []
def check_login(username: str, password: str): def check_login(username: str, password: str):
return; return
users = Blueprint("users_api", __name__) users = Blueprint("users_api", __name__)