backend: полная реструктуризация

This commit is contained in:
2022-11-20 19:36:42 +03:00
parent 8dc700fb7c
commit f8f570c533
14 changed files with 223 additions and 200 deletions

View File

@@ -1,14 +1,14 @@
import json
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_admin import Admin
from textsouls.models import db
app = Flask(
"__name__",
)
db = SQLAlchemy()
migrate = Migrate(app, db, compare_type=True)
admin = Admin(name="TextSouls")
@@ -25,10 +25,14 @@ app.config.update(db_settings)
admin.init_app(app)
db.init_app(app)
from .admin import ts_admin as ts_admin_blueprint
from textsouls.actions.api import bp
app.register_blueprint(ts_admin_blueprint)
app.register_blueprint(bp)
from .main import main as main_blueprint
from textsouls.characters.api import bp
app.register_blueprint(main_blueprint)
app.register_blueprint(bp)
from textsouls.users.api import bp
app.register_blueprint(bp)

View File

View File

@@ -0,0 +1,19 @@
from flask import Blueprint
from textsouls import db
from textsouls import admin
from textsouls.common.api import register_api
from textsouls.common.api import CommonAdminView
from textsouls.actions.models import DuelParticipant
from textsouls.actions.models import Duel
bp = Blueprint("actions", __name__)
register_api(bp, DuelParticipant, "duels_participant")
register_api(bp, Duel, "duels")
admin.add_view(CommonAdminView(DuelParticipant, db.session))
admin.add_view(CommonAdminView(Duel, db.session))

View File

@@ -0,0 +1,108 @@
import datetime
from random import randint
from sqlalchemy.orm import backref
from sqlalchemy_serializer import SerializerMixin
from textsouls import db
from textsouls.characters.models import Character
class DuelParticipant(db.Model, SerializerMixin):
__tablename__ = "duels_participants"
id = db.Column(db.Integer, primary_key=True)
participant_id = db.Column(
db.Integer,
db.ForeignKey("characters.id", ondelete="CASCADE"),
)
turn_order = db.Column(db.Integer, nullable=False)
duel_id = db.Column(
db.Integer,
db.ForeignKey("duels.id", ondelete="CASCADE"),
)
def __str__(self):
return f"{self.duel_id}: {self.participant_id}"
class Duel(db.Model, SerializerMixin):
__tablename__ = "duels"
id = db.Column(db.Integer, primary_key=True)
created_on = db.Column(
db.DateTime, nullable=False, default=datetime.datetime.now()
)
participants = db.relationship(
"DuelParticipant",
backref=backref("duel", order_by="DuelParticipant.turn_order.asc()"),
lazy="dynamic",
)
def attack(self, attacked_character, defensive_character):
defensive_character_endurance = (
defensive_character.endurance_base
- attacked_character.battle_stats["attack_power"]
)
return defensive_character_endurance
def defence(self, defensive_character):
procced = False
if (
randint(
int(10 * defensive_character.battle_stats["defence_chance"]),
50,
)
== 50
):
procced is True
return procced
def dodge(self, defensive_character):
procced = False
if (
randint(
int(10 * defensive_character.battle_stats["dodge_chance"]), 50
)
== 50
):
procced is True
return procced
def duel_one_to_one(self):
character_first = Character.query.get(
self.participants[0].participant_id
)
character_second = Character.query.get(
self.participants[1].participant_id
)
while (
character_first.endurance_base > 0
and character_second.endurance_base > 0
):
if not self.defence(character_second) or not self.dodge(
character_second
):
character_second.endurance_base = self.attack(
character_first, character_second
)
if not self.defence(character_first) or not self.dodge(
character_first
):
character_first.endurance_base = self.attack(
character_second, character_first
)
if character_first.endurance_base > 0:
return character_first.name
elif character_second.endurance_base > 0:
return character_second.name
else:
return "Ничья"

View File

