From b60a9abb84138476ceae4a5b1867bc3fe92e4dfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20M=C3=A9taireau?= Date: Thu, 26 Nov 2020 22:27:25 +0100 Subject: [PATCH] Add a demo mode --- copanier/models.py | 40 ++++++++++++++++++- copanier/static/app.css | 9 +++++ copanier/templates/base.html | 7 ++++ .../templates/delivery/list_deliveries.html | 1 - copanier/templates/onboarding.html | 12 ++++++ copanier/views/delivery.py | 7 +++- copanier/views/login.py | 29 +++++++++++++- tests/test_models.py | 6 +-- 8 files changed, 103 insertions(+), 8 deletions(-) create mode 100644 copanier/templates/onboarding.html diff --git a/copanier/models.py b/copanier/models.py index 3f0b30c..f01f184 100644 --- a/copanier/models.py +++ b/copanier/models.py @@ -77,11 +77,39 @@ class Base: @dataclass class PersistedBase(Base): + @classmethod def get_root(cls): - return Path(config.DATA_ROOT) / cls.__root__ + root = Path(config.DATA_ROOT) + if getattr(config, 'DEMO_MODE', False): + root = root / "demo" + + return root / cls.__root__ +@dataclass +class SavedConfiguration(PersistedBase): + __lock__ = threading.Lock() + demo_mode_enabled: bool = False + + @classmethod + def get_path(cls): + return Path(config.DATA_ROOT) / "config.yml" + + def persist(self): + with self.__lock__: + self.get_path().write_text(self.dump()) + + @classmethod + def load(cls): + path = cls.get_path() + if path.exists(): + data = yaml.safe_load(path.read_text()) + data = {k: v for k, v in data.items() if k in cls.__dataclass_fields__} + else: + data = {} + return cls(**data) + @dataclass class Person(Base): email: str @@ -133,6 +161,12 @@ class Groups(PersistedBase): data = {"groups": {}} groups = cls(**data) return groups + + @classmethod + def is_defined(cls): + groups = cls.load() + return len(groups.groups) > 0 + def persist(self): with self.__lock__: @@ -384,6 +418,10 @@ class Delivery(PersistedBase): for path in root.glob("*.yml"): id_ = str(path.relative_to(cls.get_root())).replace(".yml", "") yield Delivery.load(id_) + + @classmethod + def is_defined(cls): + return len(list(cls.all())) > 0 @classmethod def incoming(cls): diff --git a/copanier/static/app.css b/copanier/static/app.css index 54ffd17..18fce1c 100644 --- a/copanier/static/app.css +++ b/copanier/static/app.css @@ -720,3 +720,12 @@ ul.actions > li { small { font-size: 70% !important; } + +.demo-mode { + background: var(--warning-color); + padding: 0em !important; +} + +.header { + padding-bottom: 2em !important; +} \ No newline at end of file diff --git a/copanier/templates/base.html b/copanier/templates/base.html index 6e4a52f..76a9f02 100644 --- a/copanier/templates/base.html +++ b/copanier/templates/base.html @@ -18,6 +18,13 @@ + {% if config.DEMO_MODE %} +
+
+

Le site est en mode démo. désactiver

+
+
+ {% endif %}
diff --git a/copanier/templates/delivery/list_deliveries.html b/copanier/templates/delivery/list_deliveries.html index 7824f16..dc65559 100644 --- a/copanier/templates/delivery/list_deliveries.html +++ b/copanier/templates/delivery/list_deliveries.html @@ -4,7 +4,6 @@

Distributions

- {% with deliveries=incoming %} {% include "includes/delivery_list.html" %} {% endwith %} diff --git a/copanier/templates/onboarding.html b/copanier/templates/onboarding.html new file mode 100644 index 0000000..a9329ce --- /dev/null +++ b/copanier/templates/onboarding.html @@ -0,0 +1,12 @@ +{% extends "base.html" %} +{% block body %} +

Bienvenue sur copanier

+

On dirait que vous venez de lancer ce logiciel pour la première fois, bienvenue ici 😀.

+

Pour commencer, deux options :

+
+

Bon voyage 🙏 !

+{% endblock body %} diff --git a/copanier/views/delivery.py b/copanier/views/delivery.py index 9a05605..19fde3f 100644 --- a/copanier/views/delivery.py +++ b/copanier/views/delivery.py @@ -5,7 +5,7 @@ from roll import HttpError from debts.solver import order_balance, check_balance, reduce_balance from .core import app, staff_only, session, env -from ..models import Delivery, Person, Order, ProductOrder +from ..models import Delivery, Person, Order, ProductOrder, Groups, SavedConfiguration from .. import utils, reports, emails, config @@ -16,8 +16,11 @@ async def on_startup(): @app.route("/", methods=["GET"]) async def home(request, response): + if not Delivery.is_defined() and not Groups.is_defined(): + response.redirect = url_for("onboarding") + return if not request["user"].group_id: - response.redirect = "/groupes" + response.redirect = url_for("groups") return response.html( "delivery/list_deliveries.html", diff --git a/copanier/views/login.py b/copanier/views/login.py index b2e6e2a..28231fa 100644 --- a/copanier/views/login.py +++ b/copanier/views/login.py @@ -1,6 +1,6 @@ from .core import app, session, env, url -from ..models import Groups, Person +from ..models import Groups, Person, SavedConfiguration from .. import utils, emails, config @@ -11,6 +11,13 @@ async def auth_required(request, response): # route as unprotected. if request.path.startswith("/static/"): return + + saved_config = SavedConfiguration.load() + if saved_config.demo_mode_enabled: + setattr(config, 'DEMO_MODE', True) + else: + setattr(config, 'DEMO_MODE', False) + if request.route.payload and not request.route.payload.get("unprotected"): token = request.cookies.get("token") email = None @@ -83,3 +90,23 @@ async def set_sesame(request, response, token): async def logout(request, response): response.cookies.set(name="token", value="", httponly=True) response.redirect = "/" + + +@app.route("/premier-lancement", methods=["GET"]) +async def onboarding(request, response): + response.html("onboarding.html") + +@app.route("/premier-lancement/demo", methods=["GET"]) +async def activate_demo(request, response): + saved_config = SavedConfiguration.load() + saved_config.demo_mode_enabled = True + saved_config.persist() + response.redirect = "/" + +@app.route("/premier-lancement/demo/désactiver", methods=["GET"]) +async def desactivate_demo(request, response): + saved_config = SavedConfiguration.load() + saved_config.demo_mode_enabled = False + saved_config.persist() + response.redirect = "/" + diff --git a/tests/test_models.py b/tests/test_models.py index 92493e4..d60cecc 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -165,9 +165,9 @@ def test_productorder_quantity(): def test_group_management(): ndp = Group( - id="nid-de-poules", name="Nid de poules", members=["someone@domain.tld"] + id="passage-creuse", name="Nid de poules", members=["someone@domain.tld"] ) - assert ndp.id == "nid-de-poules" + assert ndp.id == "passage-creuse" assert ndp.name == "Nid de poules" assert len(ndp.members) == 1 groups = Groups.load() @@ -177,7 +177,7 @@ def test_group_management(): groups.add_user("simon@tld", ndp.id) assert "simon@tld" in groups.groups[ndp.id].members - ladouce = Group(id="la-douce", name="La douce", members=[]) + ladouce = Group(id="la-lointaine", name="La douce", members=[]) groups.add_group(ladouce) groups.add_user("simon@tld", ladouce.id) assert "simon@tld" in groups.groups[ladouce.id].members