Compare commits
12 Commits
Kilian
...
prepare202
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f7c36a804 | |||
| 3bfc2fc182 | |||
| 802af2418a | |||
| cd9fc4755e | |||
| 158c419747 | |||
| 79e5fdf56b | |||
| a9338805e2 | |||
| 7f82a288da | |||
| 8728d3028b | |||
| bc7e1591bd | |||
| 673b671ab8 | |||
| 578b2c15d8 |
@@ -6,7 +6,6 @@ from flask_sqlalchemy import SQLAlchemy
|
|||||||
import os
|
import os
|
||||||
from config import config
|
from config import config
|
||||||
from flask_security.forms import LoginForm
|
from flask_security.forms import LoginForm
|
||||||
from flask_limiter import Limiter
|
|
||||||
from flask_limiter.util import get_remote_address
|
from flask_limiter.util import get_remote_address
|
||||||
|
|
||||||
from .forms import *
|
from .forms import *
|
||||||
@@ -15,13 +14,6 @@ from .forms import *
|
|||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config.from_object(config[os.getenv('FLASK_CONFIG') or 'default'])
|
app.config.from_object(config[os.getenv('FLASK_CONFIG') or 'default'])
|
||||||
|
|
||||||
# applies to all routes, so choose limits wisely!
|
|
||||||
limiter = Limiter(
|
|
||||||
app,
|
|
||||||
key_func=get_remote_address,
|
|
||||||
# default_limits=["500 per second"]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@app.errorhandler(429)
|
@app.errorhandler(429)
|
||||||
def ratelimit_handler(e):
|
def ratelimit_handler(e):
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from .checks import *
|
|||||||
|
|
||||||
|
|
||||||
class CreateServiceForm(FlaskForm):
|
class CreateServiceForm(FlaskForm):
|
||||||
date = DateField('Date of Pitstop')
|
date = DateField('Date of Service')
|
||||||
odometer = IntegerField('Odometer (km)', validators=[odometer_date_check])
|
odometer = IntegerField('Odometer (km)', validators=[odometer_date_check])
|
||||||
costs = DecimalField('Costs (€, overall)', places=2, validators=[costs_check])
|
costs = DecimalField('Costs (€, overall)', places=2, validators=[costs_check])
|
||||||
description = TextAreaField('Description', validators=[Length(1, 4096)])
|
description = TextAreaField('Description', validators=[Length(1, 4096)])
|
||||||
@@ -72,4 +72,4 @@ class EditServiceForm(FlaskForm):
|
|||||||
'litres': 'Litres must be higher than 0.01 L.',
|
'litres': 'Litres must be higher than 0.01 L.',
|
||||||
'costs': 'Costs must be higher than 0.01 €.'
|
'costs': 'Costs must be higher than 0.01 €.'
|
||||||
}
|
}
|
||||||
return messages
|
return messages
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from flask_security.core import current_user
|
|||||||
import requests
|
import requests
|
||||||
|
|
||||||
from ..entities import FillingStation
|
from ..entities import FillingStation
|
||||||
from .. import app, db, limiter
|
from .. import app, db
|
||||||
|
|
||||||
|
|
||||||
@app.route('/filling_stations/favourites/toggle/<fsid>')
|
@app.route('/filling_stations/favourites/toggle/<fsid>')
|
||||||
@@ -24,7 +24,6 @@ def add_favourite_filling_stations(fsid):
|
|||||||
|
|
||||||
@app.route('/filling_stations', methods=['GET'])
|
@app.route('/filling_stations', methods=['GET'])
|
||||||
@login_required
|
@login_required
|
||||||
@limiter.limit('1 per second')
|
|
||||||
def query_filling_stations():
|
def query_filling_stations():
|
||||||
api_key = app.config['TANKERKOENIG_API_KEY']
|
api_key = app.config['TANKERKOENIG_API_KEY']
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ from ..tools import (
|
|||||||
db_log_delete,
|
db_log_delete,
|
||||||
get_event_line_for_vehicle,
|
get_event_line_for_vehicle,
|
||||||
get_latest_pitstop_for_vehicle,
|
get_latest_pitstop_for_vehicle,
|
||||||
|
get_users_active_vehicle,
|
||||||
)
|
)
|
||||||
from .. import app, db
|
from .. import app, db
|
||||||
|
|
||||||
|
|||||||
@@ -164,6 +164,7 @@
|
|||||||
<ul id="consumable_{{vehicle.id}}_{{consumable.id}}_tabs" class="nav nav-tabs" data-tabs="tabs">
|
<ul id="consumable_{{vehicle.id}}_{{consumable.id}}_tabs" class="nav nav-tabs" data-tabs="tabs">
|
||||||
{{ nav_tab(vehicle.id|string + '_' + consumable.id|string + '_consumption', 'Consumption', true) }}
|
{{ nav_tab(vehicle.id|string + '_' + consumable.id|string + '_consumption', 'Consumption', true) }}
|
||||||
{{ nav_tab(vehicle.id|string + '_' + consumable.id|string + '_amount', 'Amount', false) }}
|
{{ nav_tab(vehicle.id|string + '_' + consumable.id|string + '_amount', 'Amount', false) }}
|
||||||
|
{{ nav_tab(vehicle.id|string + '_' + consumable.id|string + '_price', 'Price', false) }}
|
||||||
</ul>
|
</ul>
|
||||||
<div id="consumable_{{vehicle.id}}_{{consumable.id}}_content" class="tab-content ">
|
<div id="consumable_{{vehicle.id}}_{{consumable.id}}_content" class="tab-content ">
|
||||||
{{ tab_pane(
|
{{ tab_pane(
|
||||||
@@ -188,6 +189,17 @@
|
|||||||
false
|
false
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
|
{{ tab_pane(
|
||||||
|
vehicle.id|string + '_' + consumable.id|string + '_price',
|
||||||
|
chart(
|
||||||
|
consumable.price,
|
||||||
|
'ref_' + vehicle.id|string + '_' + consumable.id|string + '_price',
|
||||||
|
'€ / '+consumable.unit,
|
||||||
|
url_for('create_pit_stop_form', vid=vehicle.id, cid=consumable.id)
|
||||||
|
),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}}
|
||||||
</div>
|
</div>
|
||||||
{{ tab_script('vehicle_' + vehicle.id|string + '_' + consumable.id|string + '_tabs') }}
|
{{ tab_script('vehicle_' + vehicle.id|string + '_' + consumable.id|string + '_tabs') }}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class ConsumableStats:
|
|||||||
self.average_amount_used = 0
|
self.average_amount_used = 0
|
||||||
self.average_amount = []
|
self.average_amount = []
|
||||||
self.amounts = []
|
self.amounts = []
|
||||||
|
self.price = []
|
||||||
|
|
||||||
pitstops = [
|
pitstops = [
|
||||||
stop for stop in vehicle.pitstops if stop.consumable_id == consumable.id
|
stop for stop in vehicle.pitstops if stop.consumable_id == consumable.id
|
||||||
@@ -37,6 +38,9 @@ class ConsumableStats:
|
|||||||
for pitstop in pitstops:
|
for pitstop in pitstops:
|
||||||
self.overall_amount += pitstop.amount
|
self.overall_amount += pitstop.amount
|
||||||
self.amounts.append(StatsEvent(pitstop.date, pitstop.amount))
|
self.amounts.append(StatsEvent(pitstop.date, pitstop.amount))
|
||||||
|
# some pitstops seem to have lost their costs...
|
||||||
|
if pitstop.costs:
|
||||||
|
self.price.append(StatsEvent(pitstop.date, pitstop.costs/pitstop.amount))
|
||||||
self.average_amount_fuelled = self.overall_amount / pitstop_count
|
self.average_amount_fuelled = self.overall_amount / pitstop_count
|
||||||
if pitstop_count > 1:
|
if pitstop_count > 1:
|
||||||
overall_distance = (
|
overall_distance = (
|
||||||
@@ -204,7 +208,9 @@ def compute_lower_limits_for_new_pitstop(
|
|||||||
|
|
||||||
|
|
||||||
def pitstop_service_key(x):
|
def pitstop_service_key(x):
|
||||||
return x.date, x.odometer
|
# if the entry got no odometer (regular costs!) then we assume it's okay
|
||||||
|
# to have regular cost at a virtual odometer of 0 on that day.
|
||||||
|
return x.date, x.odometer or 0
|
||||||
|
|
||||||
|
|
||||||
def get_event_line_for_vehicle(vehicle):
|
def get_event_line_for_vehicle(vehicle):
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ class TestingConfig(Config):
|
|||||||
|
|
||||||
|
|
||||||
class ProductionConfig(Config):
|
class ProductionConfig(Config):
|
||||||
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:{h}@database/pitstops'.format(
|
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://pitstops:{h}@localhost/pitstops'.format(
|
||||||
h=os.environ.get('DATABASE_ENV_MYSQL_ROOT_PASSWORD'))
|
h=os.environ.get('MYSQL_PASSWORD'))
|
||||||
|
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
Flask
|
Flask==2.1.2
|
||||||
Flask-SQLAlchemy
|
Flask-SQLAlchemy==2.5.1
|
||||||
Flask-Security
|
Flask-Security==3.0.0
|
||||||
Flask-WTF
|
Flask-WTF==1.0.1
|
||||||
PyMySQL
|
PyMySQL==1.0.2
|
||||||
markdown
|
markdown
|
||||||
Flask-Limiter
|
Flask-Limiter==2.4.5.1
|
||||||
requests
|
requests==2.27.1
|
||||||
email_validator
|
email-validator==1.2.1
|
||||||
|
gunicorn==20.1.0
|
||||||
|
pytz==2022.1
|
||||||
|
SQLAlchemy==1.4.36
|
||||||
|
Werkzeug==2.2.2
|
||||||
Reference in New Issue
Block a user