mirror of
https://github.com/almet/copanier.git
synced 2025-04-28 19:42:37 +02:00
Add COPANIER_SITE_URL
This commit is contained in:
parent
9dc7794f2d
commit
6a9d94413e
13 changed files with 39 additions and 21 deletions
|
@ -15,6 +15,7 @@ STAFF = []
|
||||||
LOCALE = "fr_FR.UTF-8"
|
LOCALE = "fr_FR.UTF-8"
|
||||||
#LOCALE = "en_US.UTF-8"
|
#LOCALE = "en_US.UTF-8"
|
||||||
SITE_NAME = "Copanier"
|
SITE_NAME = "Copanier"
|
||||||
|
SITE_URL = "http://localhost:2244"
|
||||||
SITE_DESCRIPTION = "Shared orders"
|
SITE_DESCRIPTION = "Shared orders"
|
||||||
EMAIL_SIGNATURE = "The kind people behind copanier"
|
EMAIL_SIGNATURE = "The kind people behind copanier"
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ def send(to, subject, body, html=None, copy=None, attachments=None):
|
||||||
|
|
||||||
if not config.SEND_EMAILS:
|
if not config.SEND_EMAILS:
|
||||||
body = body.replace("https", "http")
|
body = body.replace("https", "http")
|
||||||
return print("Sending email", str(body))
|
return print("Sending email", str(body.encode('utf-8')))
|
||||||
|
|
||||||
message.send(
|
message.send(
|
||||||
to=to,
|
to=to,
|
||||||
|
@ -37,7 +37,7 @@ def send_from_template(env, template, to, subject, **params):
|
||||||
send(to, subject, body=txt, html=html)
|
send(to, subject, body=txt, html=html)
|
||||||
|
|
||||||
|
|
||||||
def send_order(request, env, person, delivery, order, group_id):
|
def send_order(request, env, person, delivery, order, group_id, **kwargs):
|
||||||
send_from_template(
|
send_from_template(
|
||||||
env,
|
env,
|
||||||
"order_summary",
|
"order_summary",
|
||||||
|
@ -48,4 +48,5 @@ def send_order(request, env, person, delivery, order, group_id):
|
||||||
delivery=delivery,
|
delivery=delivery,
|
||||||
request=request,
|
request=request,
|
||||||
group_id=group_id,
|
group_id=group_id,
|
||||||
|
**kwargs,
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,11 +7,11 @@
|
||||||
<title>{% if title %}{{ title }} - {% endif %}{{ config.SITE_NAME }}</title>
|
<title>{% if title %}{{ title }} - {% endif %}{{ config.SITE_NAME }}</title>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="stylesheet" type="text/css" href="/static/app.css">
|
<link rel="stylesheet" type="text/css" href="{{ url_for('/static/app.css') }}">
|
||||||
<link rel="stylesheet" type="text/css" href="/static/icomoon.css">
|
<link rel="stylesheet" type="text/css" href="{{ url_for('/static/icomoon.css') }}">
|
||||||
<link rel="stylesheet" type="text/css" href="/static/purecss.css">
|
<link rel="stylesheet" type="text/css" href="{{ url_for('/static/purecss.css') }}">
|
||||||
<link rel="stylesheet" type="text/css" href="/static/side-menu.css">
|
<link rel="stylesheet" type="text/css" href="{{ url_for('/static/side-menu.css') }}">
|
||||||
<link rel="stylesheet" type="text/css" href="/static/flash.min.css">
|
<link rel="stylesheet" type="text/css" href="{{ url_for('/static/flash.min.css') }}">
|
||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
{% endblock head %}
|
{% endblock head %}
|
||||||
|
@ -60,8 +60,8 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<script src="/static/js/flash.min.js"></script>
|
<script src="{{ url_for('/static/js/flash.min.js') }}"></script>
|
||||||
<script src="/static/js/app.js"></script>
|
<script src="{{ url_for('/static/js/app.js') }}"></script>
|
||||||
{% if message %}
|
{% if message %}
|
||||||
<script>
|
<script>
|
||||||
new window.FlashMessage("{{ message[0] }}", "{{ message[1] }}", {
|
new window.FlashMessage("{{ message[0] }}", "{{ message[1] }}", {
|
||||||
|
|
|
@ -13,7 +13,7 @@ Bonjour,
|
||||||
Et voilà, les commandes maintenant terminées, il est maintenant temps de passer à l'action !
|
Et voilà, les commandes maintenant terminées, il est maintenant temps de passer à l'action !
|
||||||
En pièce-jointe, les informations pour les producteurs⋅rices dont tu est référent⋅e.
|
En pièce-jointe, les informations pour les producteurs⋅rices dont tu est référent⋅e.
|
||||||
|
|
||||||
Tu peux aussi retrouver le doc à cette URL : https://{{ request.host }}{{ url_for('list_products', id=delivery.id) }}
|
Tu peux aussi retrouver le doc à cette URL : {{ url_for('list_products', id=delivery.id) }}
|
||||||
|
|
||||||
Rendez-vous pour la distribution, le {{ delivery.from_date|date }} de {{ delivery.from_date|time }} à {{ delivery.to_date|time }} à {{ delivery.where }}.
|
Rendez-vous pour la distribution, le {{ delivery.from_date|date }} de {{ delivery.from_date|time }} à {{ delivery.to_date|time }} à {{ delivery.where }}.
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
|
|
||||||
<p>Voici le sésame, clique dessus pour t'authentifier, ou copie-colle-le dans ton navigateur:</p>
|
<p>Voici le sésame, clique dessus pour t'authentifier, ou copie-colle-le dans ton navigateur:</p>
|
||||||
|
|
||||||
<a href="https://{{ hostname }}{{ url_for('set_sesame', token=token) }}">https://{{ hostname }}{{ url_for('set_sesame', token=token) }}</a>
|
<a href="{{ url_for('set_sesame', token=token) }}">{{ url_for('set_sesame', token=token) }}</a>
|
||||||
|
|
||||||
<p>{{ config.EMAIL_SIGNATURE }}</p>
|
<p>{{ config.EMAIL_SIGNATURE }}</p>
|
||||||
|
|
|
@ -2,6 +2,6 @@ Hey ho!
|
||||||
|
|
||||||
Voici le sésame, clique dessus pour accéder à la commande :
|
Voici le sésame, clique dessus pour accéder à la commande :
|
||||||
|
|
||||||
https://{{ hostname }}{{ url_for('set_sesame', token=token) }}
|
{{ url_for('set_sesame', token=token) }}
|
||||||
|
|
||||||
{{ config.EMAIL_SIGNATURE }}
|
{{ config.EMAIL_SIGNATURE }}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
{% include "includes/order_summary.html" %}
|
{% include "includes/order_summary.html" %}
|
||||||
<p>Distribution: {{ delivery.where }}, le {{ delivery.from_date|date }} de {{ delivery.from_date|time }} à {{ delivery.to_date|time }}</p>
|
<p>Distribution: {{ delivery.where }}, le {{ delivery.from_date|date }} de {{ delivery.from_date|time }} à {{ delivery.to_date|time }}</p>
|
||||||
{% if delivery.is_open %}
|
{% if delivery.is_open %}
|
||||||
<p>Tu peux la modifier (jusqu'au {{ delivery.order_before|date }}) <a href="https://{{ request.host }}/distribution/{{ delivery.id }}/commander">en cliquant ici</a>.</p>
|
<p>Tu peux la modifier (jusqu'au {{ delivery.order_before|date }}) <a href="{{ url_for('place_order', id=delivery.id) }}">en cliquant ici</a>.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<p>Bonne journée!</p>
|
<p>Bonne journée!</p>
|
||||||
<p>{{ config.EMAIL_SIGNATURE }}</p>
|
<p>{{ config.EMAIL_SIGNATURE }}</p>
|
||||||
|
|
|
@ -14,7 +14,7 @@ Distribution: {{ delivery.where }}, le {{ delivery.from_date|date }} de {{ deliv
|
||||||
{% if delivery.is_open %}
|
{% if delivery.is_open %}
|
||||||
Tu peux la modifier (jusqu'au {{ delivery.order_before|date }}) en cliquant ici:
|
Tu peux la modifier (jusqu'au {{ delivery.order_before|date }}) en cliquant ici:
|
||||||
|
|
||||||
https://{{ request.host }}/distribution/{{ delivery.id }}/commander
|
{{ url_for('place_order', id=delivery.id) }}
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block toplink %}<a href="/distribution/{{ delivery.id }}">↶ Retourner à la distribution</a>{% endblock %}
|
{% block toplink %}<a href="{{ url_for('show_delivery', id=delivery.id) }}">↶ Retourner à la distribution</a>{% endblock %}
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<h1>Gérer les produits</h1>
|
<h1>Gérer les produits</h1>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import ujson as json
|
import ujson as json
|
||||||
|
|
||||||
|
from urllib.parse import urljoin
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from jinja2 import Environment, PackageLoader, select_autoescape
|
from jinja2 import Environment, PackageLoader, select_autoescape
|
||||||
from roll.extensions import traceback
|
from roll.extensions import traceback
|
||||||
|
@ -57,7 +58,7 @@ class Response(RollResponse):
|
||||||
|
|
||||||
def redirect(self, location):
|
def redirect(self, location):
|
||||||
self.status = 302
|
self.status = 302
|
||||||
self.headers["Location"] = location
|
self.headers["Location"] = url(location)
|
||||||
|
|
||||||
redirect = property(None, redirect)
|
redirect = property(None, redirect)
|
||||||
|
|
||||||
|
@ -76,6 +77,15 @@ def get_function_name(node):
|
||||||
return func.__name__
|
return func.__name__
|
||||||
|
|
||||||
|
|
||||||
|
def url(path):
|
||||||
|
if config.SITE_URL:
|
||||||
|
site_url = config.SITE_URL.rstrip('/')
|
||||||
|
if not path.startswith(site_url):
|
||||||
|
path = site_url + path
|
||||||
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Roll(BaseRoll):
|
class Roll(BaseRoll):
|
||||||
Response = Response
|
Response = Response
|
||||||
|
|
||||||
|
@ -103,11 +113,13 @@ class Roll(BaseRoll):
|
||||||
return route
|
return route
|
||||||
|
|
||||||
def url_for(self, name, *args, **kwargs):
|
def url_for(self, name, *args, **kwargs):
|
||||||
|
if name.startswith("/"):
|
||||||
|
return url(name)
|
||||||
route = self._find_route_by_name(name)
|
route = self._find_route_by_name(name)
|
||||||
if not route:
|
if not route:
|
||||||
raise Exception(f"Route for '{name}' wasn't found")
|
raise Exception(f"Route for '{name}' wasn't found")
|
||||||
try:
|
try:
|
||||||
return route.path.format(*args, **kwargs)
|
return url(route.path.format(*args, **kwargs))
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
raise Exception(f"Unable to build URL for {name} : '{e}' is missing")
|
raise Exception(f"Unable to build URL for {name} : '{e}' is missing")
|
||||||
|
|
||||||
|
@ -134,6 +146,7 @@ env = Environment(
|
||||||
autoescape=select_autoescape(["copanier"]),
|
autoescape=select_autoescape(["copanier"]),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
env.filters["date"] = utils.date_filter
|
env.filters["date"] = utils.date_filter
|
||||||
env.filters["time"] = utils.time_filter
|
env.filters["time"] = utils.time_filter
|
||||||
|
|
||||||
|
|
|
@ -213,6 +213,7 @@ async def place_order(request, response, id):
|
||||||
delivery=delivery,
|
delivery=delivery,
|
||||||
order=order,
|
order=order,
|
||||||
group_id=orderer.group_id,
|
group_id=orderer.group_id,
|
||||||
|
url_for=app.url_for,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
emails.send_order(
|
emails.send_order(
|
||||||
|
@ -222,6 +223,7 @@ async def place_order(request, response, id):
|
||||||
delivery=delivery,
|
delivery=delivery,
|
||||||
order=order,
|
order=order,
|
||||||
group_id=orderer.email,
|
group_id=orderer.email,
|
||||||
|
url_for=app.url_for,
|
||||||
)
|
)
|
||||||
response.message(
|
response.message(
|
||||||
f"La commande pour « {orderer.name} » a bien été prise en compte, "
|
f"La commande pour « {orderer.name} » a bien été prise en compte, "
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from .core import app, session, env
|
from .core import app, session, env, url
|
||||||
|
|
||||||
from ..models import Groups, Person
|
from ..models import Groups, Person
|
||||||
from .. import utils, emails, config
|
from .. import utils, emails, config
|
||||||
|
@ -18,7 +18,7 @@ async def auth_required(request, response):
|
||||||
decoded = utils.read_token(token)
|
decoded = utils.read_token(token)
|
||||||
email = decoded.get("sub")
|
email = decoded.get("sub")
|
||||||
if not email:
|
if not email:
|
||||||
response.redirect = f"/connexion?next={request.path}"
|
response.redirect = f"/connexion?next={url(request.path)}"
|
||||||
return response
|
return response
|
||||||
|
|
||||||
groups = Groups.load()
|
groups = Groups.load()
|
||||||
|
|
|
@ -5,6 +5,7 @@ import pytest
|
||||||
from openpyxl import load_workbook
|
from openpyxl import load_workbook
|
||||||
from pyquery import PyQuery as pq
|
from pyquery import PyQuery as pq
|
||||||
|
|
||||||
|
from copanier.views.core import url
|
||||||
from copanier.models import Delivery, Order, ProductOrder, Product
|
from copanier.models import Delivery, Order, ProductOrder, Product
|
||||||
|
|
||||||
pytestmark = pytest.mark.asyncio
|
pytestmark = pytest.mark.asyncio
|
||||||
|
@ -14,7 +15,7 @@ async def test_home_redirects_to_group_if_needed(client):
|
||||||
client.login(email="new@example.org")
|
client.login(email="new@example.org")
|
||||||
resp = await client.get("/")
|
resp = await client.get("/")
|
||||||
assert resp.status == 302
|
assert resp.status == 302
|
||||||
assert resp.headers["Location"] == "/groupes"
|
assert resp.headers["Location"] == url("/groupes")
|
||||||
|
|
||||||
|
|
||||||
async def test_empty_home(client, delivery, groups):
|
async def test_empty_home(client, delivery, groups):
|
||||||
|
@ -35,7 +36,7 @@ async def test_home_should_redirect_to_login_if_not_logged(client):
|
||||||
client.logout()
|
client.logout()
|
||||||
resp = await client.get("/")
|
resp = await client.get("/")
|
||||||
assert resp.status == 302
|
assert resp.status == 302
|
||||||
assert resp.headers["Location"] == "/connexion?next=/"
|
assert resp.headers["Location"] == url("/connexion?next=" + url("/"))
|
||||||
|
|
||||||
|
|
||||||
async def test_create_delivery(client):
|
async def test_create_delivery(client):
|
||||||
|
|
Loading…
Reference in a new issue