Was able to successfully implement htmx for interactive select. The advacement requires new documentation. sensor update have been implmented, sensor_add, sensor_account are the next steps

master
Kerem Yollu 10 months ago
parent a3858ff048
commit 996b2cdfcd

79
web/$

@ -1,79 +0,0 @@
from flask import render_template, url_for, flash, redirect, request, Blueprint
from flask_login import login_required, current_user
from minibase.app import db
import minibase.theme as theme
from minibase.blueprints.company.models import Companies
import minibase.blueprints.database.utils as dbUtils
import minibase.blueprints.main.utils as mainUtils
import minibase.blueprints.geography.utils as geoUtils
import minibase.blueprints.company.utils as companyUtils
from minibase.blueprints.company.forms import updateCompanyForm
from minibase.blueprints.user.utils import save_picture
from flask_wtf import FlaskForm
# Declaring a blueprint
company = Blueprint('company', __name__, template_folder='templates')
@company.route("/list", methods=['GET', 'POST'])
def list():
page=request.args.get('page', 1, type=int)
table=dbUtils.table_printable_paginate(Companies, page, 20, 'edit/', 'id')
return(render_template('view.html', theme=theme, table=table, title="Companies"))
@company.route("/edit/<int:companyId>", methods=['GET', 'POST'])
@login_required
def edit_company(companyId):
if id:
form = updateCompanyForm()
company = companyUtils.queryById(companyId)
form.city.choices = [(row.id, row.name) for row in geoUtils.queryCiytNamesOfStateWithDefId(company.city_id, company.state_id)]
form.state.choices = [(row.id, row.name) for row in geoUtils.queryStateNamesOfCuntryWithDefId(company.state_id, company.country_id)]
form.country.choices = [(row.id, row.name) for row in geoUtils.queryCountryNamesWithDefault(company.country_id)]
form.industry.choices = [(row.id, row.name) for row in mainUtils.queryIndustryNamesWithDefault(company.industry_id)]
form.legal_entity.choices = [(row.id, row.name) for row in companyUtils.queryLegalEntityNames()]
form.type.choices = [(row.id, row.name) for row in companyUtils.queryTypeNames()]
form.relation.choices = [(row.id, row.name) for row in companyUtils.queryRelationNames()]
form.status.choices = [(row.id, row.name) for row in companyUtils.queryStatusNames()]
if form.validate_on_submit():
comp = Companies(
name = form.name.data,
street = form.street.data,
website = form.website.data,
street_no = form.street_no.data,
post_code = form.post_code.data,
city_id = form.city.data,
state_id = form.state.data,
country_id = form.country.data,
industry_id = form.industry.data,
legal_entity_id = form.legal_entity.data,
type_id = form.type.data,
relation_id = form.relation.data,
status_id = form.status.data,
comment = form.comment.data)
flash('Company Has been successfully updated', 'success')
return redirect(url_for('company.edit', companyId))
elif request.method == 'GET':
form.name.data = company.name
form.website.data = company.website
form.street.data = company.street
form.street_no.data = company.street_no
form.post_code.data = company.post_code
form.comment.data = company.comment
# This could be very interesting but neds more time to think !
#for field in form:
# if field.name != 'csrf_token' and hasattr(company, field.name):
# attr = getattr(company, field.name)
# field.data = attr
image_file = url_for('static', filename='pics/' + companyUtils.queryImageById(companyId))
return render_template('company/account.html',
theme=theme,
image_file=image_file,
form=form)
else:
flash('You need to select a company id', 'alarm')
return redirect(url_for('company.list'))

139
web/2

@ -0,0 +1,139 @@
from flask import render_template, Blueprint, request, flash, redirect, url_for
import minibase.theme as theme
from minibase.blueprints.sensor.models import nbiotDevice
import minibase.blueprints.sensor.utils as sensorUtils
from minibase.blueprints.sensor.forms import updateNbioDeviceUpdateForm, updateNbioDeviceAddForm
import minibase.blueprints.database.utils as dbUtils
import minibase.blueprints.company.utils as companyUtils
import minibase.blueprints.user.utils as userUtils
from minibase.app import db
import json
import os
sensor = Blueprint('sensor', __name__, template_folder='templates')
DATA_FILE = 'data.json'
sensor.route('/callback', methods=['POST'])
def callback():
data = request.json
if not data:
return jsonify({"error": "Invalid data"}), 400
# Read existing data
if os.path.exists(DATA_FILE):
with open(DATA_FILE, 'r') as f:
stored_data = json.load(f)
else:
stored_data = []
# Append new data
stored_data.append(data)
# Write data back to file
with open(DATA_FILE, 'w') as f:
json.dump(stored_data, f, indent=4)
return 'Callback received', 200
@sensor.route('/data', methods=['GET'])
def get_data():
if os.path.exists(DATA_FILE):
with open(DATA_FILE, 'r') as f:
stored_data = json.load(f)
else:
stored_data = []
return jsonify(stored_data)
@sensor.route('/list', methods=['GET','POST'])
def list():
page=request.args.get('page', 1, type=int)
table=dbUtils.table_printable_paginate(nbiotDevice, page, 20, 'edit/', 'id')
return(render_template('view.html', theme=theme, table=table, title="Devices List"))
@sensor.route("/edit/<int:deviceId>", methods=['GET', 'POST'])
def edit(deviceId):
if deviceId:
device = nbiotDevice.query.get_or_404(deviceId)
form = updateNbioDeviceUpdateForm(current_device_id=device.id)
form.user_id.choices = [(row.id, row.username) for row in userUtils.queryUserNamesWithDefault(device.user_id)]
form.owner_id.choices = [(row.id, row.username) for row in userUtils.queryUserNamesWithDefault(device.user_id)]
form.manufacturer_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(device.manufacturer_id)]
form.company_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(device.company_id)]
form.status_id.choices = [(row.id, row.name) for row in sensorUtils.queryStatusNamesWithDefault(device.status_id)]
form.type_id.choices = [(row.id, row.name) for row in sensorUtils.queryTypeNamesWithDefault(device.type_id)]
form.area_id.choices = [(row.id, row.name) for row in sensorUtils.queryAreaNamesWithDefault(device.area_id)]
if form.validate_on_submit():
device.name=form.name.data
device.serial_no = form.serial_no.data
device.device_id=form.device_id.data
device.imsi=form.imsi.data
device.iccid=form.iccid.data
device.ip=form.ip.data
device.port=form.port.data
device.registration_date=form.registration_date.data
device.activation_date=form.activation_date.data
device.deactivation_date=form.deactivation_date.data
device.owner_id=form.owner_id.data
device.user_id=form.user_id.data
device.status_id=form.status_id.data
device.type_id=form.type_id.data
device.area_id=form.area_id.data
device.manufacturer_id = form.manufacturer_id.data
device.company_id = form.manufacturer_id.data
db.session.commit()
flash('Device has been successfully updated', 'success')
return redirect(url_for('sensor.edit', deviceId=deviceId))
elif request.method == 'GET':
form.name.data = device.name
form.serial_no.data = device.serial_no
form.device_id.data = device.device_id
form.imsi.data = device.imsi
form.iccid.data = device.iccid
form.ip.data = device.ip
form.port.data = device.port
form.registration_date.data = device.registration_date
form.activation_date.data = device.activation_date
form.deactivation_date.data = device.deactivation_date
return render_template('sensor/account.html',
theme=theme,
form=form)
else:
flash('You need to select a Device id', 'alarm')
return redirect(url_for('sensor.list'))
@sensor.route('/add', methods=['GET', 'POST'])
def add():
form = updateNbioDeviceAddForm()
form.user_id.choices = [(row.id, row.username) for row in userUtils.queryUserChoices(1)]
form.status_id.choices = [(row.id, row.name) for row in sensorUtils.queryStatusChoices(1)]
form.type_id.choices = [(row.id, row.name) for row in sensorUtils.queryTypeChoices(1)]
form.area_id.choices = [(row.id, row.name) for row in sensorUtils.queryAreaChoices(1)]
if form.validate_on_submit():
dev = nbiotDevice(
name=form.name.data,
device_id=form.device_id.data,
imsi=form.imsi.data,
iccid=form.iccid.data,
ip=form.ip.data,
port=form.port.data,
registration_date=form.registration_date.data,
activation_date=form.activation_date.data,
deactivation_date=form.deactivation_date.data,
user_id=form.user_id.data,
status_id=form.status_id.data,
type_id=form.type_id.data,
area_id=form.area_id.data)
dbUtils.dbAddAndCommit(dev)
flash('Device has been successfully added', 'success')
return render_template('sensor/account.html',
theme=theme,
form=form)

@ -0,0 +1 @@
,key,devbian,13.08.2024 18:20,file:///home/key/.config/libreoffice/4;

@ -1,2 +1,2 @@
name,device_id,serial_no,imsi,iccid,ip,port,user_id,owner_id,man_id,status_id,type_id,area_id
miniUni,24070580,24070576,901405710203483,89882280000107407542,10.128.24.42,50000,1,1,1,1,1,1
name,device_id,serial_no,imsi,iccid,ip,port,user_id,owner_id,manufacturer_id,status_id,type_id,area_id,company_id
miniUni,24070580,24070576,901405710203483,898822800001074,10.128.24.42,50000,1,1,1,1,1,1,3

1 name device_id serial_no imsi iccid ip port user_id owner_id man_id manufacturer_id status_id type_id area_id company_id
2 miniUni 24070580 24070576 901405710203483 89882280000107407542 898822800001074 10.128.24.42 50000 1 1 1 1 1 1 1 3

Binary file not shown.

@ -50,6 +50,7 @@ def create_app():
from minibase.blueprints.errors.routes import errors
from minibase.blueprints.company.routes import company
from minibase.blueprints.geography.routes import geography
from minibase.blueprints.sensor.routes import sensor
# (BLUEPRINTS) Registering the blueprints.
# Giving them theie ulr_prefixes that will define their links on the webBrowser.
@ -58,6 +59,7 @@ def create_app():
app.register_blueprint(errors, url_prefix='/errors')
app.register_blueprint(company, url_prefix='/company')
app.register_blueprint(geography, url_prefix='/geography')
app.register_blueprint(sensor, url_prefix='/sensor')
# (APP) Returning the initialised app
return app

@ -3,15 +3,16 @@ from flask_wtf.file import FileField, FileAllowed
from wtforms import StringField, SubmitField, URLField, IntegerField, SelectField
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
import minibase.blueprints.company.utils as companyUtils
import minibase.theme as theme
class updateCompanyForm(FlaskForm): # Defines the form class to be used for the user update
name = StringField('Name', validators=[DataRequired(), Length(min=3, max=100)])
website = URLField('Website', validators=[DataRequired(), Length(min=3, max=100)])
country = SelectField('Country', validators=[DataRequired()])
city = SelectField('City', validators=[DataRequired()])
post_code = IntegerField('Post', validators=[DataRequired()])
country = SelectField('Country', validators=[DataRequired()], render_kw={"hx-get": "/geography/get_cities", "hx-target": "#city"})
city = SelectField('City', validators=[DataRequired()], render_kw={"hx-get": "/geography/get_states", "hx-target": "#state"})
state = SelectField('State', validators=[])
post_code = IntegerField('Post', validators=[DataRequired()])
street = StringField('Street', validators=[DataRequired()])
street_no = IntegerField('No', validators=[DataRequired()])
industry = SelectField('Industry', validators=[DataRequired()])
@ -21,7 +22,7 @@ class updateCompanyForm(FlaskForm): # Defines the form class to be used for the
status = SelectField('Status', validators=[DataRequired()])
comment = StringField('Comment', validators=[DataRequired(), Length(min=3, max=400)])
image_file = FileField('Update company Picture', validators=[FileAllowed(['jpg', 'png'])])
picture = FileField('Update company Picture', validators=[FileAllowed(['jpg', 'png'])])
submit = SubmitField('Update')
@ -31,3 +32,29 @@ class updateCompanyForm(FlaskForm): # Defines the form class to be used for the
if company:
raise ValidationError('That username is taken please choose another one')
class addCompanyForm(FlaskForm): # Defines the form class to be used for the user update
name = StringField('Name', validators=[DataRequired(), Length(min=3, max=100)])
website = URLField('Website', validators=[DataRequired(), Length(min=3, max=100)])
country = SelectField('Country', validators=[DataRequired()],choices=[], render_kw={"hx-get": "/geography/get_cities", "hx-target": "#city"})
city = SelectField('City', validators=[DataRequired()], render_kw={"hx-get": "/geography/get_states", "hx-target": "#state"})
state = SelectField('State', validators=[])
post_code = IntegerField('Post', validators=[DataRequired()])
street = StringField('Street', validators=[DataRequired()])
street_no = IntegerField('No', validators=[DataRequired()])
industry = SelectField('Industry', validators=[DataRequired()])
legal_entity= SelectField('Legal Entity', validators=[DataRequired()])
type = SelectField('Type', validators=[DataRequired()])
relation = SelectField('Relation', validators=[DataRequired()])
status = SelectField('Status', validators=[DataRequired()])
comment = StringField('Comment', validators=[DataRequired(), Length(min=3, max=400)])
submit = SubmitField('Add')
# Queries to be made in order to validate the form : If username exists
def validate_companyName(self, company_name):
company = companyUtils.queryByNameFirst(company_name)
if company:
raise ValidationError('That username is taken please choose another one')

@ -1,36 +1,41 @@
from flask import render_template, url_for, flash, redirect, request, Blueprint
from flask_login import login_required, current_user
from minibase.app import db
import minibase.theme as theme
from minibase.blueprints.company.models import Companies
from minibase.blueprints.geography.models import City
import minibase.blueprints.database.utils as dbUtils
import minibase.blueprints.main.utils as mainUtils
import minibase.blueprints.geography.utils as geoUtils
import minibase.blueprints.company.utils as companyUtils
from minibase.blueprints.company.forms import updateCompanyForm
from minibase.blueprints.user.utils import save_picture
from flask_wtf import FlaskForm
from minibase.blueprints.company.forms import updateCompanyForm, addCompanyForm
# Declaring a blueprint
company = Blueprint('company', __name__, template_folder='templates')
@company.route("/", methods=['GET', 'POST'])
@company.route("/list", methods=['GET', 'POST'])
def list():
page=request.args.get('page', 1, type=int)
table=dbUtils.table_printable_paginate(Companies, page, 20, 'edit/', 'id')
table=dbUtils.table_printable_paginate(Companies, page, 20, 'account/', 'id')
return(render_template('view.html', theme=theme, table=table, title="Companies"))
@company.route("/edit/<int:companyId>", methods=['GET', 'POST'])
@company.route("/account/<int:companyId>", methods=['GET', 'POST'])
@login_required
def edit_company(companyId):
def account(companyId):
if companyId:
company = Companies.query.get_or_404(companyId)
form = updateCompanyForm()
form.city.choices = [(row.id, row.name) for row in geoUtils.queryCiytNamesOfStateWithDefId(company.city_id, company.state_id)]
form.state.choices = [(row.id, row.name) for row in geoUtils.queryStateNamesOfCuntryWithDefId(company.state_id, company.country_id)]
form.country.choices = [(row.id, row.name) for row in geoUtils.queryCountryNamesWithDefault(company.country_id)]
# This is for the htmx implementation. please be careful how of there is data we switch the funtion needed
if form.country.data:
form.city.choices = [(row.id, row.name) for row in geoUtils.queryCityNamesWithCountryId(form.country.data)]
form.state.choices = [(row.id, row.name) for row in geoUtils.queryStateNamesWithCountryId(form.country.data)]
else:
form.city.choices = [(row.id, row.name) for row in geoUtils.queryCityNamesWithCountryIdWithDefault(company.city_id, company.country_id)]
form.state.choices = [(row.id, row.name) for row in geoUtils.queryStateNamesWithCountryIdWithDefault(company.state_id, company.country_id)]
form.industry.choices = [(row.id, row.name) for row in mainUtils.queryIndustryNamesWithDefault(company.industry_id)]
form.legal_entity.choices = [(row.id, row.name) for row in companyUtils.queryLegalEntityNamesWithDefault(company.legal_entity_id)]
form.type.choices = [(row.id, row.name) for row in companyUtils.queryTypeNamesWithDefault(company.type_id)]
@ -38,31 +43,39 @@ def edit_company(companyId):
form.status.choices = [(row.id, row.name) for row in companyUtils.queryStatusNamesWithDefault(company.status_id)]
if form.validate_on_submit():
company.name = form.name.data
company.street = form.street.data
company.website = form.website.data
company.street_no = form.street_no.data
company.post_code = form.post_code.data
company.city_id = form.city.data
company.state_id = form.state.data
company.country_id = form.country.data
company.industry_id = form.industry.data
company.legal_entity_id = form.legal_entity.data
company.type_id = form.type.data
company.relation_id = form.relation.data
company.status_id = form.status.data
company.comment = form.comment.data
flash('Company Has been successfully updated', 'success')
return redirect(url_for('company.edit', companyId=companyId))
if form.picture.data:
picture_file = mainUtils.save_picture(form.picture.data)
company.image_file = picture_file
company.name = form.name.data
company.website = form.website.data
company.country_id = form.country.data
company.city_id = form.city.data
company.state_id = form.state.data
company.post_code = form.post_code.data
company.street = form.street.data
company.street_no = form.street_no.data
company.industry_id = form.industry.data
company.legal_entity_id = form.legal_entity.data
company.type_id = form.type.data
company.relation_id = form.relation.data
company.status_id = form.status.data
company.comment = form.comment.data
dbUtils.dbCommit()
flash('Company Has been successfully updated', 'success')
return redirect(url_for('company.account', companyId=companyId))
elif request.method == 'GET':
form.name.data = company.name
form.website.data = company.website
form.country.data = company.country_id
form.city.data = company.city_id
form.state.data = company.state_id
form.post_code.data = company.post_code
form.street.data = company.street
form.street_no.data = company.street_no
form.post_code.data = company.post_code
form.comment.data = company.comment
form.legal_entity.data = company.legal_entity.name
form.type.data = company.type.name
form.type.data = company.type.name
form.comment.data = company.comment
image_file = url_for('static', filename='pics/' + companyUtils.queryImageById(companyId))
@ -72,10 +85,50 @@ def edit_company(companyId):
form=form)
else:
flash('You need to select a company id', 'alarm')
return redirect(url_for('company./'))
# This could be very interesting but neds more time to think !
#for field in form:
# if field.name != 'csrf_token' and hasattr(company, field.name):
# attr = getattr(company, field.name)
# field.data = attr
return redirect(url_for('company.list'))
@company.route("/add", methods=['GET', 'POST'])
@login_required
def add():
form = addCompanyForm()
form.country.choices = [(row.id, row.name) for row in geoUtils.queryCountryNames()]
# This is for the htmx implementation. please be careful how of there is data we switch the funtion needed
if form.country.data:
form.city.choices = [(row.id, row.name) for row in geoUtils.queryCityNamesWithCountryId(form.country.data)]
form.state.choices = [(row.id, row.name) for row in geoUtils.queryStateNamesWithCountryId(form.country.data)]
else:
form.city.choices = []
form.state.choices = []
form.industry.choices = [(row.id, row.name) for row in mainUtils.queryIndustryNames()]
form.legal_entity.choices = [(row.id, row.name) for row in companyUtils.queryLegalEntityNames()]
form.type.choices = [(row.id, row.name) for row in companyUtils.queryTypeNames()]
form.relation.choices = [(row.id, row.name) for row in companyUtils.queryRelationNames()]
form.status.choices = [(row.id, row.name) for row in companyUtils.queryStatusNames()]
if form.validate_on_submit():
company = Companies(
name = form.name.data,
website = form.website.data,
country_id = form.country.data,
city_id = form.city.data,
state_id = form.state.data,
post_code = form.post_code.data,
street = form.street.data,
street_no = form.street_no.data,
industry_id = form.industry.data,
legal_entity_id = form.legal_entity.data,
type_id = form.type.data,
relation_id = form.relation.data,
status_id = form.status.data,
comment = form.comment.data)
dbUtils.dbAddAndCommit(company)
flash('Company Has been successfully added', 'success')
return redirect(url_for('company.list'))
return render_template('edit.html',
title="Add Company",
theme=theme,
form=form)

