Add typing to general app files
This commit is contained in:
parent
b7fa92a22a
commit
15794b06b7
8 changed files with 47 additions and 35 deletions
|
@ -1,12 +1,14 @@
|
|||
import flask_login as login
|
||||
from flask import Flask
|
||||
from flask_admin import Admin
|
||||
from flask_admin.contrib.sqla import ModelView
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
|
||||
from models import Location, Order, OrderItem, Product, User
|
||||
|
||||
|
||||
class ModelBaseView(ModelView):
|
||||
def is_accessible(self):
|
||||
def is_accessible(self) -> bool:
|
||||
if login.current_user.is_anonymous():
|
||||
return False
|
||||
|
||||
|
@ -29,7 +31,7 @@ class LocationAdminModel(ModelBaseView):
|
|||
form_columns = ("name", "address", "website", "telephone")
|
||||
|
||||
|
||||
def init_admin(app, db):
|
||||
def init_admin(app: Flask, db: SQLAlchemy) -> None:
|
||||
admin = Admin(app, name="Haldis", url="/admin", template_mode="bootstrap3")
|
||||
|
||||
admin.add_view(UserAdminModel(User, db.session))
|
||||
|
|
21
app/app.py
21
app/app.py
|
@ -1,4 +1,5 @@
|
|||
import logging
|
||||
import typing
|
||||
from datetime import datetime
|
||||
from logging.handlers import TimedRotatingFileHandler
|
||||
|
||||
|
@ -19,7 +20,7 @@ from utils import euro_string
|
|||
from zeus import init_oauth
|
||||
|
||||
|
||||
def create_app():
|
||||
def create_app() -> Manager:
|
||||
app = Flask(__name__)
|
||||
|
||||
# Load the config file
|
||||
|
@ -34,7 +35,7 @@ def create_app():
|
|||
return manager
|
||||
|
||||
|
||||
def register_plugins(app, debug: bool):
|
||||
def register_plugins(app: Flask, debug: bool) -> Manager:
|
||||
# Register Airbrake and enable the logrotation
|
||||
if not app.debug:
|
||||
timedFileHandler = TimedRotatingFileHandler(
|
||||
|
@ -96,17 +97,17 @@ def register_plugins(app, debug: bool):
|
|||
return manager
|
||||
|
||||
|
||||
def add_handlers(app):
|
||||
def add_handlers(app: Flask) -> None:
|
||||
@app.errorhandler(404)
|
||||
def handle404(e):
|
||||
def handle404(e) -> typing.Tuple[str, int]:
|
||||
return render_template("errors/404.html"), 404
|
||||
|
||||
@app.errorhandler(401)
|
||||
def handle401(e):
|
||||
def handle401(e) -> typing.Tuple[str, int]:
|
||||
return render_template("errors/401.html"), 401
|
||||
|
||||
|
||||
def add_routes(application):
|
||||
def add_routes(application: Flask) -> None:
|
||||
# import views # TODO convert to blueprint
|
||||
# import views.stats # TODO convert to blueprint
|
||||
|
||||
|
@ -127,9 +128,9 @@ def add_routes(application):
|
|||
application.register_blueprint(debug_bp, url_prefix="/debug")
|
||||
|
||||
|
||||
def add_template_filters(app):
|
||||
def add_template_filters(app: Flask) -> None:
|
||||
@app.template_filter("countdown")
|
||||
def countdown(value, only_positive=True, show_text=True):
|
||||
def countdown(value, only_positive: bool = True, show_text: bool = True) -> str:
|
||||
delta = value - datetime.now()
|
||||
if delta.total_seconds() < 0 and only_positive:
|
||||
return "closed"
|
||||
|
@ -141,11 +142,11 @@ def add_template_filters(app):
|
|||
return time
|
||||
|
||||
@app.template_filter("year")
|
||||
def current_year(value):
|
||||
def current_year(value: typing.Any) -> str:
|
||||
return str(datetime.now().year)
|
||||
|
||||
@app.template_filter("euro")
|
||||
def euro(value):
|
||||
def euro(value: int) -> None:
|
||||
euro_string(value)
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import typing
|
||||
|
||||
from sqlalchemy.sql import desc, func
|
||||
|
||||
from models import Location, Order, OrderItem, Product, User
|
||||
|
@ -42,7 +44,7 @@ class FatOrderItem(OrderItem, FatModel):
|
|||
|
||||
class FatProduct(Product, FatModel):
|
||||
@classmethod
|
||||
def top4(cls):
|
||||
def top4(cls) -> None:
|
||||
top4 = (
|
||||
OrderItem.query.join(Product)
|
||||
.join(Location)
|
||||
|
|
11
app/forms.py
11
app/forms.py
|
@ -3,7 +3,8 @@ from datetime import datetime, timedelta
|
|||
from flask import session
|
||||
from flask_login import current_user
|
||||
from flask_wtf import FlaskForm as Form
|
||||
from wtforms import DateTimeField, SelectField, StringField, SubmitField, validators
|
||||
from wtforms import (DateTimeField, SelectField, StringField, SubmitField,
|
||||
validators)
|
||||
|
||||
from models import Location, User
|
||||
from utils import euro_string
|
||||
|
@ -20,7 +21,7 @@ class OrderForm(Form):
|
|||
stoptime = DateTimeField("Stoptime", format="%d-%m-%Y %H:%M")
|
||||
submit_button = SubmitField("Submit")
|
||||
|
||||
def populate(self):
|
||||
def populate(self) -> None:
|
||||
if current_user.is_admin():
|
||||
self.courrier_id.choices = [(0, None)] + [
|
||||
(u.id, u.username) for u in User.query.order_by("username")
|
||||
|
@ -42,7 +43,7 @@ class OrderItemForm(Form):
|
|||
extra = StringField("Extra")
|
||||
submit_button = SubmitField("Submit")
|
||||
|
||||
def populate(self, location):
|
||||
def populate(self, location: Location) -> None:
|
||||
self.product_id.choices = [
|
||||
(i.id, (i.name + ": " + euro_string(i.price))) for i in location.products
|
||||
]
|
||||
|
@ -51,12 +52,12 @@ class OrderItemForm(Form):
|
|||
class AnonOrderItemForm(OrderItemForm):
|
||||
name = StringField("Name", validators=[validators.required()])
|
||||
|
||||
def populate(self, location):
|
||||
def populate(self, location: Location) -> None:
|
||||
OrderItemForm.populate(self, location)
|
||||
if self.name.data is None:
|
||||
self.name.data = session.get("anon_name", None)
|
||||
|
||||
def validate(self):
|
||||
def validate(self) -> bool:
|
||||
rv = OrderForm.validate(self)
|
||||
if not rv:
|
||||
return False
|
||||
|
|
12
app/login.py
12
app/login.py
|
@ -1,6 +1,6 @@
|
|||
from flask import abort, Blueprint
|
||||
from flask import redirect, session, url_for
|
||||
from flask import Blueprint, abort, redirect, session, url_for
|
||||
from flask_login import current_user, logout_user
|
||||
from werkzeug.wrappers import Response
|
||||
|
||||
from models import User
|
||||
from zeus import zeus_login
|
||||
|
@ -8,9 +8,9 @@ from zeus import zeus_login
|
|||
auth_bp = Blueprint("auth_bp", __name__)
|
||||
|
||||
|
||||
def init_login(app):
|
||||
def init_login(app) -> None:
|
||||
@app.login_manager.user_loader
|
||||
def load_user(userid):
|
||||
def load_user(userid) -> User:
|
||||
return User.query.filter_by(id=userid).first()
|
||||
|
||||
|
||||
|
@ -20,13 +20,13 @@ def login():
|
|||
|
||||
|
||||
@auth_bp.route("/logout")
|
||||
def logout():
|
||||
def logout() -> Response:
|
||||
if "zeus_token" in session:
|
||||
session.pop("zeus_token", None)
|
||||
logout_user()
|
||||
return redirect(url_for("general_bp.home"))
|
||||
|
||||
|
||||
def before_request():
|
||||
def before_request() -> None:
|
||||
if current_user.is_anonymous() or not current_user.is_allowed():
|
||||
abort(401)
|
||||
|
|
|
@ -7,7 +7,7 @@ from flask import current_app as app
|
|||
from flask import url_for
|
||||
|
||||
|
||||
def post_order_to_webhook(order_item):
|
||||
def post_order_to_webhook(order_item) -> None:
|
||||
message = ""
|
||||
if order_item.courrier is not None:
|
||||
message = "<!channel|@channel> {3} is going to {1}, order <{0}|here>! Deadline in {2} minutes!".format(
|
||||
|
@ -27,14 +27,14 @@ def post_order_to_webhook(order_item):
|
|||
|
||||
|
||||
class WebhookSenderThread(Thread):
|
||||
def __init__(self, message):
|
||||
def __init__(self, message: str) -> None:
|
||||
super(WebhookSenderThread, self).__init__()
|
||||
self.message = message
|
||||
|
||||
def run(self):
|
||||
def run(self) -> None:
|
||||
self.slack_webhook()
|
||||
|
||||
def slack_webhook(self):
|
||||
def slack_webhook(self) -> None:
|
||||
js = json.dumps({"text": self.message})
|
||||
url = app.config["SLACK_WEBHOOK"]
|
||||
if len(url) > 0:
|
||||
|
@ -43,7 +43,7 @@ class WebhookSenderThread(Thread):
|
|||
app.logger.info(str(js))
|
||||
|
||||
|
||||
def remaining_minutes(value):
|
||||
def remaining_minutes(value) -> str:
|
||||
delta = value - datetime.now()
|
||||
if delta.total_seconds() < 0:
|
||||
return "0"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
def euro_string(value):
|
||||
def euro_string(value: int) -> str:
|
||||
"""
|
||||
Convert cents to string formatted euro
|
||||
"""
|
||||
|
|
16
app/zeus.py
16
app/zeus.py
|
@ -1,6 +1,10 @@
|
|||
from flask import current_app, flash, redirect, request, session, url_for, Blueprint
|
||||
import typing
|
||||
|
||||
from flask import (Blueprint, current_app, flash, redirect, request, session,
|
||||
url_for)
|
||||
from flask_login import login_user
|
||||
from flask_oauthlib.client import OAuthException, OAuth
|
||||
from flask_oauthlib.client import OAuth, OAuthException
|
||||
from werkzeug.wrappers import Response
|
||||
|
||||
from models import User, db
|
||||
|
||||
|
@ -14,7 +18,9 @@ def zeus_login():
|
|||
|
||||
|
||||
@oauth_bp.route("/login/zeus/authorized")
|
||||
def authorized():
|
||||
def authorized() -> typing.Any:
|
||||
# type is 'typing.Union[str, Response]', but this errors due to
|
||||
# https://github.com/python/mypy/issues/7187
|
||||
resp = current_app.zeus.authorized_response()
|
||||
if resp is None:
|
||||
return "Access denied: reason=%s error=%s" % (
|
||||
|
@ -60,12 +66,12 @@ def init_oauth(app):
|
|||
return zeus
|
||||
|
||||
|
||||
def login_and_redirect_user(user):
|
||||
def login_and_redirect_user(user) -> Response:
|
||||
login_user(user)
|
||||
return redirect(url_for("general_bp.home"))
|
||||
|
||||
|
||||
def create_user(username):
|
||||
def create_user(username) -> User:
|
||||
user = User()
|
||||
user.configure(username, False, 1)
|
||||
db.session.add(user)
|
||||
|
|
Loading…
Reference in a new issue