Initial commit

master
informatic 2020-03-26 10:09:44 +01:00
parent 0477400a74
commit a5f7dc54dd
13 changed files with 7461 additions and 3 deletions

View File

@ -1,5 +1,5 @@
import flask
from formity.extensions import db, migrate, admin
from formity.extensions import db, migrate, admin, auth, babel
def create_app():
app = flask.Flask(
@ -14,6 +14,8 @@ def create_app():
db.init_app(app)
migrate.init_app(app, db)
admin.init_app(app)
babel.init_app(app)
auth.init_app(app)
import formity.admin
import formity.views

View File

@ -0,0 +1,5 @@
from formity.extensions import admin, db, ModelView
from formity.models import FaceshieldRequest
admin.add_view(ModelView(FaceshieldRequest, db.session))

View File

@ -2,6 +2,8 @@ from flask import current_app
import flask_sqlalchemy
import flask_migrate
import flask_admin
import flask_babel
import spaceauth
from flask_admin.contrib.sqla import ModelView as BaseModelView
from flask_login import current_user
@ -26,3 +28,5 @@ class ModelView(SecurityMixin, BaseModelView):
db = flask_sqlalchemy.SQLAlchemy()
migrate = flask_migrate.Migrate()
admin = flask_admin.Admin(template_mode='bootstrap3', index_view=IndexView())
babel = flask_babel.Babel()
auth = spaceauth.SpaceAuth()

15
formity/forms.py Normal file
View File

@ -0,0 +1,15 @@
from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField, IntegerField, validators
class FaceshieldRequestForm(FlaskForm):
entity_info = TextAreaField('Dane placówki', validators=[validators.DataRequired()])
full_name = StringField('Imię i nazwisko', validators=[validators.DataRequired()])
phone_number = StringField('Numer telefonu', validators=[validators.DataRequired()])
email = StringField('Adres e-mail', validators=[validators.DataRequired(), validators.Email()])
extra = TextAreaField('Dodatkowe informacje')
faceshield_front_required = IntegerField('Pilnie potrzebna minimalna ilość samych szybek do przyłbic', validators=[validators.DataRequired()])
faceshield_model = StringField('Model przyłbicy', validators=[validators.DataRequired()])
faceshield_full_required = IntegerField('Pilnie potrzebna minimalna ilość pełnych przyłbic', validators=[validators.DataRequired()])

View File

@ -1 +1,21 @@
from formity.extensions import db
from datetime import datetime
class FaceshieldRequest(db.Model):
id = db.Column(db.Integer, primary_key=True)
entity_info = db.Column(db.String)
full_name = db.Column(db.String)
phone_number = db.Column(db.String)
email = db.Column(db.String)
extra = db.Column(db.String)
faceshield_front_required = db.Column(db.Integer)
faceshield_model = db.Column(db.String)
faceshield_full_required = db.Column(db.Integer)
created = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
updated = db.Column(db.DateTime, default=datetime.utcnow, nullable=False,
onupdate=datetime.utcnow)

View File

@ -6,3 +6,8 @@ FLASK_ADMIN_FLUID_LAYOUT = True
SECRET_KEY = env.str('SECRET_KEY', default='randomstring')
SQLALCHEMY_DATABASE_URI = env.str('DATABASE_URI', default='postgresql+psycopg2://postgres:secret@postgres')
SPACEAUTH_CONSUMER_KEY = env.str('SPACEAUTH_CONSUMER_KEY', default='')
SPACEAUTH_CONSUMER_SECRET = env.str('SPACEAUTH_CONSUMER_SECRET', default='')
BABEL_DEFAULT_LOCALE = 'pl'

View File

@ -1,3 +1,20 @@
from flask import Blueprint
from flask import Blueprint, render_template, flash
from formity.extensions import db
from formity.models import FaceshieldRequest
from formity.forms import FaceshieldRequestForm
bp = Blueprint('main', __name__)
@bp.route('/', methods=['GET', 'POST'])
def index():
form = FaceshieldRequestForm()
if form.validate_on_submit():
db.session.add(FaceshieldRequest(**{
k: v
for k, v in form.data.items()
if hasattr(FaceshieldRequest, k)
}))
db.session.commit()
flash('Zapytanie zostało wysłane.', 'success')
return render_template('index.html', form=form)

View File

@ -0,0 +1,41 @@
"""Initial migration
Revision ID: 1379dfa9e1d4
Revises:
Create Date: 2020-03-26 08:21:09.279323
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '1379dfa9e1d4'
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('faceshield_request',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('entity_info', sa.String(), nullable=True),
sa.Column('full_name', sa.String(), nullable=True),
sa.Column('phone_number', sa.String(), nullable=True),
sa.Column('email', sa.String(), nullable=True),
sa.Column('extra', sa.String(), nullable=True),
sa.Column('faceshield_front_required', sa.Integer(), nullable=True),
sa.Column('faceshield_model', sa.String(), nullable=True),
sa.Column('faceshield_full_required', sa.Integer(), nullable=True),
sa.Column('created', sa.DateTime(), nullable=False),
sa.Column('updated', sa.DateTime(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('faceshield_request')
# ### end Alembic commands ###

View File

@ -1,4 +1,5 @@
alembic==1.4.2
Babel==2.8.0
blinker==1.4
certifi==2019.11.28
chardet==3.0.4
@ -6,11 +7,13 @@ click==7.1.1
environs==7.3.1
Flask==1.1.1
Flask-Admin==1.5.5
Flask-Babel==1.0.0
Flask-Login==0.5.0
Flask-Migrate==2.5.3
Flask-OAuthlib==0.9.5
git+https://code.hackerspace.pl/informatic/flask-spaceauth#egg=Flask-SpaceAuth
Flask-SQLAlchemy==2.4.1
Flask-WTF==0.14.3
idna==2.9
itsdangerous==1.1.0
Jinja2==2.11.1
@ -21,10 +24,11 @@ oauthlib==2.1.0
python-dateutil==2.8.1
python-dotenv==0.12.0
python-editor==1.0.4
pytz==2019.3
requests==2.23.0
requests-oauthlib==1.3.0
six==1.14.0
SQLAlchemy==1.3.15
urllib3==1.25.8
Werkzeug==1.0.0
Werkzeug==0.16.1
WTForms==2.2.1

7173
static/css/bootstrap.css Normal file

File diff suppressed because it is too large Load Diff

99
templates/_helpers.html Normal file
View File

@ -0,0 +1,99 @@
{% macro format_currency(amount, color=True, precision=2) -%}
{%- if amount == None -%}
None
{%- else -%}
<span class="amount{% if color %}{% if amount < 0 %} amount-negative{% else %} amount-positive{% endif %}{% endif %}" data-original="{{ amount }}">
{{ format_currency_raw(amount, precision) }}
</span>
{%- endif %}
{%- endmacro %}
{% macro format_currency_raw(amount, precision=0) -%}
{{ ("%%.%sf" | format(precision) | format(amount/100)) }}SOG
{%- endmacro %}
{% macro render_field(field, prefix=None, suffix=None, layout=True, label=True) %}
{% if field.type == 'HiddenField' or field.type == 'CSRFTokenField' %}
{{ field(**kwargs) }}
{% else %}
{% if layout %}
<div class="form-group{% if field.errors %} has-error{% endif %}">
{% if field.type == 'BooleanField' %}
<div class="col-md-3"></div>
{% elif label %}
{{ field.label(class_='col-md-3 control-label' + (' control-label-required' if field.flags.required else '')) }}
{% endif %}
<div class="col-md-9">
{% endif %}
{{ render_field_inner(field, prefix, suffix, label=label, **kwargs) }}
{% if layout %}
</div>
</div>
{% endif %}
{% endif %}
{% endmacro %}
{% macro render_field_inner(field, prefix=None, suffix=None, label=True, input_group_class='') %}
{% if field.type == 'BooleanField' %}<div class="checkbox"><label for="{{ field.id }}">{% endif %}
{% if prefix or suffix %}<div class="input-group {{ input_group_class }}">{% endif %}
{% if prefix %}<span class="input-group-addon">{{ prefix }}</span>{% endif %}
{% if field.type == 'BooleanField' %}
{{ field(**kwargs) }} {% if label %}{{ field.label.text }}{% endif %}
{% elif field.type == 'RadioField' %}
{{ field(**kwargs) }}
{% else %}
{{ field(class_='form-control '+kwargs.pop('class_', ''), **kwargs) }}
{% endif %}
{% if suffix %}<span class="input-group-addon">{{ suffix }}</span>{% endif %}
{% if prefix or suffix %}</div>{% endif %}
{% if field.description and label %}
<span class="help-block">{{ field.description }}</span>
{% endif %}
{% if field.errors %}
{% for error in field.errors %}
<span class="help-block">{{ error }}</span>
{% endfor %}
{% endif %}
{% if field.type == 'BooleanField' %}</label></div>{% endif %}
{% endmacro %}
{% macro render_submit(label='Submit', class_='btn btn-primary', layout=True) %}
{% if layout %}
<div class="form-group">
<div class="col-md-9 col-md-offset-3">
{% endif %}
<button type="submit" class="{{ class_ }}">{{ label }}</button>
{% if layout %}
</div>
</div>
{% endif %}
{% endmacro %}
{% macro render_pagination(pagination) %}
<ul class="pagination text-center">
{% if pagination.has_prev %}
<li><a href="{{ url_for_other_page(pagination.page - 1) }}">&laquo;</a></li>
{% else %}
<li class="disabled"><a>&laquo;</a></li>
{% endif %}
{%- for page in pagination.iter_pages() %}
{% if page %}
{% if page != pagination.page %}
<li><a href="{{ url_for_other_page(page) }}">{{ page }}</a></li>
{% else %}
<li class="active"><a href="{{ url_for_other_page(page) }}">{{ page }}</a></li>
{% endif %}
{% else %}
<li class="disabled"><a></a></li>
{% endif %}
{%- endfor %}
{% if pagination.has_next %}
<li><a href="{{ url_for_other_page(pagination.page + 1) }}">&raquo;</a></li>
{% else %}
<li class="disabled"><a>&raquo;</a></li>
{% endif %}
</ul>
{% endmacro %}

62
templates/base.html Normal file
View File

@ -0,0 +1,62 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>COVID-19 Relief</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap.css') }}" media="screen">
<style>
body {
margin-top: 80px;
}
h3 {
margin: 0;
padding: 0;
padding-bottom: 0.5em;
}
footer {
padding-bottom: 20px;
}
h3.page-header {
margin-top: 10px;
}
.input-group-btn .btn {
padding-bottom: 8px;
}
.placeholder {
text-align: center;
opacity: 0.5;
font-style: italic;
}
.vend-item code {
word-wrap: break-word;
}
.control-label-required::after {
content: ' *';
color: red;
}
</style>
</head>
<body>
<div class="container">
{% with messages = get_flashed_messages(with_categories=true) %}
{% for category, message in messages %}
<div class="alert alert-{{category}}">{{ message }}</div>
{% endfor %}
{% endwith %}
{% block content %}{% endblock %}
<hr>
<footer class="row"><big>made by <a href="https://wiki.hackerspace.pl/people:informatic:start">inf</a></big></footer>
</div>
<script src="{{ url_for('static', filename='js/jquery-1.10.2.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/bootstrap.min.js') }}"></script>
{% block tail_js %}
{% endblock %}
</body>
</html>

11
templates/index.html Normal file
View File

@ -0,0 +1,11 @@
{% extends "base.html" %}
{% from "_helpers.html" import render_field, render_submit %}
{% block content %}
<form action="" method="POST" class="form-horizontal">
{% for field in form %}
{{ render_field(field) }}
{% endfor %}
{{ render_submit() }}
</form>
{% endblock %}