From db4640de723186e92e5bb45db7523c46b1983b11 Mon Sep 17 00:00:00 2001 From: Augusto Gunsch Date: Thu, 14 Oct 2021 16:02:23 -0300 Subject: [PATCH] Commit inicial --- .gitignore | 4 +++ Makefile | 2 ++ README.md | 7 ++++++ app/__init__.py | 7 ++++++ app/database.py | 55 ++++++++++++++++++++++++++++++++++++++++++ app/routes/__init__.py | 0 app/routes/routes.py | 41 +++++++++++++++++++++++++++++++ app/trainer.py | 18 ++++++++++++++ create_db.py | 5 ++++ requirements.txt | 1 + run.py | 5 ++++ 11 files changed, 145 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 app/__init__.py create mode 100644 app/database.py create mode 100644 app/routes/__init__.py create mode 100644 app/routes/routes.py create mode 100644 app/trainer.py create mode 100755 create_db.py create mode 100644 requirements.txt create mode 100755 run.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c81dc6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +__pycache__/ +venv/ +pyrightconfig.json +database.db diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7eaea23 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +requirements: + pipreqs diff --git a/README.md b/README.md new file mode 100644 index 0000000..a068e0b --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# Rodando +As dependências (Python) do projeto estão listadas em `requirements.txt`. +Para rodar o servidor de desenvolvimento, basta executar `python run.py`. Mas antes, é preciso criar o banco de dados uma vez: `python create_db.py`. O servidor por padrão tem sua interface em `http://localhost:5000`. + +# Desenvolvimento +- Comecei a desenvolver o projeto em Rust, mas sofri muito com a linguagem, perdendo uma tarde inteira lutando com o *borrow checker* e o framework Rocket. Concluí que preciso aprender melhor as mecânicas de *ownership* do Rust, e decidi fazer em Python (framework Flask) ao invés. +- Pensei em fazer em C# ou C++, mas seria obrigado a usar um sistema de build como cmake, que demoraria bastante tempo pra organizar. Isso porque uso Linux, e não posso garantir a portabilidade das `Makefile`s pra outras plataformas. diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..62e9225 --- /dev/null +++ b/app/__init__.py @@ -0,0 +1,7 @@ +from flask import Flask + +app = Flask(__name__) + +app.debug = True + +from .routes import routes diff --git a/app/database.py b/app/database.py new file mode 100644 index 0000000..f426c8f --- /dev/null +++ b/app/database.py @@ -0,0 +1,55 @@ +from .trainer import Trainer +import sqlite3 + +class Database: + def __init__(self, db_file): + self.db_file = db_file + + def create_trainers_table(self): + con = sqlite3.connect(self.db_file) + + con.execute(""" + CREATE TABLE IF NOT EXISTS Trainers + ( + id INT UNSIGNED UNIQUE, + nickname TINYTEXT PRIMARY KEY, + first_name TINYTEXT, + last_name TINYTEXT, + email TINYTEXT, + password TINYTEXT, + team TINYTEXT, + pokemons_owned INT UNSIGNED + ) + """) + + con.commit() + con.close() + + def __get_trainers(self, sql): + con = sqlite3.connect(self.db_file) + trainers = [] + for row in con.execute(*sql): + trainers.append(Trainer(*row).__dict__) + con.close() + return trainers + + def get_trainer_by_nickname(self, nickname, limit, offset): + return self.__get_trainers(("SELECT * FROM Trainers WHERE nickname = ? ? OFFSET ?", (nickname, limit, offset))) + + def get_trainers_by_nickname_contains(self, contains, limit, offset): + return self.__get_trainers(("SELECT * FROM Trainers WHERE nickname LIKE ? ? OFFSET", ("%" + contains + "%", limit, offset))) + + def insert_trainer(self, trainer): + con = sqlite3.connect(self.db_file) + + con.execute("INSERT INTO Trainers VALUES (?, ?, ?, ?, ?, ?, ?, ?)", + (trainer.id, trainer.nickname, + trainer.first_name, trainer.last_name, + trainer.email, trainer.password, + trainer.team, trainer.pokemons_owned) + ) + + con.commit() + con.close() + +db = Database("database.db") diff --git a/app/routes/__init__.py b/app/routes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/routes/routes.py b/app/routes/routes.py new file mode 100644 index 0000000..a48c607 --- /dev/null +++ b/app/routes/routes.py @@ -0,0 +1,41 @@ +from flask import request, jsonify +from app import app +from app.database import db + +@app.route('/trainer', methods=['GET']) +def route_get_trainers(): + args = request.args + + try: + limit = int(args.get("limit", 0)) + offset = int(args.get("offset", 0)) + except ValueError: + return { + "code": 1, + "type": "Integer parsing error", + "message": "Couldn't parse parameter as integer" + }, 500 + + if limit < 0 or offset < 0: + return { + "code": 2, + "type": "Integer parsing error", + "message": "Expected positive integer as parameter" + }, 500 + + limit_str = "LIMIT %d" % limit if "limit" in args else "" # gambiarra pra tornar o limite infinito por padrão + + nickname = args.get("nickname", "") + nickname_contains = args.get("nickname_contains", "") + + if nickname and nickname_contains: + return { + "code": 3, + "type": "Invalid parameter", + "message": "Parameters \"nickname\" and \"nickname_contains\" are mutually exclusive" + }, 500 + + if nickname: + return jsonify(db.get_trainer_by_nickname(nickname, limit_str, offset)) + else: + return jsonify(db.get_trainers_by_nickname_contains(nickname_contains, limit_str, offset)) diff --git a/app/trainer.py b/app/trainer.py new file mode 100644 index 0000000..764a8fd --- /dev/null +++ b/app/trainer.py @@ -0,0 +1,18 @@ +class Trainer: + def __init__(self, + id, + nickname, + first_name, + last_name, + email, + password, + team, + pokemons_owned): + self.id = id + self.nickname = nickname + self.first_name = first_name + self.last_name = last_name + self.email = email + self.password = password + self.team = team + self.pokemons_owned = pokemons_owned diff --git a/create_db.py b/create_db.py new file mode 100755 index 0000000..c856b05 --- /dev/null +++ b/create_db.py @@ -0,0 +1,5 @@ +#!/bin/python3 +from app.database import db +from app.trainer import Trainer + +db.create_trainers_table() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e433f90 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +Flask==2.0.2 diff --git a/run.py b/run.py new file mode 100755 index 0000000..ceac1f9 --- /dev/null +++ b/run.py @@ -0,0 +1,5 @@ +#!/bin/python3 +from app import app + +if __name__ == "__main__": + app.run()