Commit inicial

This commit is contained in:
Augusto Gunsch 2021-10-14 16:02:23 -03:00
commit db4640de72
No known key found for this signature in database
GPG Key ID: F7EEFE29825C72DC
11 changed files with 145 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
__pycache__/
venv/
pyrightconfig.json
database.db

2
Makefile Normal file
View File

@ -0,0 +1,2 @@
requirements:
pipreqs

7
README.md Normal file
View File

@ -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.

7
app/__init__.py Normal file
View File

@ -0,0 +1,7 @@
from flask import Flask
app = Flask(__name__)
app.debug = True
from .routes import routes

55
app/database.py Normal file
View File

@ -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")

0
app/routes/__init__.py Normal file
View File

41
app/routes/routes.py Normal file
View File

@ -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))

18
app/trainer.py Normal file
View File

@ -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

5
create_db.py Executable file
View File

@ -0,0 +1,5 @@
#!/bin/python3
from app.database import db
from app.trainer import Trainer
db.create_trainers_table()

1
requirements.txt Normal file
View File

@ -0,0 +1 @@
Flask==2.0.2

5
run.py Executable file
View File

@ -0,0 +1,5 @@
#!/bin/python3
from app import app
if __name__ == "__main__":
app.run()