@ -15,6 +15,11 @@ def queryNameById(cid):
return selected.name
def queryNamesWithDefault(defId):
choices = dbUtils.queryNameWithDefaultId(Companies, defId)
return choices
def queryStreetById(cid):
selected = Companies.query.filter_by(id=cid).first()
return selected.street

@ -6,6 +6,7 @@ import minibase.blueprints.company.utils as companyUtils
class LocationForm(FlaskForm):
country = SelectField('Country', validators=[DataRequired()])
# Addinf custom argumets to the form filed to make it compatible with htmx, without hawing to edit the HTML fomrs.
country = SelectField('Country', validators=[DataRequired()],render_kw={"hx-get": "get_cities", "hx-target": "#city"})
city = SelectField('City', validators=[DataRequired()])
submit = SubmitField('Update')

@ -12,6 +12,8 @@ from flask_wtf import FlaskForm
# Declaring a blueprint
geography = Blueprint('geography', __name__, template_folder='templates')
country_id = 0
@geography.route('/test', methods=["GET", "POST"])
def test():
print("hello")
@ -34,19 +36,17 @@ def test():
@geography.route("/get_cities", methods=['GET', 'POST'])
def get_cities():
global country_id
country_id = request.args.get("country", type=int)
print(f"/get_cities -> country_id: {country_id}")
cities = City.query.filter_by(country_id=country_id).all()
print(len(cities))
if len(cities) == 0:
cities = 'Non Awailable'
return render_template("geography/city_options.html", cities=cities)
@geography.route("/get_states", methods=['GET', 'POST'])
def get_states():
country_id = request.args.get("country", type=int)
cities = State.query.filter_by(country_id=country_id).all()
print(len(cities))
if len(cities) == 0:
cities = 'Non Awailable'
return render_template("geography/city_options.html", cities=cities)
global country_id
print(f"/get_states -> country_id: {country_id}")
states = State.query.filter_by(country_id=country_id).all()
return render_template("geography/state_options.html", states=states)

@ -3,7 +3,7 @@
<form method="POST" action="" enctype="multipart/form-data">>
<fieldset class="form-group">
{{ form.hidden_tag() }}
{{ form.country(**{"hx-get": "get_cities", "hx-target": "#city"}) }}
{{ form.country() }}
{{ form.city }}
<button>Submit</button>
</fieldset>

@ -0,0 +1,7 @@
{% for city in cities %}
<option value="{{ city.id }}">{{ city.name }}</option>
{% endfor %}
{% for state in states %}
<option value="{{ state.id }}">{{ state.name }}</option>
{% endfor %}

@ -0,0 +1,3 @@
{% for state in states %}
<option value="{{ state.id }}">{{ state.name }}</option>
{% endfor %}

@ -23,12 +23,18 @@ def queryStateNamesWithDefault(defId):
return choices
def queryStateNamesOfCuntryWithDefId(defId, Filterid):
def queryStateNamesWithCountryIdWithDefault(defId, Filterid):
table = State
choices = table.query.order_by(case((table.id == defId, 0), else_=1), table.name.asc()).filter_by(country_id=Filterid)
return choices
def queryStateNamesWithCountryId(Filterid):
table = State
choices = table.query.order_by(table.name.asc()).filter_by(country_id=Filterid)
return choices
def queryCityNames():
choices = City.query.order_by(City.name.asc())
return choices
@ -39,7 +45,13 @@ def queryCityNamesWithDefault(defId):
return choices
def queryCiytNamesOfStateWithDefId(defId, Filterid):
def queryCityNamesWithCountryIdWithDefault(defId, Filterid):
table = City
choices = table.query.order_by(case((table.id == defId, 0), else_=1), table.name.asc()).filter_by(country_id=Filterid)
return choices
def queryCityNamesWithCountryId(Filterid):
table = City
choices = table.query.order_by(case((table.id == defId, 0), else_=1), table.name.asc()).filter_by(state_id=Filterid)
choices = table.query.order_by(table.name.asc()).filter_by(country_id=Filterid)
return choices

@ -1,15 +1,43 @@
import os
import secrets
from PIL import Image
from flask import url_for, current_app
from flask_mail import Message
from minibase.app import mail
from minibase.blueprints.main.models import Industries
import minibase.blueprints.database.utils as dbUtils
from sqlalchemy import case
def save_picture(form_picture):
random_hex = secrets.token_hex(8)
_, f_ext = os.path.splitext(form_picture.filename)
picture_fn = random_hex + f_ext
picture_path = os.path.join(current_app.root_path, 'static/pics', picture_fn)
output_size = (125, 125)
i = Image.open(form_picture)
i.thumbnail(output_size)
i.save(picture_path)
return picture_fn
def send_reset_email(user):
token = user.get_reset_token()
msg = Message('Password Reset Request',
sender='noreply@demo.com',
recipients=[user.email_account])
msg.body = f'''To reset your password, visit the following link:
{url_for('user.reset_token', token=token, _external=True)}
If you didn't make this request, then simply ingnore this email and no chancges will be made.
'''
mail.send(msg)
def queryIndustryNames():
choices = Industries.query.order_by(Industries.name.asc())
return choices
def queryIndustryNamesWithDefault(defId):
choices = dbUtils.queryNameWithDefaultId(Industries,defId)
return choices

@ -2,13 +2,13 @@ from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed
from wtforms import StringField, PasswordField, SubmitField, BooleanField, URLField, IntegerField, DateField, SelectField
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
from iot.blueprints.sensor.models import nbiotDevice
from minibase.blueprints.sensor.models import nbiotDevice
from datetime import date
class updateNbioDeviceUpdateForm(FlaskForm): # Defines the form class to be used for the user update
name = StringField('Device Name', validators=[DataRequired(), Length(min=3, max=50)])
device_id = StringField('Device Id', validators=[DataRequired(), Length(min=3, max=50)])
serialNumber = StringField('Serial Number', validators=[DataRequired(), Length(min=3, max=50)])
serial_no = StringField('Serial Number', validators=[DataRequired(), Length(min=3, max=50)])
imsi = StringField('Imsi No', validators=[DataRequired(), Length(min=10, max=50)])
iccid = StringField('Iccid No', validators=[DataRequired(), Length(min=10, max=100)])
ip = StringField('Ip (ipv4)', validators=[DataRequired(), Length(min=7, max=15)])
@ -21,7 +21,8 @@ class updateNbioDeviceUpdateForm(FlaskForm): # Defines the form class to be use
status_id = SelectField('Status', validators=[DataRequired()])
type_id = SelectField('Type', validators=[DataRequired()])
area_id = SelectField('Area', validators=[DataRequired()])
manufacturer_id = SelectField('Manufacturer', validators=[DataRequired()])
company_id = SelectField('Managed By', validators=[DataRequired()])
submit = SubmitField(f'Update')
@ -62,6 +63,7 @@ class updateNbioDeviceUpdateForm(FlaskForm): # Defines the form class to be use
class updateNbioDeviceAddForm(FlaskForm): # Defines the form class to be used for the user update
name = StringField('Device Name', validators=[DataRequired(), Length(min=3, max=50)])
device_id = StringField('Device Id', validators=[DataRequired(), Length(min=3, max=50)])
serial_no = StringField('Serial Number', validators=[DataRequired(), Length(min=3, max=50)])
imsi = StringField('Imsi No', validators=[DataRequired(), Length(min=10, max=50)])
iccid = StringField('Iccid No', validators=[DataRequired(), Length(min=10, max=100)])
ip = StringField('Ip (ipv4)', validators=[Length(min=7, max=15)])
@ -73,6 +75,8 @@ class updateNbioDeviceAddForm(FlaskForm): # Defines the form class to be used f
status_id = SelectField('Status', validators=[DataRequired()])
type_id = SelectField('Type', validators=[DataRequired()])
area_id = SelectField('Area', validators=[DataRequired()])
manufacturer_id = SelectField('Manufacturer', validators=[DataRequired()])
company_id = SelectField('Managed By', validators=[DataRequired()])
submit = SubmitField(f'Add')

@ -1,4 +1,4 @@
from iot.app import db
from minibase.app import db
from datetime import datetime
class nbiotDevice(db.Model):
@ -6,6 +6,7 @@ class nbiotDevice(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False)
serial_no = db.Column(db.String(50), nullable=False)
device_id = db.Column(db.String(30), nullable=False)
imsi = db.Column(db.String(30), nullable=False)
iccid = db.Column(db.String(50), nullable=False)
@ -14,6 +15,7 @@ class nbiotDevice(db.Model):
registration_date = db.Column(db.DateTime, nullable=True)
activation_date = db.Column(db.DateTime, nullable=True)
deactivation_date = db.Column(db.DateTime, nullable=True)
image_file = db.Column(db.String(20), nullable=False, default='def_sensor.png')
created = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
updated = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow)
@ -22,9 +24,9 @@ class nbiotDevice(db.Model):
status_id = db.Column(db.Integer, db.ForeignKey('nbiotDeviceStatus.id'), nullable=False)
type_id = db.Column(db.Integer, db.ForeignKey('nbiotDeviceType.id'), nullable=False)
area_id = db.Column(db.Integer, db.ForeignKey('nbiotDeviceArea.id'), nullable=False)
manufacturer_id = db.Column(db.Integer, db.ForeignKey('companies.id'), nullable=False)
company_id = db.Column(db.Integer, db.ForeignKey('companies.id'), nullable=False)
owner = db.relationship('User', foreign_keys=[owner_id], backref='owned_devices')
user = db.relationship('User', foreign_keys=[user_id], backref='used_devices')
class nbiotDeviceStatus(db.Model):
__tablename__ = 'nbiotDeviceStatus'

@ -1,11 +1,12 @@
from flask import render_template, Blueprint, request, flash, redirect, url_for
import iot.theme as theme
from iot.blueprints.sensor.models import nbiotDevice
import iot.blueprints.sensor.utils as sensorUtils
from iot.blueprints.sensor.forms import updateNbioDeviceUpdateForm, updateNbioDeviceAddForm
import iot.blueprints.database.utils as dbUtils
import iot.blueprints.user.utils as userUtils
from iot.app import db
import minibase.theme as theme
from minibase.blueprints.sensor.models import nbiotDevice
import minibase.blueprints.sensor.utils as sensorUtils
from minibase.blueprints.sensor.forms import updateNbioDeviceUpdateForm, updateNbioDeviceAddForm
import minibase.blueprints.database.utils as dbUtils
import minibase.blueprints.company.utils as companyUtils
import minibase.blueprints.user.utils as userUtils
from minibase.app import db
import json
import os
@ -13,7 +14,6 @@ sensor = Blueprint('sensor', __name__, template_folder='templates')
DATA_FILE = 'data.json'
sensor.route('/callback', methods=['POST'])
def callback():
data = request.json
@ -61,13 +61,16 @@ def edit(deviceId):
if deviceId:
device = nbiotDevice.query.get_or_404(deviceId)
form = updateNbioDeviceUpdateForm(current_device_id=device.id)
form.user_id.choices = [(row.id, row.username) for row in userUtils.queryUserChoices(device.user_id)]
form.owner_id.choices = [(row.id, row.username) for row in userUtils.queryUserChoices(device.user_id)]
form.status_id.choices = [(row.id, row.name) for row in sensorUtils.queryStatusChoices(device.status_id)]
form.type_id.choices = [(row.id, row.name) for row in sensorUtils.queryTypeChoices(device.type_id)]
form.area_id.choices = [(row.id, row.name) for row in sensorUtils.queryAreaChoices(device.area_id)]
form.user_id.choices = [(row.id, row.username) for row in userUtils.queryUserNamesWithDefault(device.user_id)]
form.owner_id.choices = [(row.id, row.username) for row in userUtils.queryUserNamesWithDefault(device.user_id)]
form.manufacturer_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(device.manufacturer_id)]
form.company_id.choices = [(row.id, row.name) for row in companyUtils.queryNamesWithDefault(device.company_id)]
form.status_id.choices = [(row.id, row.name) for row in sensorUtils.queryStatusNamesWithDefault(device.status_id)]
form.type_id.choices = [(row.id, row.name) for row in sensorUtils.queryTypeNamesWithDefault(device.type_id)]
form.area_id.choices = [(row.id, row.name) for row in sensorUtils.queryAreaNamesWithDefault(device.area_id)]
if form.validate_on_submit():
device.name=form.name.data
device.serial_no = form.serial_no.data
device.device_id=form.device_id.data
device.imsi=form.imsi.data
device.iccid=form.iccid.data
@ -81,11 +84,14 @@ def edit(deviceId):
device.status_id=form.status_id.data
device.type_id=form.type_id.data
device.area_id=form.area_id.data
device.manufacturer_id = form.manufacturer_id.data
device.company_id = form.company_id.data
db.session.commit()
flash('Device has been successfully updated', 'success')
return redirect(url_for('sensor.edit', deviceId=deviceId))
elif request.method == 'GET':
form.name.data = device.name
form.serial_no.data = device.serial_no
form.device_id.data = device.device_id
form.imsi.data = device.imsi
form.iccid.data = device.iccid

