diff --git a/transporte/__init__.py b/transporte/__init__.py index 024cc120ed21545c5fb839044d01f138ecc4e951..2f741b81fa56cd696bdddf5e4948f1d5a10ecd45 100644 --- a/transporte/__init__.py +++ b/transporte/__init__.py @@ -1 +1,24 @@ -from .transporte import app \ No newline at end of file +from flask import Flask +from flask_sqlalchemy import SQLAlchemy +from flask_mail import Mail + +from flask_login import LoginManager + +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..6e986ca4fa705456d8fa9655d4ca92da8fc677c9 100644 --- a/transporte/models.py +++ b/transporte/models.py @@ -1,13 +1,12 @@ -from .transporte import app, db, mail - -from flask import flash, Markup, url_for - +from flask import Markup, flash, url_for from flask_login import UserMixin from flask_mail import Message - -from itsdangerous import URLSafeTimedSerializer as Serializer +from flask import current_app as app from itsdangerous import BadSignature, SignatureExpired +from itsdangerous import URLSafeTimedSerializer as Serializer + +from . import db, mail class User(UserMixin, db.Model): @@ -56,12 +55,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..4e5ddc2330b80edb6b95649cfd26b23ff4bd0cd8 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 +from . import create_app -app = Flask(__name__) - -app.config.from_pyfile('config.cfg') +app = create_app() -db = SQLAlchemy(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 40a12de8c2ed82c941353a994bcd9ca239d94436..8e2bef6ba1aabf25573d0680d7883ac7a50def2b 100644 --- a/transporte/views.py +++ b/transporte/views.py @@ -1,23 +1,22 @@ -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, escape, flash, redirect, render_template, + request, send_from_directory, url_for) +from flask_login import current_user, login_required, login_user, logout_user +from jinja2 import evalcontextfilter from werkzeug.utils import secure_filename +from flask import current_app as app + +from flask_wtf import FlaskForm +from . import db, login_manager +from .forms import LoginForm, TransportForm, TransportFilterForm, AddressForm, RoleForm, VehicleTypes, Roles +from .models import User, Address, Transport, File +from .zammad_integration import close_ticket, update_ticket @app.route('/') @@ -34,16 +33,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 @@ -61,7 +60,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)) @@ -131,10 +130,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() @@ -168,7 +167,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() @@ -181,7 +180,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() @@ -242,9 +241,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) @@ -310,7 +309,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 df7018fc7a597f0d83371db8843cf1fe6720b79b..e0e5324cc99d2114d4e916681abd1fb4738678ca 100644 --- a/transporte/zammad_integration.py +++ b/transporte/zammad_integration.py @@ -1,7 +1,9 @@ -from zammad_py import ZammadAPI +from datetime import datetime + from flask import render_template +from zammad_py import ZammadAPI + from .transporte import app -from datetime import datetime def close_ticket(transport, reason): @@ -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: