diff --git a/backend/migrations/versions/226bb7e77b6b_.py b/backend/migrations/versions/8f02337dbef0_.py similarity index 75% rename from backend/migrations/versions/226bb7e77b6b_.py rename to backend/migrations/versions/8f02337dbef0_.py index 4a957ae..5907236 100644 --- a/backend/migrations/versions/226bb7e77b6b_.py +++ b/backend/migrations/versions/8f02337dbef0_.py @@ -1,8 +1,8 @@ """empty message -Revision ID: 226bb7e77b6b +Revision ID: 8f02337dbef0 Revises: -Create Date: 2022-11-17 22:55:34.747233 +Create Date: 2022-11-18 17:37:55.798611 """ from alembic import op @@ -10,7 +10,7 @@ import sqlalchemy as sa # revision identifiers, used by Alembic. -revision = '226bb7e77b6b' +revision = '8f02337dbef0' down_revision = None branch_labels = None depends_on = None @@ -19,15 +19,13 @@ depends_on = None def upgrade(): # ### commands auto generated by Alembic - please adjust! ### op.create_table('users', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('tg_id', sa.Integer(), nullable=False), + sa.Column('id', sa.Integer(), autoincrement=False, nullable=False), sa.Column('first_name', sa.String(length=255), nullable=True), sa.Column('last_name', sa.String(length=255), nullable=True), sa.Column('username', sa.String(length=255), nullable=False), sa.Column('registered_on', sa.DateTime(), nullable=False), sa.Column('is_admin', sa.Boolean(), nullable=False), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('tg_id') + sa.PrimaryKeyConstraint('id') ) # ### end Alembic commands ### diff --git a/backend/requirements.txt b/backend/requirements.txt index 4567e1a..5cbdf29 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -16,6 +16,7 @@ MarkupSafe==2.1.1 pycparser==2.21 PyMySQL==1.0.2 SQLAlchemy==1.4.44 +SQLAlchemy-serializer==1.4.1 Werkzeug==2.2.2 WTForms==3.0.1 zipp==3.10.0 diff --git a/backend/textsouls/__init__.py b/backend/textsouls/__init__.py index 43be2ba..88da6cc 100644 --- a/backend/textsouls/__init__.py +++ b/backend/textsouls/__init__.py @@ -16,10 +16,10 @@ admin = Admin(name="TextSouls") with open("textsouls/config.json") as config_file: config_data = json.load(config_file) -main_settings = config_data["main_settings"] +main_settings = config_data["MAIN_SETTINGS"] app.config.update(main_settings) -db_settings = config_data["db_settings"] +db_settings = config_data["DB_SETTINGS"] app.config.update(db_settings) admin.init_app(app) diff --git a/backend/textsouls/admin.py b/backend/textsouls/admin.py index 7be565b..688176c 100644 --- a/backend/textsouls/admin.py +++ b/backend/textsouls/admin.py @@ -7,4 +7,12 @@ from textsouls.models import User ts_admin = Blueprint("ts_admin", __name__) -admin.add_view(ModelView(User, db.session)) + +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) + + +admin.add_view(AdminView(User, db.session)) diff --git a/backend/textsouls/config.json_template b/backend/textsouls/config.json_template index d92fefe..42dfd50 100644 --- a/backend/textsouls/config.json_template +++ b/backend/textsouls/config.json_template @@ -1,9 +1,9 @@ { - "main_settings": { + "MAIN_SETTINGS": { "SECRET_KEY": "some-very-secret-key", "SQLALCHEMY_TRACK_MODIFICATIONS": false }, - "db_settings": { + "DB_SETTINGS": { "SQLALCHEMY_DATABASE_URI": "mysql+pymysql://ownername:pass@localhost/textsouls" } } \ No newline at end of file diff --git a/backend/textsouls/main.py b/backend/textsouls/main.py index 3c514a3..83dd8c3 100644 --- a/backend/textsouls/main.py +++ b/backend/textsouls/main.py @@ -1,5 +1,7 @@ from flask import Blueprint from flask import request +from flask import jsonify +from flask.views import MethodView from . import db from textsouls.models import User @@ -7,34 +9,67 @@ from textsouls.models import User main = Blueprint("main", __name__) -@main.route("/") -def index(): - return "Nice!", 200 +class ItemAPI(MethodView): + init_every_request = False + def __init__(self, model): + self.model = model -@main.route("/registration", methods=["POST"]) -def registration(): - data = request.get_json() + def _get_item(self, id): + return self.model.query.get_or_404(id) - tg_id = data.get("tg_id") - first_name = data.get("first_name") - last_name = data.get("last_name") - username = data.get("username") + def get(self, id): + item = self._get_item(id) + return item.to_dict() - existed_user = User.query.filter_by(tg_id=tg_id).first() + def patch(self, id): + item = self._get_item(id) + errors = self.validator.validate(item, request.json) - if not existed_user: - new_user = User( - tg_id=tg_id, - first_name=first_name, - last_name=last_name, - username=username, - ) + if errors: + return jsonify(errors), 400 - db.session.add(new_user) + item.update_from_json(request.json) db.session.commit() + return item.to_dict() - return {"created": True, "id": new_user.id} + def delete(self, id): + item = self._get_item(id) + db.session.delete(item) + db.session.commit() + return "", 200 - else: - return {"created": False, "id": existed_user.id} + +class ListAPI(MethodView): + init_every_request = False + + def __init__(self, model): + self.model = model + + def _get_item(self, id): + return self.model.query.filter_by(id=id).first() + + def get(self): + items = self.model.query.all() + return jsonify([item.to_dict() for item in items]) + + def post(self): + + item = self._get_item(request.json["id"]) + + if item: + return "Already exists!", 400 + + db.session.add(self.model(**request.json)) + db.session.commit() + return "", 200 + + +def register_api(app, model, name): + item = ItemAPI.as_view(f"{name}-item", model) + group = ListAPI.as_view(f"{name}-list", model) + app.add_url_rule(f"/{name}/", view_func=item) + app.add_url_rule(f"/{name}/", view_func=group) + + +register_api(main, User, "users") diff --git a/backend/textsouls/models.py b/backend/textsouls/models.py index 84b1caa..588e98d 100644 --- a/backend/textsouls/models.py +++ b/backend/textsouls/models.py @@ -1,16 +1,17 @@ import datetime from flask_sqlalchemy import SQLAlchemy +from sqlalchemy_serializer import SerializerMixin + db = SQLAlchemy() -class User(db.Model): +class User(db.Model, SerializerMixin): __tablename__ = "users" - id = db.Column(db.Integer, primary_key=True) - tg_id = db.Column(db.Integer, unique=True, nullable=False) + id = db.Column(db.Integer, primary_key=True, autoincrement=False) 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) diff --git a/telegram/textsouls/common.py b/telegram/textsouls/common.py index 1ca4f5a..719ef6a 100644 --- a/telegram/textsouls/common.py +++ b/telegram/textsouls/common.py @@ -6,7 +6,7 @@ with open("textsouls/config.json") as config_file: class Backend: - base_url = config_data["backend_settings"]["base_url"] + base_url = config_data["BACKEND_SETTINGS"]["BASE_URL"] def post(self, relative_url, data): try: diff --git a/telegram/textsouls/config.json_template b/telegram/textsouls/config.json_template index d97d24e..e3bdb5b 100644 --- a/telegram/textsouls/config.json_template +++ b/telegram/textsouls/config.json_template @@ -1,8 +1,8 @@ { - "main_settings": { - "bot_token": "token-from-@BotFather" + "MAIN_SETTINGS": { + "BOT_TOKEN": "token-from-@BotFather" }, - "backend_settings": { - "base_url": "http://localhost:5000" + "BACKEND_SETTINGS": { + "BASE_URL": "http://localhost:5000" } } \ No newline at end of file diff --git a/telegram/textsouls/main.py b/telegram/textsouls/main.py index abbccd3..f2e21c9 100755 --- a/telegram/textsouls/main.py +++ b/telegram/textsouls/main.py @@ -7,7 +7,7 @@ from common import backend with open("textsouls/config.json") as config_file: config_data = json.load(config_file) -API_TOKEN = config_data["main_settings"]["bot_token"] +API_TOKEN = config_data["MAIN_SETTINGS"]["BOT_TOKEN"] bot = Bot(token=API_TOKEN) dp = Dispatcher(bot) @@ -17,18 +17,20 @@ dp = Dispatcher(bot) async def start(message): tg_user = message.from_user ts_user = { - "tg_id": tg_user.id, + "id": tg_user.id, "first_name": tg_user.first_name, "last_name": tg_user.last_name, "username": tg_user.username, } - result = backend.post("/registration", ts_user) - if not result["error"] and result["response"].ok: - data = json.loads(result["response"].text) - if data["created"]: + result = backend.post("/users", ts_user) + if not result["error"]: + response_code = result["response"].status_code + if response_code == 200: await message.reply("Добро пожаловать!") - else: + elif response_code == 400: await message.reply("Добро пожаловать! Снова") + else: + await message.reply("Что-то другое") else: await message.reply("Упс! Что-то пошло не так")