From 89e13627dea86448d38404a7d13f5d3c1dbdf884 Mon Sep 17 00:00:00 2001 From: Florian Bezannier Date: Sat, 23 Oct 2021 12:37:51 +0200 Subject: [PATCH] update to dash v2,dbc v1 and fix issue --- libs/config.py | 5 +++-- libs/requirements.py | 17 +++++++++++++++++ requirements.txt | 4 ++-- server.py | 5 +++++ web/figures.py | 16 ++++++++-------- web/tools/Button.py | 3 ++- web/tools/Switch.py | 2 +- web/tools/figurefilter.py | 2 +- web/utils.py | 2 +- web/view/config_views.py | 24 +++++++++++------------- web/view/control.py | 2 +- web/view/views.py | 6 ++---- 12 files changed, 54 insertions(+), 34 deletions(-) diff --git a/libs/config.py b/libs/config.py index efda32f..30a8491 100644 --- a/libs/config.py +++ b/libs/config.py @@ -57,7 +57,7 @@ class Config(metaclass=Singleton): def start_remote_control(self): if self.args.remote_disable: logger.info("mqtt disabled") - elif not self.args.web_conf or path.exists(OTP_CONFIG_NAME): + elif not self.args.web_conf or path.isfile(OTP_CONFIG_NAME): if self.myp.mqtt_client is not None: self.myp.mqtt_client.disconnect() self.myp.start_mqtt() @@ -70,9 +70,10 @@ class Config(metaclass=Singleton): my_logger(handler_level=int(self.args.debug)) if self.args.config: self.config_name = self.args.config - if path.exists(self.config_name): + if path.isfile(self.config_name): self.myp = MyPSACC.load_config(name=self.config_name) elif self.args.web_conf: + self.is_good = False return False else: raise FileNotFoundError(self.config_name) diff --git a/libs/requirements.py b/libs/requirements.py index e69de29..9e43fb2 100644 --- a/libs/requirements.py +++ b/libs/requirements.py @@ -0,0 +1,17 @@ +import pkg_resources +from pathlib import Path + + +class TestRequirements: + """Test availability of required packages.""" + + def __init__(self, requirement_path): + self.requirement_path = Path(requirement_path) + + def test_requirements(self): + """Test that each required package is available.""" + # Ref: https://stackoverflow.com/a/45474387/ + requirements = pkg_resources.parse_requirements(self.requirement_path.open()) + for requirement in requirements: + requirement = str(requirement) + pkg_resources.require(requirement) diff --git a/requirements.txt b/requirements.txt index e34af87..5b1b714 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ paho-mqtt>=1.5.0 -dash>=1.18.0 +dash>=2 dash_daq plotly>=4 cryptography>=2.6 @@ -11,7 +11,7 @@ pytz typing argparse flask -dash_bootstrap_components +dash_bootstrap_components>=1 geojson reverse_geocode androguard diff --git a/server.py b/server.py index 63acaef..b2f4585 100755 --- a/server.py +++ b/server.py @@ -2,9 +2,14 @@ # pylint: disable=wrong-import-position import sys from threading import Thread + +from libs.requirements import TestRequirements + if sys.version_info < (3, 6): raise RuntimeError("This application requires Python 3.6+") +TestRequirements("requirements.txt").test_requirements() + import web.app from libs.config import Config from mylogger import logger diff --git a/web/figures.py b/web/figures.py index c024fae..923837f 100644 --- a/web/figures.py +++ b/web/figures.py @@ -2,12 +2,12 @@ from copy import deepcopy from statistics import mean import dash_bootstrap_components as dbc -import dash_table -from dash_table.Format import Format, Scheme, Symbol +from dash import html +from dash.dash_table import Format, DataTable import plotly.express as px import plotly.graph_objects as go -from web.tools.import_dash_html import html -from web.tools.import_dash_core import dcc +from dash.dash_table.Format import Scheme, Symbol +from dash.dcc import Graph from libs.car import Car from libs.elec_price import ElecPrice @@ -69,7 +69,7 @@ def get_figures(car: Car): style_cell_conditional.append({'if': {'column_id': 'consumption_fuel_km', }, 'display': 'None', }) if car.is_thermal(): style_cell_conditional.append({'if': {'column_id': 'consumption_km', }, 'display': 'None', }) - table_fig = dash_table.DataTable( + table_fig = DataTable( id='trips-table', sort_action='custom', sort_by=[{'column_id': 'id', 'direction': 'desc'}], @@ -116,7 +116,7 @@ def get_figures(car: Car): consumption_fig_by_speed.update_layout(xaxis_title="average Speed km/h", yaxis_title="Consumption kWh/100Km") # battery_table - battery_table = dash_table.DataTable( + battery_table = DataTable( id='battery-table', sort_action='custom', sort_by=[{'column_id': 'start_at_str', 'direction': 'desc'}], @@ -199,7 +199,7 @@ def get_battery_curve_fig(row: dict, car: Car): battery_curves.append({"level": row["end_level"], "speed": speed}) fig = px.line(battery_curves, x="level", y="speed") fig.update_layout(xaxis_title="Battery %", yaxis_title="Charging speed in kW") - return html.Div(dcc.Graph(figure=fig)) + return html.Div(Graph(figure=fig)) def get_altitude_fig(trip: Trip): @@ -212,4 +212,4 @@ def get_altitude_fig(trip: Trip): fig = px.line(res, x=0, y=1) fig.update_layout(xaxis_title="Distance km", yaxis_title="Altitude m") conn.close() - return html.Div(dcc.Graph(figure=fig)) + return html.Div(Graph(figure=fig)) diff --git a/web/tools/Button.py b/web/tools/Button.py index 5292e8d..c8d9bcd 100644 --- a/web/tools/Button.py +++ b/web/tools/Button.py @@ -1,7 +1,8 @@ +import html + import dash_bootstrap_components as dbc from dash._utils import create_callback_id from dash.dependencies import Output, Input -from web.tools.import_dash_html import html from web.app import dash_app diff --git a/web/tools/Switch.py b/web/tools/Switch.py index 33e7cab..ff28ce9 100644 --- a/web/tools/Switch.py +++ b/web/tools/Switch.py @@ -1,6 +1,6 @@ import dash_bootstrap_components as dbc import dash_daq as daq -from web.tools.import_dash_html import html +from dash import html from dash.dependencies import Input from web.app import dash_app diff --git a/web/tools/figurefilter.py b/web/tools/figurefilter.py index 3afc56d..7031dd3 100644 --- a/web/tools/figurefilter.py +++ b/web/tools/figurefilter.py @@ -1,9 +1,9 @@ import json from logging import DEBUG +from dash import dcc from dash._utils import create_callback_id from dash.dependencies import Output, Input -from web.tools.import_dash_core import dcc from mylogger import logger diff --git a/web/utils.py b/web/utils.py index c0e88d5..db3c09f 100644 --- a/web/utils.py +++ b/web/utils.py @@ -1,7 +1,7 @@ from datetime import datetime, timedelta import dash_bootstrap_components as dbc -from web.tools.import_dash_html import html +from dash import html from dash.development.base_component import Component from pandas import DataFrame from pytz import UTC diff --git a/web/view/config_views.py b/web/view/config_views.py index 7baabc6..b81dc91 100644 --- a/web/view/config_views.py +++ b/web/view/config_views.py @@ -1,4 +1,4 @@ -from dash import callback_context +from dash import callback_context, html, dcc from dash.exceptions import PreventUpdate from flask import request @@ -9,14 +9,12 @@ from otp.otp import new_otp_session from web.app import dash_app import dash_bootstrap_components as dbc from dash.dependencies import Output, Input, State -from web.tools.import_dash_core import dcc -from web.tools.import_dash_html import html config = Config() -login_config_layout = dbc.Row(dbc.Col(md=12, lg=2, children=[ +login_config_layout = dbc.Row(dbc.Col(md=12, lg=2, style={"ml": 2}, children=[ html.H2('Config'), dbc.Form([ - dbc.FormGroup([ + dbc.Row([ dbc.Label("Car Brand", html_for="psa-app"), dcc.Dropdown( id="psa-app", @@ -28,7 +26,7 @@ login_config_layout = dbc.Row(dbc.Col(md=12, lg=2, children=[ {"label": "Vauxhall", "value": "com.psa.mym.myvauxhall"} ], )]), - dbc.FormGroup( + dbc.Row( [ dbc.Label("Email", html_for="psa-email"), dbc.Input(type="email", id="psa-email", placeholder="Enter email"), @@ -38,7 +36,7 @@ login_config_layout = dbc.Row(dbc.Col(md=12, lg=2, children=[ ), ] ), - dbc.FormGroup( + dbc.Row( [ dbc.Label("Password", html_for="psa-password"), dbc.Input( @@ -52,7 +50,7 @@ login_config_layout = dbc.Row(dbc.Col(md=12, lg=2, children=[ ), ] ), - dbc.FormGroup( + dbc.Row( [ dbc.Label("Country code", html_for="countrycode"), dbc.Input( @@ -66,7 +64,7 @@ login_config_layout = dbc.Row(dbc.Col(md=12, lg=2, children=[ ) ] ), - dbc.FormGroup([ + dbc.Row([ dbc.Button("Submit", color="primary", id="submit-form"), dbc.FormText( "After submit be patient it can take some time...", @@ -80,21 +78,21 @@ login_config_layout = dbc.Row(dbc.Col(md=12, lg=2, children=[ ), ])])) -config_otp_layout = dbc.Row(dbc.Col(className="col-md-12 col-lg-2 ml-2", children=[ +config_otp_layout = dbc.Row(dbc.Col(className="col-md-12 col-lg-2", style={"ml": 2}, children=[ html.H2('Config OTP'), dbc.Form([ - dbc.FormGroup([ + dbc.Row([ dbc.Label("Click to receive a code by SMS", html_for="ask-sms"), dbc.Button("Send SMS", color="info", id="ask-sms"), html.Div(id="sms-demand-result", className="mt-2") ]), - dbc.FormGroup( + dbc.Row( [ dbc.Label("Write the code you just received by SMS", html_for="psa-email"), dbc.Input(type="text", id="psa-code", placeholder="Enter code"), ] ), - dbc.FormGroup( + dbc.Row( [ dbc.Label("Enter your code PIN", html_for="psa-pin"), dbc.Input( diff --git a/web/view/control.py b/web/view/control.py index 6386375..b90d69d 100644 --- a/web/view/control.py +++ b/web/view/control.py @@ -1,5 +1,5 @@ import dash_bootstrap_components as dbc -from web.tools.import_dash_html import html +from dash import html from mylogger import logger from web.tools.Button import Button diff --git a/web/view/views.py b/web/view/views.py index ae06b25..6580765 100644 --- a/web/view/views.py +++ b/web/view/views.py @@ -3,6 +3,7 @@ from typing import List from urllib.parse import parse_qs, urlparse import dash_bootstrap_components as dbc +from dash import dcc, html from dash.dependencies import Output, Input, State from dash.exceptions import PreventUpdate from flask import jsonify, request, Response as FlaskResponse @@ -23,8 +24,6 @@ from web.utils import diff_dashtable, dash_date_to_datetime # pylint: disable=invalid-name from web.tools.figurefilter import FigureFilter -from web.tools.import_dash_html import html -from web.tools.import_dash_core import dcc from web.utils import create_card from libs.config import Config from web.view.control import get_control_tabs @@ -42,8 +41,7 @@ def add_header(el): return dbc.Row([dbc.Col(dcc.Link(html.H1('My car info'), href="/", style={"text-decoration": "none"})), dbc.Col(dcc.Link(html.Img(src="assets/images/settings.svg", width="30veh"), href="/config", - className="float-right"))], - className="justify-content-between"), el + className="float-end"))]), el @dash_app.callback(Output('page-content', 'children'),