Initial commit
parent
0477400a74
commit
a5f7dc54dd
|
@ -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
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
from formity.extensions import admin, db, ModelView
|
||||
from formity.models import FaceshieldRequest
|
||||
|
||||
|
||||
admin.add_view(ModelView(FaceshieldRequest, db.session))
|
|
@ -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()
|
||||
|
|
|
@ -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()])
|
|
@ -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)
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 ###
|
|
@ -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
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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) }}">«</a></li>
|
||||
{% else %}
|
||||
<li class="disabled"><a>«</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) }}">»</a></li>
|
||||
{% else %}
|
||||
<li class="disabled"><a>»</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endmacro %}
|
|
@ -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>
|
|
@ -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 %}
|
Loading…
Reference in New Issue