@ -1,4 +1,5 @@
from iot.blueprints.sensor.models import nbiotDevice, nbiotDeviceStatus, nbiotDeviceType, nbiotDeviceArea
from minibase.blueprints.sensor.models import nbiotDevice, nbiotDeviceStatus, nbiotDeviceType, nbiotDeviceArea
import minibase.blueprints.database.utils as dbUtils
from sqlalchemy import case
@ -7,16 +8,16 @@ def queryById(id):
return nbiotDevice.query.filter_by(id=id).first()
def queryStatusChoices(curretnId):
choices = nbiotDeviceStatus.query.order_by(case((nbiotDeviceStatus.id == curretnId, 0),else_=1),nbiotDeviceStatus.name.asc())
def queryStatusNamesWithDefault(defId):
choices = dbUtils.queryNameWithDefaultId(nbiotDeviceStatus, defId)
return choices
def queryTypeChoices(curretnId):
choices = nbiotDeviceType.query.order_by(case((nbiotDeviceType.id == curretnId, 0),else_=1),nbiotDeviceType.name.asc())
def queryTypeNamesWithDefault(defId):
choices = dbUtils.queryNameWithDefaultId(nbiotDeviceType, defId)
return choices
def queryAreaChoices(curretnId):
choices = nbiotDeviceArea.query.order_by(case((nbiotDeviceArea.id == curretnId, 0),else_=1),nbiotDeviceArea.name.asc())
def queryAreaNamesWithDefault(defId):
choices = dbUtils.queryNameWithDefaultId(nbiotDeviceArea, defId)
return choices

@ -3,7 +3,6 @@ from itsdangerous import URLSafeTimedSerializer as Serializer
from minibase.app import db, login_manager
from flask_login import UserMixin
from datetime import datetime
from minibase.blueprints.main.models import Notes
# The Default User Loading proccess
@ -29,12 +28,14 @@ class Users(db.Model, UserMixin):
notes = db.relationship('Notes', backref='author', lazy='dynamic')
todos = db.relationship('Todos', backref='author', lazy='dynamic')
# Here is a one to one relationship: each user can only have one role, and there can be multiple users with the same role
# type(user.role) = <class 'minibase.blueprints.user.models.User_Roles'>
# type(user.role_id) = <class 'int'> #
role_id = db.Column(db.Integer, db.ForeignKey('user_roles.id'), nullable=False, default=2)
role = db.relationship('User_Roles', backref=db.backref('users', lazy='dynamic'))
def get_reset_token(self, expires_sec=1800):
s = Serializer(current_app.config['SECRET_KEY'])

@ -6,7 +6,7 @@ from minibase.blueprints.user.models import Users, User_Roles
import minibase.blueprints.database.utils as dbUtils
import minibase.blueprints.user.utils as UserUtils
from minibase.blueprints.user.forms import registrationForm, loginForm, updateAccountForm, resetPasswordForm, requestResetForm, updateRoleForm
from minibase.blueprints.user.utils import save_picture, send_reset_email
import minibase.blueprints.main.utils as mainUtils
# Declaring a blueprint
user = Blueprint('user', __name__, template_folder='templates')
@ -60,7 +60,7 @@ def account():
form = updateAccountForm()
if form.validate_on_submit():
if form.picture.data:
picture_file = save_picture(form.picture.data)
picture_file = mainUtils.save_picture(form.picture.data)
current_user.image_file = picture_file
current_user.username = form.username.data
current_user.email_account = form.email_account.data
@ -87,7 +87,7 @@ def reset_request():
form = requestResetForm()
if form.validate_on_submit():
user = UserUtils.dbGetMailFirst(form.email.data)
send_reset_email(user)
mainUtils.send_reset_email(user)
flash('An Email has been sent with instruction to reset your password', 'warning')
return render_template('user/reset_request.html',
theme=theme,

@ -1,37 +1,16 @@
import os
import secrets
from PIL import Image
from flask import url_for, current_app
from flask_mail import Message
from minibase.app import mail
from minibase.blueprints.user.models import Users, User_Roles
import minibase.blueprints.database.utils as dbUtils
from sqlalchemy import case
def dbGetMailFirst(mail):
return Users.query.filter_by(email_account=mail).first()
def save_picture(form_picture):
random_hex = secrets.token_hex(8)
_, f_ext = os.path.splitext(form_picture.filename)
picture_fn = random_hex + f_ext
picture_path = os.path.join(current_app.root_path, 'static/pics', picture_fn)
output_size = (125, 125)
i = Image.open(form_picture)
i.thumbnail(output_size)
i.save(picture_path)
return picture_fn
def send_reset_email(user):
token = user.get_reset_token()
msg = Message('Password Reset Request',
sender='noreply@demo.com',
recipients=[user.email_account])
msg.body = f'''To reset your password, visit the following link:
{url_for('user.reset_token', token=token, _external=True)}
If you didn't make this request, then simply ingnore this email and no chancges will be made.
'''
mail.send(msg)
def queryRoleById(id):
return User_Roles.query.get_or_404(id)
def queryUserNamesWithDefault(defId):
choices = Users.query.order_by(case((Users.id == defId, 0),else_=1),Users.username.asc())
return choices;

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

@ -4,8 +4,6 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<!-- Referencing custom CSS stylesheet --!>
<link rel="stylesheet" type="text/css" href="/css/style.css"/>
<!-- Referencing Bootstrap CSS stylesheet --!>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<!-- Referencing Favicon --!>

@ -1,21 +1,21 @@
{% extends "base.html" %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<div class="container-fluid text-center rounded-3 mt-2 mb-2" style="{{ theme.form.div_style }};">
<div class="container text-center rounded-3 mt-2 mb-2" style="{{ theme.form.div_style }};">
<h1 class="account-heading" style="color: {{ theme.orange }};">{{ title }}</h1>
</div>
<div class="container-fluid rounded-3 " style="{{ theme.form.div_style }};">
<div class="container rounded-3 " style="{{ theme.form.div_style }};">
{% include 'form.html' %}
{% if extraButtons %}
</div>
<div class="container-fluid rounded-3 mt-2 mb-2" style="{{ theme.form.div_style }};">
<div class="btn-group">
<br>
{% for button in extraButtons %}
<li><a href ="{{ button.link }}" class="{{ theme.form.submit_class }}" style="{{ theme.form.submit_style }}">{{ button.name }}<a>
{% endfor %}
<br>
</div>
<div class="container text-left rounded-3 mt-2 mb-2" style="{{ theme.form.div_style }};">
<div class="btn-group">
<br>
{% for button in extraButtons %}
<li><a href ="{{ button.link }}" class="{{ theme.form.submit_class }}" style="{{ theme.form.submit_style }}">{{ button.name }}<a>
{% endfor %}
<br>
</div>
{% endif %}
</div>

@ -5,15 +5,14 @@
{% if item.id == 'submit' %}
{% elif item.id == 'csrf_token' %}
{% else %}
{% include 'form/stringField.html' %}
{% include 'form/selectFieldVer.html' %}
{% include 'form/dateField.html' %}
{% include 'form/boolField.html' %}
{% include 'form/fileField.html' %}
{% include 'form/urlField.html' %}
{% include 'form/integerField.html' %}
{% include 'form/allFields.html' %}
{% if item.errors %}
{% include 'form/formError.html' %}
{% endif %}
{% endif %}
{% endfor %}
</fieldset>
<div>{% include 'form/submitField.html' %}</div>
<div>
{% include 'form/submitField.html' %}
</div>
</form>

@ -0,0 +1,7 @@
{% include 'form/stringField.html' %}
{% include 'form/selectField.html' %}
{% include 'form/dateField.html' %}
{% include 'form/boolField.html' %}
{% include 'form/fileField.html' %}
{% include 'form/urlField.html' %}
{% include 'form/integerField.html' %}

@ -1,15 +1,6 @@
{% if item.type == 'BooleanField' %}
<br>
{{ item.label(class=theme.form.check_label_class, style=theme.form.check_label_style) }}
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type == 'BooleanField' %}
{{ item(class=theme.form.check_class) }}
{% endif %}
<br>
{{ item(class=theme.form.check_class) }}
{% endif %}

@ -1,23 +0,0 @@
{% for item in form %}
{% if item.id == 'submit' %}
{% elif item.id == 'csrf_token' %}
{% else %}
{% if item.type == 'BooleanField' %}
<br>
{{ item.label(class=theme.form.check_label_class, style=theme.form.check_label_style) }}
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type == 'BooleanField' %}
<br>
{{ item(class=theme.form.check_class) }}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}

@ -1,15 +1,6 @@
{% if item.type in ['DateField', 'DateTimeField'] %}
{{ item.label(class=theme.form.input_label_class, style=theme.form.input_label_style) }}
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type in ['DateField', 'DateTimeField'] %}
{{ item(class=theme.form.input_class, type=theme.form.date_type) }}
{% endif %}
<br>
{{ item.label(class=theme.form.date_label_class, style=theme.form.date_label_style) }}
<br>
{{ item(class=theme.form.date_class, style=theme.form.date_style, type=theme.form.date_type) }}
{% endif %}

@ -1,23 +0,0 @@
{% for item in form %}
{% if item.id == 'submit' %}
{% elif item.id == 'csrf_token' %}
{% else %}
{% if item.type in ['DateField', 'DateTimeField'] %}
<br>
{{ item.label(class=theme.form.input_label_class, style=theme.form.input_label_style) }}
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type in ['DateField', 'DateTimeField'] %}
<br>
{{ item(class=theme.form.input_class, type=theme.form.date_type) }}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}

@ -1,17 +1,6 @@
{% if item.type in ['FileField'] %}
<br>
{{ item.label(class=theme.form.file_label_class, style=theme.form.file_label_style) }}
<br>
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type in ['FileField'] %}
{{ item(class=theme.form.file_class, type=theme.form.file_type, style=theme.form.file_style) }}
<br>
{% endif %}
{{ item(class=theme.form.file_class, type=theme.form.file_type, style=theme.form.file_style) }}
{% endif %}

@ -1,15 +1,6 @@
{% if item.type in ['IntegerField', 'DecimalField', 'FloatField'] %}
{{ item.label(class=theme.form.input_label_class, style=theme.form.input_label_style) }}
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type in ['IntegerField', 'DecimalField', 'FloatField'] %}
{{ item(class=theme.form.input_class) }}
{% endif %}
<br>
{{ item.label(class=theme.form.integer_label_class, style=theme.form.integer_label_style) }}
<br>
{{ item(class=theme.form.integer_class, style=theme.form.integer_style) }}
{% endif %}

@ -0,0 +1,6 @@
{% if item.type in ['SelectField'] %}
<br>
{{ item.label(class=theme.form.select_label_class, style=theme.form.select_label_style) }}
<br>
{{ item(class=theme.form.select_class, type=theme.form.select_type, style=theme.form.select_style)}}
{% endif %}

@ -1,17 +0,0 @@
{% if item.type in ['SelectField'] %}
{{ item.label(class=theme.form.select_label_class, style=theme.form.select_label_style) }}
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
<div class="col">
{% if item.type in ['SelectField'] %}
{{ item(class=theme.form.select_class, type=theme.form.select_type, style=theme.form.select_style) }}
{% endif %}
</div>
{% endif %}

@ -1,17 +0,0 @@
{% if item.type in ['SelectField'] %}
{{ item.label(class=theme.form.select_label_class, style=theme.form.select_label_style) }}
<br>
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.select_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type in ['SelectField'] %}
{{ item(class=theme.form.select_class, type=theme.form.select_type, style=theme.form.select_style) }}
<br>
{% endif %}
{% endif %}

@ -1,23 +0,0 @@
{% for item in form %}
{% if item.id == 'submit' %}
{% elif item.id == 'csrf_token' %}
{% else %}
{% if item.type in ['SelectField'] %}
<br>
{{ item.label(class=theme.form.input_label_class, style=theme.form.input_label_style) }}
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type in ['SelectField'] %}
<br>
{{ item(class=theme.form.select_class, type=theme.form.select_type, style=theme.form.select_style) }}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}

@ -1,17 +1,6 @@
{% if item.type in ['StringField', 'TextAreaField', 'PasswordField'] %}
<br>
{{ item.label(class=theme.form.input_label_class, style=theme.form.input_label_style) }}
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type in ['StringField', 'TextAreaField', 'PasswordField'] %}
<div class="col">
{{ item(class=theme.form.input_class) }}
</div>
{% endif %}
<br>
{{ item(class=theme.form.input_class, style=theme.form.input_style) }}
{% endif %}

@ -1,21 +0,0 @@
{% for item in form %}
{% if item.id == 'submit' %}
{% elif item.id == 'csrf_token' %}
{% else %}
{% if item.type in ['StringField', 'TextAreaField', 'PasswordField'] %}
{{ item.label(class=theme.form.input_label_class, style=theme.form.input_label_style) }}
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.input_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type in ['StringField', 'TextAreaField', 'PasswordField'] %}
{{ item(class=theme.form.input_class) }}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}