@@ -1,41 +0,0 @@
from flask import Blueprint
from flask_admin.contrib.sqla import ModelView
from . import admin
from textsouls.models import db
from textsouls.models import User
from textsouls.models import CharacterRace
from textsouls.models import CharacterClass
from textsouls.models import CharacterState
from textsouls.models import Character
from textsouls.models import DuelParticipant
from textsouls.models import Duel
ts_admin = Blueprint("ts_admin", __name__)
class AdminView(ModelView):
def __init__(self, model, *args, **kwargs):
self.column_list = [c.key for c in model.__table__.columns]
self.form_columns = self.column_list
super(AdminView, self).__init__(model, *args, **kwargs)
class CommonView(ModelView):
def __init__(self, model, *args, **kwargs):
self.column_list = [c.key for c in model.__table__.columns]
super(CommonView, self).__init__(model, *args, **kwargs)
admin.add_view(AdminView(User, db.session))
admin.add_view(CommonView(CharacterRace, db.session))
admin.add_view(CommonView(CharacterClass, db.session))
admin.add_view(CommonView(CharacterState, db.session))
admin.add_view(CommonView(Character, db.session))
admin.add_view(CommonView(DuelParticipant, db.session))
admin.add_view(CommonView(Duel, db.session))

View File

View File

@@ -0,0 +1,25 @@
from flask import Blueprint
from textsouls import db
from textsouls import admin
from textsouls.common.api import register_api
from textsouls.common.api import CommonAdminView
from textsouls.characters.models import CharacterRace
from textsouls.characters.models import CharacterClass
from textsouls.characters.models import CharacterState
from textsouls.characters.models import Character
bp = Blueprint("characters", __name__)
register_api(bp, CharacterRace, "character_races")
register_api(bp, CharacterClass, "character_classes")
register_api(bp, CharacterState, "character_states")
register_api(bp, Character, "characters", "owner")
admin.add_view(CommonAdminView(CharacterRace, db.session))
admin.add_view(CommonAdminView(CharacterClass, db.session))
admin.add_view(CommonAdminView(CharacterState, db.session))
admin.add_view(CommonAdminView(Character, db.session))

View File

@@ -1,34 +1,8 @@
import datetime
from random import randint
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import backref
from sqlalchemy_serializer import SerializerMixin
db = SQLAlchemy()
class User(db.Model, SerializerMixin):
__tablename__ = "users"
serialize_rules = ("-character",)
id = db.Column(db.BigInteger, primary_key=True, autoincrement=False)
chat_id = db.Column(db.BigInteger, nullable=False, unique=True)
first_name = db.Column(db.String(255), nullable=True)
last_name = db.Column(db.String(255), nullable=True)
username = db.Column(db.String(255), nullable=False)
registered_on = db.Column(
db.DateTime, nullable=False, default=datetime.datetime.now()
)
is_admin = db.Column(db.Boolean, nullable=False, default=False)
characters = db.relationship("Character", backref="user", lazy="dynamic")
def __str__(self):
return f"{self.id}: {self.username}"
from textsouls import db
class CharacterRace(db.Model, SerializerMixin):
@@ -174,102 +148,3 @@ class Character(db.Model, SerializerMixin):
"defence_chance": defence_chance,
"dodge_chance": dodge_chance,
}
class DuelParticipant(db.Model, SerializerMixin):
__tablename__ = "duels_participants"
id = db.Column(db.Integer, primary_key=True)
participant_id = db.Column(
db.Integer,
db.ForeignKey("characters.id", ondelete="CASCADE"),
)
turn_order = db.Column(db.Integer, nullable=False)
duel_id = db.Column(
db.Integer,
db.ForeignKey("duels.id", ondelete="CASCADE"),
)
def __str__(self):
return f"{self.duel_id}: {self.participant_id}"
class Duel(db.Model, SerializerMixin):
__tablename__ = "duels"
id = db.Column(db.Integer, primary_key=True)
created_on = db.Column(
db.DateTime, nullable=False, default=datetime.datetime.now()
)
participants = db.relationship(
"DuelParticipant",
backref=backref("duel", order_by="DuelParticipant.turn_order.asc()"),
lazy="dynamic",
)
def attack(self, attacked_character, defensive_character):
defensive_character_endurance = (
defensive_character.endurance_base
- attacked_character.battle_stats["attack_power"]
)
return defensive_character_endurance
def defence(self, defensive_character):
procced = False
if (
randint(
int(10 * defensive_character.battle_stats["defence_chance"]),
50,
)
== 50
):
procced is True
return procced
def dodge(self, defensive_character):
procced = False
if (
randint(
int(10 * defensive_character.battle_stats["dodge_chance"]), 50
)
== 50
):
procced is True
return procced
def duel_one_to_one(self):
character_first = Character.query.get(
self.participants[0].participant_id
)
character_second = Character.query.get(
self.participants[1].participant_id
)
while (
character_first.endurance_base > 0
and character_second.endurance_base > 0
):
if not self.defence(character_second) or not self.dodge(
character_second
):
character_second.endurance_base = self.attack(
character_first, character_second
)
if not self.defence(character_first) or not self.dodge(
character_first
):
character_first.endurance_base = self.attack(
character_second, character_first
)
if character_first.endurance_base > 0:
return character_first.name
elif character_second.endurance_base > 0:
return character_second.name
else:
return "Ничья"

View File

View File

@@ -1,8 +1,16 @@
from .. import db
from flask import request
from flask.views import MethodView
from flask_admin.contrib.sqla import ModelView
from textsouls import db
class CommonAdminView(ModelView):
def __init__(self, model, *args, **kwargs):
self.column_list = [c.key for c in model.__table__.columns]
super(CommonAdminView, self).__init__(model, *args, **kwargs)
class ItemAPI(MethodView):
init_every_request = False

View File

@@ -1,25 +0,0 @@
from flask import Blueprint
from textsouls.common.views import register_api
from textsouls.models import User
from textsouls.models import CharacterRace
from textsouls.models import CharacterClass
from textsouls.models import CharacterState
from textsouls.models import Character
from textsouls.models import DuelParticipant
from textsouls.models import Duel
main = Blueprint("main", __name__)
register_api(main, User, "users")
register_api(main, CharacterRace, "character_races")
register_api(main, CharacterClass, "character_classes")
register_api(main, CharacterState, "character_states")
register_api(main, Character, "characters", "owner")
register_api(main, DuelParticipant, "duels_participant")
register_api(main, Duel, "duels")

View File

View File

@@ -0,0 +1,24 @@
from flask import Blueprint
from flask_admin.contrib.sqla import ModelView
from textsouls import db
from textsouls import admin
from textsouls.common.api import register_api
from textsouls.users.models import User
class UserAdminView(ModelView):
def __init__(self, model, *args, **kwargs):
self.column_list = [c.key for c in model.__table__.columns]
self.form_columns = self.column_list
super(UserAdminView, self).__init__(model, *args, **kwargs)
bp = Blueprint("users", __name__)
register_api(bp, User, "users")
admin.add_view(UserAdminView(User, db.session))

View File

@@ -0,0 +1,26 @@
import datetime
from sqlalchemy_serializer import SerializerMixin
from textsouls import db
class User(db.Model, SerializerMixin):
__tablename__ = "users"
serialize_rules = ("-character",)
id = db.Column(db.BigInteger, primary_key=True, autoincrement=False)
chat_id = db.Column(db.BigInteger, nullable=False, unique=True)
first_name = db.Column(db.String(255), nullable=True)
last_name = db.Column(db.String(255), nullable=True)
username = db.Column(db.String(255), nullable=False)
registered_on = db.Column(
db.DateTime, nullable=False, default=datetime.datetime.now()
)
is_admin = db.Column(db.Boolean, nullable=False, default=False)
characters = db.relationship("Character", backref="user", lazy="dynamic")
def __str__(self):
return f"{self.id}: {self.username}"