From 4039c743f522768223a17e9332766a5f2ce3b7eb Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Mon, 14 Dec 2020 11:10:31 -0300 Subject: [PATCH 01/20] Database migration - Add created_on and updated_on fields Run `flask db upgrade` --- .../migrations/versions/175235720f56_.py | 30 +++++++++++++++++++ prototipo/projeto/ext/admin/views.py | 3 +- prototipo/projeto/ext/api/models.py | 5 ++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 prototipo/migrations/versions/175235720f56_.py diff --git a/prototipo/migrations/versions/175235720f56_.py b/prototipo/migrations/versions/175235720f56_.py new file mode 100644 index 0000000..ab1d4c9 --- /dev/null +++ b/prototipo/migrations/versions/175235720f56_.py @@ -0,0 +1,30 @@ +"""empty message + +Revision ID: 175235720f56 +Revises: 61fd7b1a6054 +Create Date: 2020-12-14 13:59:25.369944 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '175235720f56' +down_revision = '61fd7b1a6054' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('estacao', sa.Column('created_on', sa.DateTime(), nullable=True)) + op.add_column('estacao', sa.Column('updated_on', sa.DateTime(), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('estacao', 'updated_on') + op.drop_column('estacao', 'created_on') + # ### end Alembic commands ### diff --git a/prototipo/projeto/ext/admin/views.py b/prototipo/projeto/ext/admin/views.py index 325d94d..6ee13d8 100644 --- a/prototipo/projeto/ext/admin/views.py +++ b/prototipo/projeto/ext/admin/views.py @@ -21,7 +21,8 @@ class UserView(AdminView): class EstacaoView(AdminView): - column_list = ("id", "local", "latitude", "longitude") + column_list = ("id", "local", "latitude", "longitude", "created_on", + "updated_on") column_sortable_list = () diff --git a/prototipo/projeto/ext/api/models.py b/prototipo/projeto/ext/api/models.py index cca948c..fcea9ba 100644 --- a/prototipo/projeto/ext/api/models.py +++ b/prototipo/projeto/ext/api/models.py @@ -10,6 +10,11 @@ class Estacao(db.Model): local = db.Column("local", db.String(255), nullable=False) latitude = db.Column("latitude", db.String(255), nullable=False) longitude = db.Column("longitude", db.String(255), nullable=False) + created_on = db.Column("created_on", db.DateTime, default=datetime.now) + updated_on = db.Column("updated_on", + db.DateTime, + default=datetime.now, + onupdate=datetime.now) def get_sensor(self, sensor_id): for sensor in self.sensores: From 8517dd165324c8a64b6dc49e649edf6168abdbbe Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Mon, 14 Dec 2020 11:32:16 -0300 Subject: [PATCH 02/20] FIX user admin form --- prototipo/projeto/ext/admin/views.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/prototipo/projeto/ext/admin/views.py b/prototipo/projeto/ext/admin/views.py index 6ee13d8..adb7372 100644 --- a/prototipo/projeto/ext/admin/views.py +++ b/prototipo/projeto/ext/admin/views.py @@ -19,6 +19,10 @@ class UserView(AdminView): column_list = ("id", "email", "is_admin") column_sortable_list = () + can_create = True + can_delete = True + can_edit = False + class EstacaoView(AdminView): column_list = ("id", "local", "latitude", "longitude", "created_on", From 0b5d35d13d5ab6fb22755c3215ec4e56e627cf56 Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Mon, 14 Dec 2020 11:41:31 -0300 Subject: [PATCH 03/20] FIX estacoes admin form --- prototipo/projeto/ext/admin/views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/prototipo/projeto/ext/admin/views.py b/prototipo/projeto/ext/admin/views.py index adb7372..cc46db8 100644 --- a/prototipo/projeto/ext/admin/views.py +++ b/prototipo/projeto/ext/admin/views.py @@ -28,6 +28,7 @@ class EstacaoView(AdminView): column_list = ("id", "local", "latitude", "longitude", "created_on", "updated_on") column_sortable_list = () + form_excluded_columns = ("created_on", "updated_on") class SensorView(AdminView): From 5b87d04f20222c9d528693d04d86905464847d28 Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Mon, 14 Dec 2020 12:33:49 -0300 Subject: [PATCH 04/20] FIX ordereded selector items --- prototipo/projeto/static/visualizacoes.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/prototipo/projeto/static/visualizacoes.js b/prototipo/projeto/static/visualizacoes.js index 517568b..87ff3dc 100644 --- a/prototipo/projeto/static/visualizacoes.js +++ b/prototipo/projeto/static/visualizacoes.js @@ -20,8 +20,8 @@ $(function () { const result = await fetch(`${URL_BASE}/estacao`); if (result.ok) { - const data = await result.json(); - return data.resources; + let data = await result.json(); + return data.resources.sort(function(a, b) {return a.id > b.id}); } } @@ -34,7 +34,7 @@ $(function () { if (result.ok) { const data = await result.json(); - return data.resources; + return data.resources.sort(function(a, b) {return a.id > b.id}); } } @@ -47,7 +47,7 @@ $(function () { if (result.ok) { const data = await result.json(); - return data.resource.params.split(","); + return data.resource.params.split(",").sort(); } } From 04844a10ce34d1c506835c100ad4a3530581a474 Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Tue, 15 Dec 2020 18:27:03 -0300 Subject: [PATCH 05/20] REFACTOR database - Add field SensorTipo - Run `flask db migrate` --- prototipo/migrations/env.py | 5 +- .../migrations/versions/175235720f56_.py | 3 +- .../migrations/versions/3eeb4ae85a13_.py | 3 +- .../migrations/versions/61fd7b1a6054_.py | 3 +- .../8384895bb7ff_initial_migration.py | 3 +- .../migrations/versions/bb88fe255549_.py | 44 ++++++++ prototipo/projeto/app.py | 1 - prototipo/projeto/ext/api/__init__.py | 1 - prototipo/projeto/ext/api/models.py | 32 ++++-- prototipo/projeto/ext/api/views.py | 3 +- prototipo/projeto/ext/auth/__init__.py | 1 - prototipo/projeto/ext/auth/views.py | 5 +- prototipo/projeto/ext/jwt.py | 1 - prototipo/projeto/ext/site.py | 1 - prototipo/sensor_sim.py | 101 +++++++++--------- 15 files changed, 131 insertions(+), 76 deletions(-) create mode 100644 prototipo/migrations/versions/bb88fe255549_.py diff --git a/prototipo/migrations/env.py b/prototipo/migrations/env.py index 9452179..f01d2e8 100644 --- a/prototipo/migrations/env.py +++ b/prototipo/migrations/env.py @@ -3,10 +3,8 @@ import logging from logging.config import fileConfig -from sqlalchemy import engine_from_config -from sqlalchemy import pool - from alembic import context +from sqlalchemy import engine_from_config, pool # this is the Alembic Config object, which provides # access to the values within the .ini file in use. @@ -22,6 +20,7 @@ # from myapp import mymodel # target_metadata = mymodel.Base.metadata from flask import current_app + config.set_main_option( 'sqlalchemy.url', str(current_app.extensions['migrate'].db.engine.url).replace('%', '%%')) diff --git a/prototipo/migrations/versions/175235720f56_.py b/prototipo/migrations/versions/175235720f56_.py index ab1d4c9..d2f090d 100644 --- a/prototipo/migrations/versions/175235720f56_.py +++ b/prototipo/migrations/versions/175235720f56_.py @@ -5,9 +5,8 @@ Create Date: 2020-12-14 13:59:25.369944 """ -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision = '175235720f56' diff --git a/prototipo/migrations/versions/3eeb4ae85a13_.py b/prototipo/migrations/versions/3eeb4ae85a13_.py index b74260f..e35deb1 100644 --- a/prototipo/migrations/versions/3eeb4ae85a13_.py +++ b/prototipo/migrations/versions/3eeb4ae85a13_.py @@ -5,9 +5,8 @@ Create Date: 2020-11-16 16:11:48.278616 """ -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision = '3eeb4ae85a13' diff --git a/prototipo/migrations/versions/61fd7b1a6054_.py b/prototipo/migrations/versions/61fd7b1a6054_.py index b2ea39c..139d2fd 100644 --- a/prototipo/migrations/versions/61fd7b1a6054_.py +++ b/prototipo/migrations/versions/61fd7b1a6054_.py @@ -5,9 +5,8 @@ Create Date: 2020-11-30 14:31:27.250926 """ -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision = '61fd7b1a6054' diff --git a/prototipo/migrations/versions/8384895bb7ff_initial_migration.py b/prototipo/migrations/versions/8384895bb7ff_initial_migration.py index 705374e..a319e85 100644 --- a/prototipo/migrations/versions/8384895bb7ff_initial_migration.py +++ b/prototipo/migrations/versions/8384895bb7ff_initial_migration.py @@ -5,9 +5,8 @@ Create Date: 2020-11-16 16:05:42.270171 """ -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision = '8384895bb7ff' diff --git a/prototipo/migrations/versions/bb88fe255549_.py b/prototipo/migrations/versions/bb88fe255549_.py new file mode 100644 index 0000000..0511b75 --- /dev/null +++ b/prototipo/migrations/versions/bb88fe255549_.py @@ -0,0 +1,44 @@ +"""empty message + +Revision ID: bb88fe255549 +Revises: 175235720f56 +Create Date: 2020-12-15 20:37:21.871157 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = 'bb88fe255549' +down_revision = '175235720f56' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('sensor_tipo', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('codigo', sa.String(length=255), nullable=False), + sa.Column('descricao', sa.String(length=255), nullable=False), + sa.Column('params', sa.String(length=255), nullable=False), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('codigo') + ) + op.add_column('sensor', sa.Column('tipo_id', sa.Integer(), nullable=False)) + op.create_foreign_key(None, 'sensor', 'sensor_tipo', ['tipo_id'], ['id']) + op.drop_column('sensor', 'tipo') + op.drop_column('sensor', 'params') + op.drop_column('sensor', 'descricao') + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('sensor', sa.Column('descricao', sa.VARCHAR(length=255), autoincrement=False, nullable=False)) + op.add_column('sensor', sa.Column('params', sa.VARCHAR(length=255), autoincrement=False, nullable=False)) + op.add_column('sensor', sa.Column('tipo', sa.VARCHAR(length=255), autoincrement=False, nullable=False)) + op.drop_constraint(None, 'sensor', type_='foreignkey') + op.drop_column('sensor', 'tipo_id') + op.drop_table('sensor_tipo') + # ### end Alembic commands ### diff --git a/prototipo/projeto/app.py b/prototipo/projeto/app.py index be77085..d6c65f2 100644 --- a/prototipo/projeto/app.py +++ b/prototipo/projeto/app.py @@ -1,7 +1,6 @@ from datetime import timedelta from flask import Flask - from projeto.ext import admin, api, auth, db, jwt, site diff --git a/prototipo/projeto/ext/api/__init__.py b/prototipo/projeto/ext/api/__init__.py index 583fe25..1643abc 100644 --- a/prototipo/projeto/ext/api/__init__.py +++ b/prototipo/projeto/ext/api/__init__.py @@ -1,5 +1,4 @@ from flask_restful import Api - from projeto.ext.api.views import (ApiEstacao, ApiEstacaoId, ApiEstacaoIdSensor, ApiSensorId, ApiSensorIdParam, ApiSensorIdParamLast) diff --git a/prototipo/projeto/ext/api/models.py b/prototipo/projeto/ext/api/models.py index fcea9ba..cb57e77 100644 --- a/prototipo/projeto/ext/api/models.py +++ b/prototipo/projeto/ext/api/models.py @@ -38,9 +38,15 @@ class Sensor(db.Model): __tablename__ = "sensor" id = db.Column("id", db.Integer, primary_key=True) - tipo = db.Column("tipo", db.String(255), nullable=False) - descricao = db.Column("descricao", db.String(255), nullable=False) - params = db.Column("params", db.String(255), nullable=False) + + tipo_id = db.Column("tipo_id", + db.Integer, + db.ForeignKey("sensor_tipo.id"), + nullable=False) + tipo = db.relationship("SensorTipo", + backref=db.backref("sensores", + cascade="all, delete-orphan", + lazy=True)) estacao_id = db.Column("estacao_id", db.Integer, @@ -54,14 +60,26 @@ class Sensor(db.Model): def json(self): return { "id": self.id, - "tipo": self.tipo, - "descricao": self.descricao, - "params": self.params, + "tipo": self.tipo.codigo, + "descricao": self.tipo.descricao, + "params": self.tipo.params, "estacao_id": self.estacao_id, } def __repr__(self): - return f"{self.tipo}" + return f"{self.tipo.codigo}" + + +class SensorTipo(db.Model): + __tablename__ = "sensor_tipo" + + id = db.Column("id", db.Integer, primary_key=True) + codigo = db.Column("codigo", db.String(255), nullable=False, unique=True) + descricao = db.Column("descricao", db.String(255), nullable=False) + params = db.Column("params", db.String(255), nullable=False) + + def __repr__(self): + return f"{self.codigo}" class Leitura(db.Model): diff --git a/prototipo/projeto/ext/api/views.py b/prototipo/projeto/ext/api/views.py index 2d2ee33..a14cc5a 100644 --- a/prototipo/projeto/ext/api/views.py +++ b/prototipo/projeto/ext/api/views.py @@ -2,12 +2,11 @@ from flask_jwt import jwt_required from flask_restful import Resource, reqparse +from projeto.ext.api.models import Estacao, Leitura, Sensor from projeto.ext.db import db from sqlalchemy.exc import IntegrityError from sqlalchemy.orm.exc import UnmappedInstanceError -from projeto.ext.api.models import Estacao, Leitura, Sensor - HTTP_RESPONSE_CREATED = 201 HTTP_RESPONSE_NOT_FOUND = 404 diff --git a/prototipo/projeto/ext/auth/__init__.py b/prototipo/projeto/ext/auth/__init__.py index 84f16ee..a4c7438 100644 --- a/prototipo/projeto/ext/auth/__init__.py +++ b/prototipo/projeto/ext/auth/__init__.py @@ -1,5 +1,4 @@ from flask_login import LoginManager - from projeto.ext.auth.models import UserAuth from projeto.ext.auth.views import bp diff --git a/prototipo/projeto/ext/auth/views.py b/prototipo/projeto/ext/auth/views.py index 5ae6f98..d224f8a 100644 --- a/prototipo/projeto/ext/auth/views.py +++ b/prototipo/projeto/ext/auth/views.py @@ -2,13 +2,12 @@ from flask_login import login_required, login_user, logout_user from flask_wtf import FlaskForm from passlib.hash import sha256_crypt +from projeto.ext.auth.models import UserAuth +from projeto.ext.db import db from wtforms import PasswordField from wtforms.fields.html5 import EmailField from wtforms.validators import DataRequired, Email, Length -from projeto.ext.auth.models import UserAuth -from projeto.ext.db import db - bp = Blueprint("auth", __name__) diff --git a/prototipo/projeto/ext/jwt.py b/prototipo/projeto/ext/jwt.py index b646ff1..94554b0 100644 --- a/prototipo/projeto/ext/jwt.py +++ b/prototipo/projeto/ext/jwt.py @@ -1,6 +1,5 @@ from flask_jwt import JWT from passlib.hash import sha256_crypt - from projeto.ext.auth.models import UserAuth diff --git a/prototipo/projeto/ext/site.py b/prototipo/projeto/ext/site.py index 9ec33f5..ad9f46c 100644 --- a/prototipo/projeto/ext/site.py +++ b/prototipo/projeto/ext/site.py @@ -1,6 +1,5 @@ from flask import Blueprint, render_template from flask_login import login_required - from projeto.ext.api.models import Estacao from projeto.ext.auth.models import UserAuth diff --git a/prototipo/sensor_sim.py b/prototipo/sensor_sim.py index e2fcd3d..3c4b687 100644 --- a/prototipo/sensor_sim.py +++ b/prototipo/sensor_sim.py @@ -4,8 +4,7 @@ import numpy as np import requests - -from projeto.ext.api.models import Estacao, Leitura, Sensor +from projeto.ext.api.models import Estacao, Leitura, Sensor, SensorTipo from projeto.ext.db import db MIN_VAR = -1 @@ -29,54 +28,64 @@ def create_all(): - estacoes = [ + estacoes = { + "ubatuba": Estacao(local="Ubatuba", latitude="-23.43389", longitude="-45.07111"), + "caragua": Estacao(local="Caraguatatuba", latitude="-23.62028", longitude="-45.41306"), + "cunha": Estacao(local="Cunha", latitude="-23.07444", longitude="-44.95972") - ] + } + + tipos = { + "dht11": + SensorTipo(codigo="DHT11", + descricao="Sensor temperatura e umidade", + params="temp_ambiente,umid_relativa"), + "ldr": + SensorTipo(codigo="LDR", + descricao="Sensor de luminosidade", + params="luminosidade"), + "ds18b20": + SensorTipo(codigo="DS18B20", + descricao="Sensor de temperatura digital", + params="temp_agua"), + "solo": + SensorTipo(codigo="LM393_solo", + descricao="Sensor de umidade do solo", + params="umid_solo"), + "chuva": + SensorTipo(codigo="LM393_chuva", + descricao="Sensor de chuva", + params="chuva"), + "som": + SensorTipo(codigo="LM393_som", descricao="Sensor de som", + params="som"), + "bmp180": + SensorTipo(codigo="BMP180", + descricao="Sensor de altitude e pressão", + params="altitude,pressao"), + "dht22": + SensorTipo(codigo="DHT22", + descricao="Sensor temperatura e umidade", + params="temp_ambiente,umid_relativa") + } sensores = [ - Sensor(tipo="DHT11", - descricao="Sensor temperatura e umidade", - params="temp_ambiente,umid_relativa", - estacao_id=1), - Sensor(tipo="LDR", - descricao="Sensor de luminosidade", - params="luminosidade", - estacao_id=1), - Sensor(tipo="DS18B20", - descricao="Sensor de temperatura digital", - params="temp_agua", - estacao_id=1), - Sensor(tipo="LM393_solo", - descricao="Sensor de umidade do solo", - params="umid_solo", - estacao_id=1), - Sensor(tipo="LM393_chuva", - descricao="Sensor de chuva", - params="chuva", - estacao_id=1), - Sensor(tipo="LM393_som", - descricao="Sensor de som", - params="som", - estacao_id=1), - Sensor(tipo="BMP180", - descricao="Sensor de altitude e pressão", - params="altitude,pressao", - estacao_id=1), - Sensor(tipo="DHT22", - descricao="Sensor temperatura e umidade", - params="temp_ambiente,umid_relativa", - estacao_id=2), - Sensor(tipo="BMP180", - descricao="Sensor de altitude e pressão", - params="altitude,pressao", - estacao_id=3) + Sensor(tipo=tipos["dht11"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["ldr"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["ds18b20"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["solo"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["chuva"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["som"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["bmp180"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["dht22"], estacao=estacoes["caragua"]), + Sensor(tipo=tipos["bmp180"], estacao=estacoes["cunha"]), ] - for estacao in estacoes: + for estacao in estacoes.values(): db.session.add(estacao) db.session.commit() @@ -84,11 +93,9 @@ def create_all(): db.session.add(sensor) db.session.commit() - def get_datahora(): return int(datetime.timestamp(datetime.now())) - def post(url, leitura, token): response = requests.post(url, json={ @@ -98,7 +105,6 @@ def post(url, leitura, token): headers={"Authorization": f"jwt {token}"}) print(response.json()) - def simular(): auth = {"email": "admin@gmail.com", "password": "12345678"} url = "http://localhost:5000/token" @@ -112,7 +118,7 @@ def simular(): # Determina os valores iniciais para cada parámetro for sensor in sensores: valores_sensor = {} - for param in sensor.params.split(","): + for param in sensor.tipo.params.split(","): if param.startswith("temp"): pmin = MIN_TEMP pmax = MAX_TEMP @@ -143,7 +149,7 @@ def simular(): sleep(1) for sensor, valores in zip_sensores: - params = sensor.params.split(",") + params = sensor.tipo.params.split(",") for param in params: url = f"http://localhost:5000/api/{VERSAO}/sensor/{sensor.id}/{param}" inicial = float(valores[param]) @@ -151,7 +157,6 @@ def simular(): leitura = Leitura(valor=valor, datahora=get_datahora()) post(url, leitura, token) - if __name__ == "__main__": print(""" Esse script não deve ser executado. @@ -161,4 +166,4 @@ def simular(): - chame a função com: `sensor_sim.create_all()` `sensor_sim.simular()` - """) +""") From c15e55c2d289af22fcd7176f82d2574708fb9c0f Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Tue, 15 Dec 2020 22:39:57 -0300 Subject: [PATCH 06/20] REFACTOR arrow functions --- prototipo/projeto/static/visualizacoes.js | 26 +++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/prototipo/projeto/static/visualizacoes.js b/prototipo/projeto/static/visualizacoes.js index 87ff3dc..d61e08a 100644 --- a/prototipo/projeto/static/visualizacoes.js +++ b/prototipo/projeto/static/visualizacoes.js @@ -21,7 +21,7 @@ $(function () { if (result.ok) { let data = await result.json(); - return data.resources.sort(function(a, b) {return a.id > b.id}); + return data.resources.sort((a, b) => {return a.id > b.id}); } } @@ -34,7 +34,7 @@ $(function () { if (result.ok) { const data = await result.json(); - return data.resources.sort(function(a, b) {return a.id > b.id}); + return data.resources.sort((a, b) => {return a.id > b.id}); } } @@ -82,12 +82,12 @@ $(function () { function updateChart(serie, sensor_id, param) { fetch(`${URL_BASE}/sensor/${sensor_id}/${param}/1`) - .then(function(response) { + .then((response) => { let contentType = response.headers.get('content-type'); if (contentType && contentType.indexOf("application/json") !== -1) { return response.json() - .then(function(json) { + .then((json) => { // seconds (python) to milliseconds (js) let x = json.resources[0].datahora * 1000; let y = parseFloat(json.resources[0].valor); @@ -107,7 +107,7 @@ $(function () { if (estacoes) { $('#local-sel').empty(); - estacoes.forEach(function(estacao) { + estacoes.forEach((estacao) => { $('#local-sel') .append($('') .val(estacao.id) @@ -118,7 +118,7 @@ $(function () { if (sensores) { $('#sensor-sel').empty(); - sensores.forEach(function(sensor) { + sensores.forEach((sensor) => { $('#sensor-sel') .append($('') .val(sensor.id) @@ -129,7 +129,7 @@ $(function () { if (params) { $('#param-sel').empty(); - params.forEach(function(param) { + params.forEach((param) => { $('#param-sel') .append($('') .val(param) @@ -145,7 +145,7 @@ $(function () { * Inicializa o objeto Highcharts com os dados assícronos fornecidos * por requestData. */ - .then(function(data) { + .then((data) => { let chart = new Highcharts.chart('container', { chart: { @@ -153,7 +153,7 @@ $(function () { animation: Highcharts.svg, // don't animate in old IE marginRight: 10, events: { - load: function () { + load: function() { const selected = { estacao_id: data.estacoes[0].id, @@ -181,7 +181,7 @@ $(function () { selected.sensor_id = this.value; requestParams(selected.estacao_id, selected.sensor_id) - .then(function(params_new) { + .then((params_new) => { data.params = params_new; selected.param = data.params[0]; @@ -198,7 +198,7 @@ $(function () { selected.estacao_id = this.value; requestSensores(selected.estacao_id) - .then(function(sensores_new) { + .then((sensores_new) => { data.sensores = sensores_new; selected.sensor_id = data.sensores[0].id; @@ -214,7 +214,7 @@ $(function () { }); // set up the updating of the chart each second - setInterval(function () { + setInterval(() => { if (serie && selected.sensor_id && selected.param) { updateChart(serie, selected.sensor_id, selected.param); } @@ -236,7 +236,7 @@ $(function () { announceNewData: { enabled: true, minAnnounceInterval: 15000, - announcementFormatter: function (allSeries, newSeries, newPoint) { + announcementFormatter: (allSeries, newSeries, newPoint) => { if (newPoint) { return 'New point added. Value: ' + newPoint.y; } From 6b6de169bdf0fc6ae1479b63e0f338f759589f74 Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Wed, 16 Dec 2020 10:59:05 -0300 Subject: [PATCH 07/20] REFACTOR project directory layout --- {prototipo/Vagrant-setup => Vagrant-setup}/bootstrap.sh | 0 prototipo/Vagrantfile => Vagrantfile | 2 +- prototipo/package-lock.json => package-lock.json | 0 prototipo/package.json => package.json | 0 prototipo/setup.py | 2 +- 5 files changed, 2 insertions(+), 2 deletions(-) rename {prototipo/Vagrant-setup => Vagrant-setup}/bootstrap.sh (100%) rename prototipo/Vagrantfile => Vagrantfile (92%) rename prototipo/package-lock.json => package-lock.json (100%) rename prototipo/package.json => package.json (100%) diff --git a/prototipo/Vagrant-setup/bootstrap.sh b/Vagrant-setup/bootstrap.sh similarity index 100% rename from prototipo/Vagrant-setup/bootstrap.sh rename to Vagrant-setup/bootstrap.sh diff --git a/prototipo/Vagrantfile b/Vagrantfile similarity index 92% rename from prototipo/Vagrantfile rename to Vagrantfile index 57d16cd..47315e2 100644 --- a/prototipo/Vagrantfile +++ b/Vagrantfile @@ -13,7 +13,7 @@ Vagrant.configure("2") do |config| # config.vm.network "private_network", ip: "192.168.33.10" config.vm.network "public_network" - config.vm.synced_folder "./", "/vagrant_data" + config.vm.synced_folder "./prototipo", "/vagrant_data" config.vm.provider "virtualbox" do |vb| vb.name = "focal64_flaskAPI" diff --git a/prototipo/package-lock.json b/package-lock.json similarity index 100% rename from prototipo/package-lock.json rename to package-lock.json diff --git a/prototipo/package.json b/package.json similarity index 100% rename from prototipo/package.json rename to package.json diff --git a/prototipo/setup.py b/prototipo/setup.py index 69ee722..50eba3c 100644 --- a/prototipo/setup.py +++ b/prototipo/setup.py @@ -8,7 +8,7 @@ def read(filename): setup( name="FlaskAPI", version="0.1.0", - description="Online Chess Game", + description="Flask REST API", packages=find_packages(), include_package_data=True, install_requires=read("requirements.txt"), From eedb9313526101fe28ebbd90d89c511dbfaf93b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Gon=C3=A7alves?= Date: Wed, 16 Dec 2020 19:13:14 -0300 Subject: [PATCH 08/20] =?UTF-8?q?Altera=C3=A7=C3=B5es=20Node?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NodeMCU/AdvancedWS_Node/AdvancedWS_Node.ino | 79 ++++++++++++++++++--- prototipo/Vagrantfile | 2 +- 2 files changed, 71 insertions(+), 10 deletions(-) diff --git a/NodeMCU/AdvancedWS_Node/AdvancedWS_Node.ino b/NodeMCU/AdvancedWS_Node/AdvancedWS_Node.ino index 9187321..0a39c25 100644 --- a/NodeMCU/AdvancedWS_Node/AdvancedWS_Node.ino +++ b/NodeMCU/AdvancedWS_Node/AdvancedWS_Node.ino @@ -23,10 +23,14 @@ DHT dht(DHTPin, DHTTYPE); WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, NTP_ADDRESS, NTP_OFFSET, NTP_INTERVAL); -const char *host = "192.168.0.106"; -const int led = D7; +const char *host = "192.168.0.106"; +const int httpPort = 5000; +const int led = D7; + +int estacao = 1; +String versao = "1.2"; +String token = ""; -int estacao = 1; int ldrPin = A0; int tmp = 80; int ldrValor = 0; @@ -110,12 +114,14 @@ void EncontraValor(String str1, String str2, String str3, int inicio, int fim, i if (str2 == "Pressao") { pos = str1.indexOf("Pressao", 0); Serial.println(pos); - if (pos > 0) + if (pos > 0) { str1 = str1.substring(pos); + Serial.println(str1); + } else if (pos == 0) { temp = str1.substring(1); pos = temp.indexOf("Pressao", 0); - if (pos >= 0) { + if (pos > 0) { Serial.println(pos); str1 = temp.substring(pos); } @@ -140,7 +146,6 @@ void EncontraValor(String str1, String str2, String str3, int inicio, int fim, i void EnviaDados(float valor, String tipo, int estacao) { WiFiClient client; - const int httpPort = 5000; timeClient.update(); if (!client.connect(host, httpPort)) { @@ -151,17 +156,32 @@ void EnviaDados(float valor, String tipo, int estacao) { String formattedTime = timeClient.getFormattedTime(); unsigned long epcohTime = timeClient.getEpochTime(); - data = "{\"valor\": " + String(valor) + ", \"datahora\": " + String(epcohTime) + "}"; - - client.println("POST /api/v1.1/sensor/" + String(estacao) + "/" + tipo + " HTTP/1.1"); + data = "{\"valor\": " + String(valor) + ", \"datahora\": " + String(epcohTime) + "}"; +/* + json= + { + "valor": 304.00, + "datahora": 1607109786 + }, + headers= + { + "Authorization": "jwt eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MDcxOTI0NzUsImlhdCI6MTYwNzEwNjA3NSwibmJmIjoxNjA3MTA2MDc1LCJpZGVudGl0eSI6MX0.gpFQ_KaX0DFd3ps8VHK7E5ly5L0doueUSbaYptgQVHI" + } +*/ + client.println("POST /api/v" + versao + "/sensor/" + String(estacao) + "/" + tipo + " HTTP/1.1"); client.print("Host: "); client.println(host); client.println("Accept: */*"); client.println("Content-Type: application/json"); + client.print("Authorization: "); + client.println(token); client.print("Content-Length: "); client.println(data.length()); + client.println(); client.print(data); + + Serial.println(token); Serial.println(data); delay(20); // Can be changed @@ -171,6 +191,43 @@ void EnviaDados(float valor, String tipo, int estacao) { delay(20); } +String RecebeToken() { + WiFiClient client; + String line, token2; + + if (!client.connect(host, httpPort)) { + Serial.println("connection failed"); + return "Erro ao conectar"; + } + + data = "{\"email\": \"admin@gmail.com\", \"password\": \"12345678\"}"; + + client.println("POST /token HTTP/1.1"); + client.print("Host: "); + client.println(host); + client.println("Accept: */*"); + client.println("Content-Type: application/json"); + client.print("Content-Length: "); + client.println(data.length()); + client.println(); + client.print(data); + + delay(20); // Can be changed + while (client.connected()) { + if (client.available()) { + line = client.readStringUntil('\n'); + if (line.indexOf("HTTP", 0) > 0) { + Serial.print("[Response:]"); + Serial.println(line.substring(0, 15)); + } + if (line.indexOf("access_token", 0) > 0) + token2 = "\"jwt " + line.substring(line.indexOf("access_token", 0)+16); + } + } + delay(20); + return token2; +} + void setup() { Serial.begin(115200); @@ -188,6 +245,10 @@ void setup() { dht.begin(); + token = RecebeToken(); + Serial.print("Token: "); + Serial.println(token); + digitalWrite(led, HIGH); delay(100); digitalWrite(led, LOW); diff --git a/prototipo/Vagrantfile b/prototipo/Vagrantfile index 57d16cd..e24dbdf 100644 --- a/prototipo/Vagrantfile +++ b/prototipo/Vagrantfile @@ -18,7 +18,7 @@ Vagrant.configure("2") do |config| config.vm.provider "virtualbox" do |vb| vb.name = "focal64_flaskAPI" vb.gui = false - vb.memory = "2048" + vb.memory = "1024" end config.vm.provision :shell, :path => "Vagrant-setup/bootstrap.sh" From 6ae340c6ba6d527df914ceb461c963724b7367aa Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Wed, 16 Dec 2020 19:44:08 -0300 Subject: [PATCH 09/20] ADD SensorType to admin panel --- prototipo/projeto/ext/admin/__init__.py | 5 +++-- prototipo/projeto/ext/admin/views.py | 9 +++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/prototipo/projeto/ext/admin/__init__.py b/prototipo/projeto/ext/admin/__init__.py index b9c38e3..02e68d0 100644 --- a/prototipo/projeto/ext/admin/__init__.py +++ b/prototipo/projeto/ext/admin/__init__.py @@ -1,6 +1,6 @@ from flask_admin import Admin -from projeto.ext.admin.views import EstacaoView, SensorView, UserView -from projeto.ext.api.models import Estacao, Sensor +from projeto.ext.admin.views import EstacaoView, SensorView, SensorTipoView, UserView +from projeto.ext.api.models import Estacao, Sensor, SensorTipo from projeto.ext.auth.models import UserAuth from projeto.ext.db import db @@ -12,6 +12,7 @@ def init_app(app): views = [ UserView(UserAuth, db.session), EstacaoView(Estacao, db.session), + SensorTipoView(SensorTipo, db.session), SensorView(Sensor, db.session), ] admin.add_views(*views) diff --git a/prototipo/projeto/ext/admin/views.py b/prototipo/projeto/ext/admin/views.py index cc46db8..1437a82 100644 --- a/prototipo/projeto/ext/admin/views.py +++ b/prototipo/projeto/ext/admin/views.py @@ -27,12 +27,17 @@ class UserView(AdminView): class EstacaoView(AdminView): column_list = ("id", "local", "latitude", "longitude", "created_on", "updated_on") - column_sortable_list = () form_excluded_columns = ("created_on", "updated_on") + column_sortable_list = () + + +class SensorTipoView(AdminView): + # column_list = ("id", "codigo", "descricao", "params") + column_sortable_list = () class SensorView(AdminView): - column_list = ("id", "tipo", "descricao", "params", "estacao") + # column_list = ("id", "tipo", "estacao") column_sortable_list = () form_excluded_columns = [ From 05f3c4f73eab0eeae10b634fa34d809710ad702f Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Mon, 14 Dec 2020 11:10:31 -0300 Subject: [PATCH 10/20] Database migration - Add created_on and updated_on fields Run `flask db upgrade` --- .../migrations/versions/175235720f56_.py | 30 +++++++++++++++++++ prototipo/projeto/ext/admin/views.py | 3 +- prototipo/projeto/ext/api/models.py | 5 ++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 prototipo/migrations/versions/175235720f56_.py diff --git a/prototipo/migrations/versions/175235720f56_.py b/prototipo/migrations/versions/175235720f56_.py new file mode 100644 index 0000000..ab1d4c9 --- /dev/null +++ b/prototipo/migrations/versions/175235720f56_.py @@ -0,0 +1,30 @@ +"""empty message + +Revision ID: 175235720f56 +Revises: 61fd7b1a6054 +Create Date: 2020-12-14 13:59:25.369944 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '175235720f56' +down_revision = '61fd7b1a6054' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('estacao', sa.Column('created_on', sa.DateTime(), nullable=True)) + op.add_column('estacao', sa.Column('updated_on', sa.DateTime(), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('estacao', 'updated_on') + op.drop_column('estacao', 'created_on') + # ### end Alembic commands ### diff --git a/prototipo/projeto/ext/admin/views.py b/prototipo/projeto/ext/admin/views.py index 325d94d..6ee13d8 100644 --- a/prototipo/projeto/ext/admin/views.py +++ b/prototipo/projeto/ext/admin/views.py @@ -21,7 +21,8 @@ class UserView(AdminView): class EstacaoView(AdminView): - column_list = ("id", "local", "latitude", "longitude") + column_list = ("id", "local", "latitude", "longitude", "created_on", + "updated_on") column_sortable_list = () diff --git a/prototipo/projeto/ext/api/models.py b/prototipo/projeto/ext/api/models.py index cca948c..fcea9ba 100644 --- a/prototipo/projeto/ext/api/models.py +++ b/prototipo/projeto/ext/api/models.py @@ -10,6 +10,11 @@ class Estacao(db.Model): local = db.Column("local", db.String(255), nullable=False) latitude = db.Column("latitude", db.String(255), nullable=False) longitude = db.Column("longitude", db.String(255), nullable=False) + created_on = db.Column("created_on", db.DateTime, default=datetime.now) + updated_on = db.Column("updated_on", + db.DateTime, + default=datetime.now, + onupdate=datetime.now) def get_sensor(self, sensor_id): for sensor in self.sensores: From fff3792c43020116edfd76466b150ff70984c00a Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Mon, 14 Dec 2020 11:32:16 -0300 Subject: [PATCH 11/20] FIX user admin form --- prototipo/projeto/ext/admin/views.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/prototipo/projeto/ext/admin/views.py b/prototipo/projeto/ext/admin/views.py index 6ee13d8..adb7372 100644 --- a/prototipo/projeto/ext/admin/views.py +++ b/prototipo/projeto/ext/admin/views.py @@ -19,6 +19,10 @@ class UserView(AdminView): column_list = ("id", "email", "is_admin") column_sortable_list = () + can_create = True + can_delete = True + can_edit = False + class EstacaoView(AdminView): column_list = ("id", "local", "latitude", "longitude", "created_on", From ab49a0f3bf1a95972e594f259e2cc1ed7de1f82a Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Mon, 14 Dec 2020 11:41:31 -0300 Subject: [PATCH 12/20] FIX estacoes admin form --- prototipo/projeto/ext/admin/views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/prototipo/projeto/ext/admin/views.py b/prototipo/projeto/ext/admin/views.py index adb7372..cc46db8 100644 --- a/prototipo/projeto/ext/admin/views.py +++ b/prototipo/projeto/ext/admin/views.py @@ -28,6 +28,7 @@ class EstacaoView(AdminView): column_list = ("id", "local", "latitude", "longitude", "created_on", "updated_on") column_sortable_list = () + form_excluded_columns = ("created_on", "updated_on") class SensorView(AdminView): From 7af2054f7a41b3c99ec958863464ecdaeebc72a1 Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Mon, 14 Dec 2020 12:33:49 -0300 Subject: [PATCH 13/20] FIX ordereded selector items --- prototipo/projeto/static/visualizacoes.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/prototipo/projeto/static/visualizacoes.js b/prototipo/projeto/static/visualizacoes.js index 517568b..87ff3dc 100644 --- a/prototipo/projeto/static/visualizacoes.js +++ b/prototipo/projeto/static/visualizacoes.js @@ -20,8 +20,8 @@ $(function () { const result = await fetch(`${URL_BASE}/estacao`); if (result.ok) { - const data = await result.json(); - return data.resources; + let data = await result.json(); + return data.resources.sort(function(a, b) {return a.id > b.id}); } } @@ -34,7 +34,7 @@ $(function () { if (result.ok) { const data = await result.json(); - return data.resources; + return data.resources.sort(function(a, b) {return a.id > b.id}); } } @@ -47,7 +47,7 @@ $(function () { if (result.ok) { const data = await result.json(); - return data.resource.params.split(","); + return data.resource.params.split(",").sort(); } } From 4a7b4b45d1eaef7fc57d3fa445f6326e4bf7a996 Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Tue, 15 Dec 2020 18:27:03 -0300 Subject: [PATCH 14/20] REFACTOR database - Add field SensorTipo - Run `flask db migrate` --- prototipo/migrations/env.py | 5 +- .../migrations/versions/175235720f56_.py | 3 +- .../migrations/versions/3eeb4ae85a13_.py | 3 +- .../migrations/versions/61fd7b1a6054_.py | 3 +- .../8384895bb7ff_initial_migration.py | 3 +- .../migrations/versions/bb88fe255549_.py | 44 ++++++++ prototipo/projeto/app.py | 1 - prototipo/projeto/ext/api/__init__.py | 1 - prototipo/projeto/ext/api/models.py | 32 ++++-- prototipo/projeto/ext/api/views.py | 3 +- prototipo/projeto/ext/auth/__init__.py | 1 - prototipo/projeto/ext/auth/views.py | 5 +- prototipo/projeto/ext/jwt.py | 1 - prototipo/projeto/ext/site.py | 1 - prototipo/sensor_sim.py | 101 +++++++++--------- 15 files changed, 131 insertions(+), 76 deletions(-) create mode 100644 prototipo/migrations/versions/bb88fe255549_.py diff --git a/prototipo/migrations/env.py b/prototipo/migrations/env.py index 9452179..f01d2e8 100644 --- a/prototipo/migrations/env.py +++ b/prototipo/migrations/env.py @@ -3,10 +3,8 @@ import logging from logging.config import fileConfig -from sqlalchemy import engine_from_config -from sqlalchemy import pool - from alembic import context +from sqlalchemy import engine_from_config, pool # this is the Alembic Config object, which provides # access to the values within the .ini file in use. @@ -22,6 +20,7 @@ # from myapp import mymodel # target_metadata = mymodel.Base.metadata from flask import current_app + config.set_main_option( 'sqlalchemy.url', str(current_app.extensions['migrate'].db.engine.url).replace('%', '%%')) diff --git a/prototipo/migrations/versions/175235720f56_.py b/prototipo/migrations/versions/175235720f56_.py index ab1d4c9..d2f090d 100644 --- a/prototipo/migrations/versions/175235720f56_.py +++ b/prototipo/migrations/versions/175235720f56_.py @@ -5,9 +5,8 @@ Create Date: 2020-12-14 13:59:25.369944 """ -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision = '175235720f56' diff --git a/prototipo/migrations/versions/3eeb4ae85a13_.py b/prototipo/migrations/versions/3eeb4ae85a13_.py index b74260f..e35deb1 100644 --- a/prototipo/migrations/versions/3eeb4ae85a13_.py +++ b/prototipo/migrations/versions/3eeb4ae85a13_.py @@ -5,9 +5,8 @@ Create Date: 2020-11-16 16:11:48.278616 """ -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision = '3eeb4ae85a13' diff --git a/prototipo/migrations/versions/61fd7b1a6054_.py b/prototipo/migrations/versions/61fd7b1a6054_.py index b2ea39c..139d2fd 100644 --- a/prototipo/migrations/versions/61fd7b1a6054_.py +++ b/prototipo/migrations/versions/61fd7b1a6054_.py @@ -5,9 +5,8 @@ Create Date: 2020-11-30 14:31:27.250926 """ -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision = '61fd7b1a6054' diff --git a/prototipo/migrations/versions/8384895bb7ff_initial_migration.py b/prototipo/migrations/versions/8384895bb7ff_initial_migration.py index 705374e..a319e85 100644 --- a/prototipo/migrations/versions/8384895bb7ff_initial_migration.py +++ b/prototipo/migrations/versions/8384895bb7ff_initial_migration.py @@ -5,9 +5,8 @@ Create Date: 2020-11-16 16:05:42.270171 """ -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision = '8384895bb7ff' diff --git a/prototipo/migrations/versions/bb88fe255549_.py b/prototipo/migrations/versions/bb88fe255549_.py new file mode 100644 index 0000000..0511b75 --- /dev/null +++ b/prototipo/migrations/versions/bb88fe255549_.py @@ -0,0 +1,44 @@ +"""empty message + +Revision ID: bb88fe255549 +Revises: 175235720f56 +Create Date: 2020-12-15 20:37:21.871157 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = 'bb88fe255549' +down_revision = '175235720f56' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('sensor_tipo', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('codigo', sa.String(length=255), nullable=False), + sa.Column('descricao', sa.String(length=255), nullable=False), + sa.Column('params', sa.String(length=255), nullable=False), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('codigo') + ) + op.add_column('sensor', sa.Column('tipo_id', sa.Integer(), nullable=False)) + op.create_foreign_key(None, 'sensor', 'sensor_tipo', ['tipo_id'], ['id']) + op.drop_column('sensor', 'tipo') + op.drop_column('sensor', 'params') + op.drop_column('sensor', 'descricao') + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('sensor', sa.Column('descricao', sa.VARCHAR(length=255), autoincrement=False, nullable=False)) + op.add_column('sensor', sa.Column('params', sa.VARCHAR(length=255), autoincrement=False, nullable=False)) + op.add_column('sensor', sa.Column('tipo', sa.VARCHAR(length=255), autoincrement=False, nullable=False)) + op.drop_constraint(None, 'sensor', type_='foreignkey') + op.drop_column('sensor', 'tipo_id') + op.drop_table('sensor_tipo') + # ### end Alembic commands ### diff --git a/prototipo/projeto/app.py b/prototipo/projeto/app.py index be77085..d6c65f2 100644 --- a/prototipo/projeto/app.py +++ b/prototipo/projeto/app.py @@ -1,7 +1,6 @@ from datetime import timedelta from flask import Flask - from projeto.ext import admin, api, auth, db, jwt, site diff --git a/prototipo/projeto/ext/api/__init__.py b/prototipo/projeto/ext/api/__init__.py index 583fe25..1643abc 100644 --- a/prototipo/projeto/ext/api/__init__.py +++ b/prototipo/projeto/ext/api/__init__.py @@ -1,5 +1,4 @@ from flask_restful import Api - from projeto.ext.api.views import (ApiEstacao, ApiEstacaoId, ApiEstacaoIdSensor, ApiSensorId, ApiSensorIdParam, ApiSensorIdParamLast) diff --git a/prototipo/projeto/ext/api/models.py b/prototipo/projeto/ext/api/models.py index fcea9ba..cb57e77 100644 --- a/prototipo/projeto/ext/api/models.py +++ b/prototipo/projeto/ext/api/models.py @@ -38,9 +38,15 @@ class Sensor(db.Model): __tablename__ = "sensor" id = db.Column("id", db.Integer, primary_key=True) - tipo = db.Column("tipo", db.String(255), nullable=False) - descricao = db.Column("descricao", db.String(255), nullable=False) - params = db.Column("params", db.String(255), nullable=False) + + tipo_id = db.Column("tipo_id", + db.Integer, + db.ForeignKey("sensor_tipo.id"), + nullable=False) + tipo = db.relationship("SensorTipo", + backref=db.backref("sensores", + cascade="all, delete-orphan", + lazy=True)) estacao_id = db.Column("estacao_id", db.Integer, @@ -54,14 +60,26 @@ class Sensor(db.Model): def json(self): return { "id": self.id, - "tipo": self.tipo, - "descricao": self.descricao, - "params": self.params, + "tipo": self.tipo.codigo, + "descricao": self.tipo.descricao, + "params": self.tipo.params, "estacao_id": self.estacao_id, } def __repr__(self): - return f"{self.tipo}" + return f"{self.tipo.codigo}" + + +class SensorTipo(db.Model): + __tablename__ = "sensor_tipo" + + id = db.Column("id", db.Integer, primary_key=True) + codigo = db.Column("codigo", db.String(255), nullable=False, unique=True) + descricao = db.Column("descricao", db.String(255), nullable=False) + params = db.Column("params", db.String(255), nullable=False) + + def __repr__(self): + return f"{self.codigo}" class Leitura(db.Model): diff --git a/prototipo/projeto/ext/api/views.py b/prototipo/projeto/ext/api/views.py index 2d2ee33..a14cc5a 100644 --- a/prototipo/projeto/ext/api/views.py +++ b/prototipo/projeto/ext/api/views.py @@ -2,12 +2,11 @@ from flask_jwt import jwt_required from flask_restful import Resource, reqparse +from projeto.ext.api.models import Estacao, Leitura, Sensor from projeto.ext.db import db from sqlalchemy.exc import IntegrityError from sqlalchemy.orm.exc import UnmappedInstanceError -from projeto.ext.api.models import Estacao, Leitura, Sensor - HTTP_RESPONSE_CREATED = 201 HTTP_RESPONSE_NOT_FOUND = 404 diff --git a/prototipo/projeto/ext/auth/__init__.py b/prototipo/projeto/ext/auth/__init__.py index 84f16ee..a4c7438 100644 --- a/prototipo/projeto/ext/auth/__init__.py +++ b/prototipo/projeto/ext/auth/__init__.py @@ -1,5 +1,4 @@ from flask_login import LoginManager - from projeto.ext.auth.models import UserAuth from projeto.ext.auth.views import bp diff --git a/prototipo/projeto/ext/auth/views.py b/prototipo/projeto/ext/auth/views.py index 5ae6f98..d224f8a 100644 --- a/prototipo/projeto/ext/auth/views.py +++ b/prototipo/projeto/ext/auth/views.py @@ -2,13 +2,12 @@ from flask_login import login_required, login_user, logout_user from flask_wtf import FlaskForm from passlib.hash import sha256_crypt +from projeto.ext.auth.models import UserAuth +from projeto.ext.db import db from wtforms import PasswordField from wtforms.fields.html5 import EmailField from wtforms.validators import DataRequired, Email, Length -from projeto.ext.auth.models import UserAuth -from projeto.ext.db import db - bp = Blueprint("auth", __name__) diff --git a/prototipo/projeto/ext/jwt.py b/prototipo/projeto/ext/jwt.py index b646ff1..94554b0 100644 --- a/prototipo/projeto/ext/jwt.py +++ b/prototipo/projeto/ext/jwt.py @@ -1,6 +1,5 @@ from flask_jwt import JWT from passlib.hash import sha256_crypt - from projeto.ext.auth.models import UserAuth diff --git a/prototipo/projeto/ext/site.py b/prototipo/projeto/ext/site.py index 9ec33f5..ad9f46c 100644 --- a/prototipo/projeto/ext/site.py +++ b/prototipo/projeto/ext/site.py @@ -1,6 +1,5 @@ from flask import Blueprint, render_template from flask_login import login_required - from projeto.ext.api.models import Estacao from projeto.ext.auth.models import UserAuth diff --git a/prototipo/sensor_sim.py b/prototipo/sensor_sim.py index e2fcd3d..3c4b687 100644 --- a/prototipo/sensor_sim.py +++ b/prototipo/sensor_sim.py @@ -4,8 +4,7 @@ import numpy as np import requests - -from projeto.ext.api.models import Estacao, Leitura, Sensor +from projeto.ext.api.models import Estacao, Leitura, Sensor, SensorTipo from projeto.ext.db import db MIN_VAR = -1 @@ -29,54 +28,64 @@ def create_all(): - estacoes = [ + estacoes = { + "ubatuba": Estacao(local="Ubatuba", latitude="-23.43389", longitude="-45.07111"), + "caragua": Estacao(local="Caraguatatuba", latitude="-23.62028", longitude="-45.41306"), + "cunha": Estacao(local="Cunha", latitude="-23.07444", longitude="-44.95972") - ] + } + + tipos = { + "dht11": + SensorTipo(codigo="DHT11", + descricao="Sensor temperatura e umidade", + params="temp_ambiente,umid_relativa"), + "ldr": + SensorTipo(codigo="LDR", + descricao="Sensor de luminosidade", + params="luminosidade"), + "ds18b20": + SensorTipo(codigo="DS18B20", + descricao="Sensor de temperatura digital", + params="temp_agua"), + "solo": + SensorTipo(codigo="LM393_solo", + descricao="Sensor de umidade do solo", + params="umid_solo"), + "chuva": + SensorTipo(codigo="LM393_chuva", + descricao="Sensor de chuva", + params="chuva"), + "som": + SensorTipo(codigo="LM393_som", descricao="Sensor de som", + params="som"), + "bmp180": + SensorTipo(codigo="BMP180", + descricao="Sensor de altitude e pressão", + params="altitude,pressao"), + "dht22": + SensorTipo(codigo="DHT22", + descricao="Sensor temperatura e umidade", + params="temp_ambiente,umid_relativa") + } sensores = [ - Sensor(tipo="DHT11", - descricao="Sensor temperatura e umidade", - params="temp_ambiente,umid_relativa", - estacao_id=1), - Sensor(tipo="LDR", - descricao="Sensor de luminosidade", - params="luminosidade", - estacao_id=1), - Sensor(tipo="DS18B20", - descricao="Sensor de temperatura digital", - params="temp_agua", - estacao_id=1), - Sensor(tipo="LM393_solo", - descricao="Sensor de umidade do solo", - params="umid_solo", - estacao_id=1), - Sensor(tipo="LM393_chuva", - descricao="Sensor de chuva", - params="chuva", - estacao_id=1), - Sensor(tipo="LM393_som", - descricao="Sensor de som", - params="som", - estacao_id=1), - Sensor(tipo="BMP180", - descricao="Sensor de altitude e pressão", - params="altitude,pressao", - estacao_id=1), - Sensor(tipo="DHT22", - descricao="Sensor temperatura e umidade", - params="temp_ambiente,umid_relativa", - estacao_id=2), - Sensor(tipo="BMP180", - descricao="Sensor de altitude e pressão", - params="altitude,pressao", - estacao_id=3) + Sensor(tipo=tipos["dht11"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["ldr"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["ds18b20"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["solo"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["chuva"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["som"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["bmp180"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["dht22"], estacao=estacoes["caragua"]), + Sensor(tipo=tipos["bmp180"], estacao=estacoes["cunha"]), ] - for estacao in estacoes: + for estacao in estacoes.values(): db.session.add(estacao) db.session.commit() @@ -84,11 +93,9 @@ def create_all(): db.session.add(sensor) db.session.commit() - def get_datahora(): return int(datetime.timestamp(datetime.now())) - def post(url, leitura, token): response = requests.post(url, json={ @@ -98,7 +105,6 @@ def post(url, leitura, token): headers={"Authorization": f"jwt {token}"}) print(response.json()) - def simular(): auth = {"email": "admin@gmail.com", "password": "12345678"} url = "http://localhost:5000/token" @@ -112,7 +118,7 @@ def simular(): # Determina os valores iniciais para cada parámetro for sensor in sensores: valores_sensor = {} - for param in sensor.params.split(","): + for param in sensor.tipo.params.split(","): if param.startswith("temp"): pmin = MIN_TEMP pmax = MAX_TEMP @@ -143,7 +149,7 @@ def simular(): sleep(1) for sensor, valores in zip_sensores: - params = sensor.params.split(",") + params = sensor.tipo.params.split(",") for param in params: url = f"http://localhost:5000/api/{VERSAO}/sensor/{sensor.id}/{param}" inicial = float(valores[param]) @@ -151,7 +157,6 @@ def simular(): leitura = Leitura(valor=valor, datahora=get_datahora()) post(url, leitura, token) - if __name__ == "__main__": print(""" Esse script não deve ser executado. @@ -161,4 +166,4 @@ def simular(): - chame a função com: `sensor_sim.create_all()` `sensor_sim.simular()` - """) +""") From 830b579d5c75346c4ceb636107ead6fe51c23db0 Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Tue, 15 Dec 2020 22:39:57 -0300 Subject: [PATCH 15/20] REFACTOR arrow functions --- prototipo/projeto/static/visualizacoes.js | 26 +++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/prototipo/projeto/static/visualizacoes.js b/prototipo/projeto/static/visualizacoes.js index 87ff3dc..d61e08a 100644 --- a/prototipo/projeto/static/visualizacoes.js +++ b/prototipo/projeto/static/visualizacoes.js @@ -21,7 +21,7 @@ $(function () { if (result.ok) { let data = await result.json(); - return data.resources.sort(function(a, b) {return a.id > b.id}); + return data.resources.sort((a, b) => {return a.id > b.id}); } } @@ -34,7 +34,7 @@ $(function () { if (result.ok) { const data = await result.json(); - return data.resources.sort(function(a, b) {return a.id > b.id}); + return data.resources.sort((a, b) => {return a.id > b.id}); } } @@ -82,12 +82,12 @@ $(function () { function updateChart(serie, sensor_id, param) { fetch(`${URL_BASE}/sensor/${sensor_id}/${param}/1`) - .then(function(response) { + .then((response) => { let contentType = response.headers.get('content-type'); if (contentType && contentType.indexOf("application/json") !== -1) { return response.json() - .then(function(json) { + .then((json) => { // seconds (python) to milliseconds (js) let x = json.resources[0].datahora * 1000; let y = parseFloat(json.resources[0].valor); @@ -107,7 +107,7 @@ $(function () { if (estacoes) { $('#local-sel').empty(); - estacoes.forEach(function(estacao) { + estacoes.forEach((estacao) => { $('#local-sel') .append($('') .val(estacao.id) @@ -118,7 +118,7 @@ $(function () { if (sensores) { $('#sensor-sel').empty(); - sensores.forEach(function(sensor) { + sensores.forEach((sensor) => { $('#sensor-sel') .append($('') .val(sensor.id) @@ -129,7 +129,7 @@ $(function () { if (params) { $('#param-sel').empty(); - params.forEach(function(param) { + params.forEach((param) => { $('#param-sel') .append($('') .val(param) @@ -145,7 +145,7 @@ $(function () { * Inicializa o objeto Highcharts com os dados assícronos fornecidos * por requestData. */ - .then(function(data) { + .then((data) => { let chart = new Highcharts.chart('container', { chart: { @@ -153,7 +153,7 @@ $(function () { animation: Highcharts.svg, // don't animate in old IE marginRight: 10, events: { - load: function () { + load: function() { const selected = { estacao_id: data.estacoes[0].id, @@ -181,7 +181,7 @@ $(function () { selected.sensor_id = this.value; requestParams(selected.estacao_id, selected.sensor_id) - .then(function(params_new) { + .then((params_new) => { data.params = params_new; selected.param = data.params[0]; @@ -198,7 +198,7 @@ $(function () { selected.estacao_id = this.value; requestSensores(selected.estacao_id) - .then(function(sensores_new) { + .then((sensores_new) => { data.sensores = sensores_new; selected.sensor_id = data.sensores[0].id; @@ -214,7 +214,7 @@ $(function () { }); // set up the updating of the chart each second - setInterval(function () { + setInterval(() => { if (serie && selected.sensor_id && selected.param) { updateChart(serie, selected.sensor_id, selected.param); } @@ -236,7 +236,7 @@ $(function () { announceNewData: { enabled: true, minAnnounceInterval: 15000, - announcementFormatter: function (allSeries, newSeries, newPoint) { + announcementFormatter: (allSeries, newSeries, newPoint) => { if (newPoint) { return 'New point added. Value: ' + newPoint.y; } From 9aa2c6b1bf2eacf54a1e69596fa75d07c66c7292 Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Wed, 16 Dec 2020 10:59:05 -0300 Subject: [PATCH 16/20] REFACTOR project directory layout --- {prototipo/Vagrant-setup => Vagrant-setup}/bootstrap.sh | 0 prototipo/Vagrantfile => Vagrantfile | 2 +- prototipo/package-lock.json => package-lock.json | 0 prototipo/package.json => package.json | 0 prototipo/setup.py | 2 +- 5 files changed, 2 insertions(+), 2 deletions(-) rename {prototipo/Vagrant-setup => Vagrant-setup}/bootstrap.sh (100%) rename prototipo/Vagrantfile => Vagrantfile (92%) rename prototipo/package-lock.json => package-lock.json (100%) rename prototipo/package.json => package.json (100%) diff --git a/prototipo/Vagrant-setup/bootstrap.sh b/Vagrant-setup/bootstrap.sh similarity index 100% rename from prototipo/Vagrant-setup/bootstrap.sh rename to Vagrant-setup/bootstrap.sh diff --git a/prototipo/Vagrantfile b/Vagrantfile similarity index 92% rename from prototipo/Vagrantfile rename to Vagrantfile index e24dbdf..ea20441 100644 --- a/prototipo/Vagrantfile +++ b/Vagrantfile @@ -13,7 +13,7 @@ Vagrant.configure("2") do |config| # config.vm.network "private_network", ip: "192.168.33.10" config.vm.network "public_network" - config.vm.synced_folder "./", "/vagrant_data" + config.vm.synced_folder "./prototipo", "/vagrant_data" config.vm.provider "virtualbox" do |vb| vb.name = "focal64_flaskAPI" diff --git a/prototipo/package-lock.json b/package-lock.json similarity index 100% rename from prototipo/package-lock.json rename to package-lock.json diff --git a/prototipo/package.json b/package.json similarity index 100% rename from prototipo/package.json rename to package.json diff --git a/prototipo/setup.py b/prototipo/setup.py index 69ee722..50eba3c 100644 --- a/prototipo/setup.py +++ b/prototipo/setup.py @@ -8,7 +8,7 @@ def read(filename): setup( name="FlaskAPI", version="0.1.0", - description="Online Chess Game", + description="Flask REST API", packages=find_packages(), include_package_data=True, install_requires=read("requirements.txt"), From f2e4e3b2470e5b32a15c99332bd5964b1b504ce9 Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Wed, 16 Dec 2020 19:44:08 -0300 Subject: [PATCH 17/20] ADD SensorType to admin panel --- prototipo/projeto/ext/admin/__init__.py | 5 +++-- prototipo/projeto/ext/admin/views.py | 9 +++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/prototipo/projeto/ext/admin/__init__.py b/prototipo/projeto/ext/admin/__init__.py index b9c38e3..02e68d0 100644 --- a/prototipo/projeto/ext/admin/__init__.py +++ b/prototipo/projeto/ext/admin/__init__.py @@ -1,6 +1,6 @@ from flask_admin import Admin -from projeto.ext.admin.views import EstacaoView, SensorView, UserView -from projeto.ext.api.models import Estacao, Sensor +from projeto.ext.admin.views import EstacaoView, SensorView, SensorTipoView, UserView +from projeto.ext.api.models import Estacao, Sensor, SensorTipo from projeto.ext.auth.models import UserAuth from projeto.ext.db import db @@ -12,6 +12,7 @@ def init_app(app): views = [ UserView(UserAuth, db.session), EstacaoView(Estacao, db.session), + SensorTipoView(SensorTipo, db.session), SensorView(Sensor, db.session), ] admin.add_views(*views) diff --git a/prototipo/projeto/ext/admin/views.py b/prototipo/projeto/ext/admin/views.py index cc46db8..1437a82 100644 --- a/prototipo/projeto/ext/admin/views.py +++ b/prototipo/projeto/ext/admin/views.py @@ -27,12 +27,17 @@ class UserView(AdminView): class EstacaoView(AdminView): column_list = ("id", "local", "latitude", "longitude", "created_on", "updated_on") - column_sortable_list = () form_excluded_columns = ("created_on", "updated_on") + column_sortable_list = () + + +class SensorTipoView(AdminView): + # column_list = ("id", "codigo", "descricao", "params") + column_sortable_list = () class SensorView(AdminView): - column_list = ("id", "tipo", "descricao", "params", "estacao") + # column_list = ("id", "tipo", "estacao") column_sortable_list = () form_excluded_columns = [ From 8c73276f20f24c1c6c945f4dc6521529d555e161 Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Thu, 17 Dec 2020 12:01:46 -0300 Subject: [PATCH 18/20] Print request metadata --- prototipo/projeto/ext/admin/__init__.py | 3 ++- prototipo/projeto/ext/api/views.py | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/prototipo/projeto/ext/admin/__init__.py b/prototipo/projeto/ext/admin/__init__.py index 02e68d0..aa6cac5 100644 --- a/prototipo/projeto/ext/admin/__init__.py +++ b/prototipo/projeto/ext/admin/__init__.py @@ -1,5 +1,6 @@ from flask_admin import Admin -from projeto.ext.admin.views import EstacaoView, SensorView, SensorTipoView, UserView +from projeto.ext.admin.views import (EstacaoView, SensorTipoView, SensorView, + UserView) from projeto.ext.api.models import Estacao, Sensor, SensorTipo from projeto.ext.auth.models import UserAuth from projeto.ext.db import db diff --git a/prototipo/projeto/ext/api/views.py b/prototipo/projeto/ext/api/views.py index a14cc5a..61420fe 100644 --- a/prototipo/projeto/ext/api/views.py +++ b/prototipo/projeto/ext/api/views.py @@ -1,5 +1,7 @@ +# from pprint import pprint from datetime import datetime +# from flask import request from flask_jwt import jwt_required from flask_restful import Resource, reqparse from projeto.ext.api.models import Estacao, Leitura, Sensor @@ -198,6 +200,7 @@ def get(self, sensor_id, param): @jwt_required() def post(self, sensor_id, param): + # pprint(request.__dict__) parser = reqparse.RequestParser() parser.add_argument("valor", type=str, From 2f8fa8a2412d8050e0392e6ec8c0ad5701fbc3c2 Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Thu, 17 Dec 2020 12:19:04 -0300 Subject: [PATCH 19/20] UPDATES --- prototipo/projeto/ext/admin/__init__.py | 3 +-- prototipo/projeto/ext/api/__init__.py | 14 +++++++------- prototipo/projeto/ext/api/models.py | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/prototipo/projeto/ext/admin/__init__.py b/prototipo/projeto/ext/admin/__init__.py index aa6cac5..02e68d0 100644 --- a/prototipo/projeto/ext/admin/__init__.py +++ b/prototipo/projeto/ext/admin/__init__.py @@ -1,6 +1,5 @@ from flask_admin import Admin -from projeto.ext.admin.views import (EstacaoView, SensorTipoView, SensorView, - UserView) +from projeto.ext.admin.views import EstacaoView, SensorView, SensorTipoView, UserView from projeto.ext.api.models import Estacao, Sensor, SensorTipo from projeto.ext.auth.models import UserAuth from projeto.ext.db import db diff --git a/prototipo/projeto/ext/api/__init__.py b/prototipo/projeto/ext/api/__init__.py index 1643abc..2282f3b 100644 --- a/prototipo/projeto/ext/api/__init__.py +++ b/prototipo/projeto/ext/api/__init__.py @@ -4,18 +4,18 @@ ApiSensorIdParam, ApiSensorIdParamLast) api = Api() -versao = "v1.2" +VERSAO = "v1.2" -api.add_resource(ApiEstacao, f"/api/{versao}/estacao") -api.add_resource(ApiEstacaoId, f"/api/{versao}/estacao/") +api.add_resource(ApiEstacao, f"/api/{VERSAO}/estacao") +api.add_resource(ApiEstacaoId, f"/api/{VERSAO}/estacao/") api.add_resource(ApiEstacaoIdSensor, - f"/api/{versao}/estacao//sensor") -api.add_resource(ApiSensorId, f"/api/{versao}/sensor/") + f"/api/{VERSAO}/estacao//sensor") +api.add_resource(ApiSensorId, f"/api/{VERSAO}/sensor/") api.add_resource(ApiSensorIdParam, - f"/api/{versao}/sensor//") + f"/api/{VERSAO}/sensor//") api.add_resource( ApiSensorIdParamLast, - f"/api/{versao}/sensor///") + f"/api/{VERSAO}/sensor///") def init_app(app): diff --git a/prototipo/projeto/ext/api/models.py b/prototipo/projeto/ext/api/models.py index cb57e77..328dddf 100644 --- a/prototipo/projeto/ext/api/models.py +++ b/prototipo/projeto/ext/api/models.py @@ -16,7 +16,7 @@ class Estacao(db.Model): default=datetime.now, onupdate=datetime.now) - def get_sensor(self, sensor_id): + def get_sensor(self, sensor_id: int): for sensor in self.sensores: if sensor.id == sensor_id: return sensor From 885a591bcbdcd16dbbf01262920b0955b023a25a Mon Sep 17 00:00:00 2001 From: Alejandro Druetta Date: Wed, 23 Dec 2020 11:51:45 -0300 Subject: [PATCH 20/20] ADD: config & .env files for configurations --- .gitignore | 1 + prototipo/projeto/app.py | 11 +---------- prototipo/projeto/config.py | 37 +++++++++++++++++++++++++++++++++++++ prototipo/requirements.txt | 1 + 4 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 prototipo/projeto/config.py diff --git a/.gitignore b/.gitignore index e8877de..97fd1f5 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ node_modules/ *.db* *.log .eslintrc.* +.env requirements-dev.txt tilix.json diff --git a/prototipo/projeto/app.py b/prototipo/projeto/app.py index d6c65f2..40d490e 100644 --- a/prototipo/projeto/app.py +++ b/prototipo/projeto/app.py @@ -6,16 +6,7 @@ def create_app(): app = Flask(__name__) - - app.config[ - "SQLALCHEMY_DATABASE_URI"] = "postgresql://" + \ - "flaskapi:flaskapi@localhost:5432/flaskapi" - app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False - app.config["SECRET_KEY"] = "super-secret-key" - app.config["JWT_AUTH_USERNAME_KEY"] = "email" - app.config["JWT_AUTH_URL_RULE"] = "/token" - app.config["JWT_EXPIRATION_DELTA"] = timedelta(seconds=86400) # one day - app.config["FLASK_ADMIN_SWATCH"] = "sandstone" + app.config.from_object("projeto.config.DevConfig") db.init_app(app) api.init_app(app) diff --git a/prototipo/projeto/config.py b/prototipo/projeto/config.py new file mode 100644 index 0000000..bf91a46 --- /dev/null +++ b/prototipo/projeto/config.py @@ -0,0 +1,37 @@ +import os +from datetime import timedelta +from dotenv import load_dotenv + +basedir = os.path.abspath(os.path.dirname(__file__)) +load_dotenv(os.path.join(basedir, ".env"), verbose=True) + + +class BaseConfig: + """Base configs""" + + DEBUG = False + TESTING = False + SECRET_KEY = os.getenv("SECRET_KEY") + STATIC_FOLDER = "static" + TEMPLATE_FOLDER = "templates" + SQLALCHEMY_TRACK_MODIFICATIONS = False + JWT_AUTH_USERNAME_KEY = "email" + JWT_AUTH_URL_RULE = "/token" + JWT_EXPIRATION_DELTA = timedelta(seconds=86400) # one day + FLASK_ADMIN_SWATCH = "sandstone" + + +class ProdConfig(BaseConfig): + """Production configs""" + + FLASK_ENV = "production" + SQLALCHEMY_DATABASE_URI = os.getenv("PROD_DATABASE_URI") + + +class DevConfig(BaseConfig): + """Development configs""" + + FLASK_ENV = "development" + DEBUG = True + TESTING = True + SQLALCHEMY_DATABASE_URI = os.getenv("DEV_DATABASE_URI") diff --git a/prototipo/requirements.txt b/prototipo/requirements.txt index a675aaf..7c581f2 100644 --- a/prototipo/requirements.txt +++ b/prototipo/requirements.txt @@ -12,4 +12,5 @@ passlib numpy requests psycopg2-binary +python-dotenv