@ -1,15 +1,6 @@
{% if item.type in ['URLField'] %}
<br>
{{ item.label(class=theme.form.url_label_class, style=theme.form.url_label_style) }}
{% endif %}
{% if item.errors %}
{{ item(class=theme.form.url_error_class) }}
<div class="{{ theme.form.div_error_class }}">
{% for error in item.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{% if item.type in ['URLField'] %}
{{ item(class=theme.form.url_class, type=theme.form.url_type, style=theme.form.url_style) }}
{% endif %}
<br>
{{ item(class=theme.form.url_class, type=theme.form.url_type, style=theme.form.url_style) }}
{% endif %}

@ -1,34 +0,0 @@
<form method="POST" action="" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<fieldset class="form-group">
{% if itemList | length == 1 %}
<div class="col-md-3 rounded">
<div class="p-3 py-5">
{% include 'form.html' %}
</div>
</div>
{% else %}
{% for labelItems in itemList %}
<div class="col-md-3">
<div class="p-3 py-4">
{% for item in form %}
{% if item.id == 'submit' %}
{% elif item.id == 'csrf_token' %}
{% else %}
{% for label in labelItems %}
{% if label == item.name %}
{% include 'form/stringField.html' %}
{% include 'form/selectFieldVer.html' %}
{% include 'form/dateField.html' %}
{% include 'form/boolField.html' %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
</div>
</div>
{% endfor %}
{% endif %}
</fieldset>
<div>{% include 'form/submitField.html' %}</div>
</form>

@ -1,10 +0,0 @@
<form method="POST" action="" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<div>{% include 'form/stringFields.html' %}</div>
<div>{% include 'form/selectFields.html' %}</div>
<div>{% include 'form/dateFields.html' %}</div>
<div>{% include 'form/boolFields.html' %}</div>
</fieldset>
<div>{% include 'form/submitField.html' %}</div>
</form>

@ -9,6 +9,9 @@ light_orange = "#f9a36c"
orange = "#f26628"
yellow = "#f8cb66"
label_font_size = "14pt"
field_font_size = "14pt"
class maineTheme:
div_style = "background-color:" + yellow
@ -19,14 +22,16 @@ class form:
div_error_class = "invalid-feedback"
default_label_class = "col-form-label"
default_label_style = "color:" + orange + "; font-size: 14pt; font-weight: bold;"
default_error_class = "form-control form-control-lg is-invalid"
default_label_style = "color:" + orange + "; font-size: " + label_font_size + "; font-weight: bold;"
default_field_style = "color:" + black + "; font-size: " + field_font_size + "; background-color: " + white + ";"
default_error_class = "form-control is-invalid"
input_label_class = default_label_class
input_label_style = default_label_style
input_class = "form-control form-control-lg"
input_class = "form-control"
input_style = default_field_style
input_error_class = default_error_class
check_label_class = "form-check-label"
check_label_style = "input_label_style"
check_class = "form-check-input"
@ -34,29 +39,35 @@ class form:
file_label_class = default_label_class
file_label_style = default_label_style
file_class = input_class
file_style = default_field_style
file_type = "file"
file_error_class = default_error_class
url_label_class = default_label_class
url_label_style = default_label_style
url_class = input_class
url_style = default_field_style
url_default = "https://example.com/"
url_error_class = default_error_class
select_label_class = default_label_class
select_label_style = default_label_style
select_class = "btn btn-lg form-select"
select_style = "color:" + black + "; font-size: 14pt; background-color: " + white + ";"
submit_class = "btn btn-outline-info mb-2 mt-2"
submit_style = ""
integer_label_class = default_label_class
integer_label_style = default_label_style
integer_class = input_class
integer_style = default_field_style
date_label_class = default_label_class
date_label_style = default_label_style
date_class = ""
date_error_class = default_error_class
date_class = input_class
date_style = default_field_style
date_type = "date"
submit_class = "btn btn-outline-info mb-2 mt-2"
submit_style = ""
class menu:
menuDict = generate_blueprint_structure('minibase/blueprints')
@ -64,23 +75,29 @@ class menu:
{"menuName":"Company",
"sublinks": [
{"text": "List", "url": "company.list"},
{"text": "Presons", "url": "main.index"},
{"decoration": "line"},
{"text": "Create Company", "url": "main.index"},
{"text": "Create Person", "url": "main.index"},
{"text": "Add", "url": "company.add"},
{"decoration": "line"},
{"text": "Edit Company", "url": "main.index"},
{"text": "Edit Person", "url": "main.index"},
{"text": "Remove", "url": "main.index"},
],},
{"menuName":"Sensor",
"sublinks": [
{"text": "List", "url": "main.index"},
{"decoration": "line"},
{"text": "Add", "url": "main.index"},
{"decoration": "line"},
{"text": "Edit", "url": "main.index"},
],},
]
navbar_items_user = [
{"menuName": "Login", "url": "user.login", "show":"not_logged"},
{"menuName": "Register", "url": "user.register", "show":"not_logged"},
{"menuName": "Account", "url": "user.account", "show":"logged"},
{"menuName": "Logout", "url": "user.logout", "show":"logged"}
]
navbar_items_admin = [
{"menuName": "Admin",
"sublinks": [

@ -2,8 +2,9 @@ from minibase.app import db, create_app, bcrypt
from minibase.blueprints.user.models import Users, User_Roles
from minibase.blueprints.company.models import Companies, Company_types, Company_legal_entities, Industries, Company_relations, Company_status
from minibase.blueprints.main.models import Notes
from minibase.blueprints.sensor.models import nbiotDevice, nbiotDeviceArea, nbiotDeviceType, nbiotDeviceStatus
import csv
import subprocess
import os
app = create_app()
app.app_context().push()
@ -46,6 +47,10 @@ def initDatabase():
uploadCsvOnlyName(Industries)
uploadCsvOnlyName(User_Roles)
uploadCsvOnlyName(Notes)
uploadCsvOnlyName(nbiotDeviceStatus)
uploadCsvOnlyName(nbiotDeviceType)
uploadCsvOnlyName(nbiotDeviceArea)
uploadCsvOnlyName(nbiotDevice)
hashed_pw = bcrypt.generate_password_hash('pass').decode('utf-8')
user = Users(username="Admin", email_account="admin@kynsight.com", email_comm="admin@kynsight.com", password=hashed_pw, role_id=1)
@ -68,3 +73,4 @@ if __name__ == '__main__':
users=Users.query.all()
roles=User_Roles.query.all()
notes=Notes.query.all()
os.system("sqlite3 instance/test.db < init/static/countries/dump1.sql")

Loading…
Cancel
Save