diff --git a/transporte/__init__.py b/transporte/__init__.py index 024cc120ed21545c5fb839044d01f138ecc4e951..463f27ba6bf135527d412e89b1f238442ae5e761 100644 --- a/transporte/__init__.py +++ b/transporte/__init__.py @@ -1 +1,23 @@ -from .transporte import app \ No newline at end of file +from flask import Flask +from flask_login import LoginManager +from flask_mail import Mail +from flask_sqlalchemy import SQLAlchemy + +db = SQLAlchemy() +mail = Mail() +login_manager = LoginManager() + + +def create_app(): + """Construct the core application.""" + app = Flask(__name__) + app.config.from_pyfile('config.cfg') + db.init_app(app) + mail.init_app(app) + login_manager.init_app(app) + + with app.app_context(): + from . import views # noqa: F401 + db.create_all() + + return app diff --git a/transporte/forms.py b/transporte/forms.py index 6c91373f28dca4e38d49a50302dd8a27d824a0b9..5385fb0660a87fcfff5d603247ec8955f9a97a99 100644 --- a/transporte/forms.py +++ b/transporte/forms.py @@ -3,15 +3,12 @@ import datetime from flask_wtf import FlaskForm from flask_wtf.file import FileField -from wtforms import StringField, SelectField, TextAreaField, SubmitField +from wtforms import SelectField, StringField, SubmitField, TextAreaField from wtforms.fields import BooleanField from wtforms.fields.html5 import TimeField -from wtforms.validators import * - +from wtforms.validators import DataRequired, Email, Optional # DateField from wtforms_components supports min/max depending on DateRange -from wtforms_components import DateField -from wtforms_components import DateRange - +from wtforms_components import DateField, DateRange VehicleTypes = { 'car': 'Car', diff --git a/transporte/models.py b/transporte/models.py index 597a95ce07006f76dd23c8954440a0cde3314657..aad1ada226521585293b2f35655825bfd9d07854 100644 --- a/transporte/models.py +++ b/transporte/models.py @@ -1,13 +1,13 @@ -from .transporte import app, db, mail - -from flask import flash, Markup, url_for - +from flask import Markup +from flask import current_app as app +from flask import flash, url_for from flask_login import UserMixin from flask_mail import Message - -from itsdangerous import URLSafeTimedSerializer as Serializer from itsdangerous import BadSignature, SignatureExpired +from itsdangerous import URLSafeTimedSerializer as Serializer + +from . import db, mail class User(UserMixin, db.Model): @@ -56,12 +56,14 @@ class User(UserMixin, db.Model): def __repr__(self): return '<User {}>'.format(self.login) + class Address(db.Model): id = db.Column(db.Integer, primary_key=True, autoincrement=True) public = db.Column(db.Boolean, default=False, nullable=False) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) address = db.Column(db.Text, nullable=False) + class Transport(db.Model): id = db.Column(db.Integer, primary_key=True, autoincrement=True) ticket_id = db.Column(db.Integer) diff --git a/transporte/transporte.py b/transporte/transporte.py index fc1977217169d023ba001cdd3ada8945cbec477d..7f44e5c1a654325c6c233978dd8b3763b69907a1 100644 --- a/transporte/transporte.py +++ b/transporte/transporte.py @@ -1,38 +1,17 @@ #! /usr/bin/env python -from flask import Flask - -from flask_sqlalchemy import SQLAlchemy - -from flask_mail import Mail - -from flask_login import LoginManager - -from flask_qrcode import QRcode - from flask_limiter import Limiter from flask_limiter.util import get_remote_address +from flask_qrcode import QRcode -app = Flask(__name__) - -app.config.from_pyfile('config.cfg') +from . import create_app -db = SQLAlchemy(app) +app = create_app() limiter = Limiter(app, key_func=get_remote_address) -mail = Mail(app) - QRcode(app) -login_manager = LoginManager() -login_manager.init_app(app) -login_manager.login_view = 'login' - -from .views import * - -login_manager.user_loader(load_user) - if app.config['DEBUG']: import logging import http.client diff --git a/transporte/views.py b/transporte/views.py index f0f86623cd5dda69c19a950377e686535e247241..23505071ba2a9690faa97c55ac901c129022738b 100644 --- a/transporte/views.py +++ b/transporte/views.py @@ -1,24 +1,25 @@ -from .transporte import app, db, login_manager -from .models import * -from .forms import * - import datetime -from flask import request, g, render_template, session, url_for, redirect, flash, Markup, escape, \ - send_from_directory, abort -from jinja2 import evalcontextfilter - -from email_validator import validate_email - -from flask_login import login_user, logout_user, login_required, current_user -from .zammad_integration import update_ticket, close_ticket - -import babel -import re import os +import re +import babel from dateutil import parser +from email_validator import validate_email +from flask import Markup, abort +from flask import current_app as app +from flask import (escape, flash, redirect, render_template, request, + send_from_directory, url_for) +from flask_login import current_user, login_required, login_user, logout_user +from flask_wtf import FlaskForm +from jinja2 import evalcontextfilter from werkzeug.utils import secure_filename +from . import db, login_manager +from .forms import (AddressForm, LoginForm, RoleForm, Roles, + TransportFilterForm, TransportForm, VehicleTypes) +from .models import Address, File, Transport, User +from .zammad_integration import close_ticket, update_ticket + @app.route('/') @login_required @@ -34,16 +35,16 @@ def index(): ), ) - query = Transport.query.filter(Transport.cancelled == False) + query = Transport.query.filter(not Transport.cancelled) try: todo[0]['progress'] = 100 / query.filter(Transport.date == datetime.date.today()).count() * query.filter( - Transport.date == datetime.date.today()).filter(Transport.done == True).count() + Transport.date == datetime.date.today()).filter(Transport.done).count() except ZeroDivisionError: pass try: - todo[1]['progress'] = 100 / query.count() * query.filter(Transport.done == True).count() + todo[1]['progress'] = 100 / query.count() * query.filter(Transport.done).count() except ZeroDivisionError: pass @@ -72,7 +73,7 @@ def login(): try: if not app.config['DEBUG']: v = validate_email(email) - email = v['email'] # replace with normalized form + email = v['email'] # replace with normalized form except Exception as e: loginform.login.errors.append(str(e)) @@ -155,10 +156,10 @@ def edit_transport(id=None): db.session.add(transport) db.session.commit() - ## - ## if ticket is new, update object with zammad ticket id - ## - if transport.ticket_id == None: + # + # if ticket is new, update object with zammad ticket id + # + if transport.ticket_id is None: transport.ticket_id = update_ticket(transport) db.session.add(transport) db.session.commit() @@ -192,7 +193,7 @@ def edit_transport(id=None): addresslist = Address.query if current_user.role not in ['admin', 'helpdesk']: - addresslist = addresslist.filter(Address.public == True) + addresslist = addresslist.filter(Address.public) addresslist = addresslist.all() @@ -205,7 +206,7 @@ def edit_transport(id=None): def list_transports(): transportlist = Transport.query - if not current_user.role in ['helpdesk', 'admin']: + if current_user.role not in ['helpdesk', 'admin']: transportlist = transportlist.filter(Transport.user_id == current_user.id) dates = transportlist.with_entities(Transport.date).distinct().order_by(Transport.date).all() @@ -266,9 +267,9 @@ def mark_transport(mark, id=None): elif mark == 'cancelled': transport.cancelled = True - ## - ## close ticket - ## + # + # close ticket + # if transport.ticket_id: close_ticket(transport, mark) @@ -334,7 +335,7 @@ def edit_address(id=None): def delete_address(id): address = Address.query.get(id) - if address is None or current_user.id is not address.user_id or not current_user.role in ['admin']: + if address is None or current_user.id is not address.user_id or current_user.role not in ['admin']: abort(404) form = FlaskForm() diff --git a/transporte/zammad_integration.py b/transporte/zammad_integration.py index 1ccce4c4327cb311f4ff87c388d6699da250822d..5c3ea46f11d8c24781f2f901918260dfa79858aa 100644 --- a/transporte/zammad_integration.py +++ b/transporte/zammad_integration.py @@ -1,8 +1,10 @@ -from zammad_py import ZammadAPI -from flask import render_template -from .transporte import app from datetime import datetime +from flask import render_template +from zammad_py import ZammadAPI + +from flask import current_app as app + def close_ticket(transport, reason): client = ZammadAPI(username=app.config['ZAMMAD_USER'], password=app.config['ZAMMAD_PASS'], @@ -10,9 +12,9 @@ def close_ticket(transport, reason): messagebody = reason - ## - ## if new helpdesk user is closing a ticket, we need to create the user in the ticket system - ## + # + # if new helpdesk user is closing a ticket, we need to create the user in the ticket system + # zammad_search_result = client.user.search({'query': transport.user.login}) if zammad_search_result: zammad_user = zammad_search_result[0] @@ -40,9 +42,9 @@ def update_ticket(transport): client = ZammadAPI(username=app.config['ZAMMAD_USER'], password=app.config['ZAMMAD_PASS'], host=app.config['ZAMMAD_HOST'], is_secure=app.config['ZAMMAD_SECURE']) - ## - ## Create user if not exists - ## + # + # Create user if not exists + # zammad_search_result = client.user.search({'query': transport.user.login}) if zammad_search_result: zammad_user = zammad_search_result[0] @@ -65,11 +67,10 @@ def update_ticket(transport): 'pending_time': '{}Z'.format(datetime.utcnow().isoformat()), } - - ## - ## Create a new ticket, if the transport has no ticket_id in the db - ## - if transport.ticket_id == None: + # + # Create a new ticket, if the transport has no ticket_id in the db + # + if transport.ticket_id is None: transport.ticket_id = client.ticket.create(ticketTemplate)['id'] else: