Compare commits

...

18 Commits

Author SHA1 Message Date
3de3586fe0 Fǒnt update 2025-08-05 18:52:19 +02:00
9b6811c410 Mets des écaillěs 2025-08-05 17:38:29 +02:00
ebe9516557 Voici les Blěktřs pour schtroumpfer les bidules. 2025-07-27 19:26:27 +02:00
1426ca5fa6 Update README.md 2025-02-11 14:46:28 +00:00
0c574ca913 Add missing dependency 2025-02-11 14:23:14 +00:00
bbc59931e1 Fix borken thangs 2024-09-03 19:26:28 +00:00
092c0d17ae Add docker-compose file 2024-05-23 03:51:32 +00:00
489e005c96 Adjust for jenova 2024-05-23 03:51:29 +00:00
5efcee12a9 frontend: sort by title 2023-08-03 20:18:43 +02:00
b838c79cdb CSRF $#%?@!!. Also konami to django admin 2023-08-03 20:11:45 +02:00
e8abfaf51b Add example system config files 2023-08-03 18:00:27 +02:00
55711d68c1 backend: allow all hosts 2023-08-03 17:59:59 +02:00
2b539a45d2 Set subs per product category 2023-07-03 20:52:43 +02:00
2895d295e4 Update README 2023-07-03 20:02:09 +02:00
74d7564bdc frontend: avoid double slash in data urls 2023-07-03 19:57:14 +02:00
0d164a1f31 Now deployable 2023-07-03 19:56:32 +02:00
2395bc215d Backend LGTM 2023-07-03 16:56:58 +02:00
9a7ce60913 manage.py makemigrations 2023-07-03 16:38:35 +02:00
22 changed files with 10873 additions and 39 deletions

View File

@@ -1,6 +1,7 @@
FROM alpine FROM alpine
RUN apk --no-cache add python3 inkscape bash imagemagick ttf-opensans RUN apk --no-cache add python3 inkscape bash imagemagick ghostscript ttf-opensans
RUN apk --no-cache add py3-pip && pip3 install --break-system-packages django tzdata gunicorn
ADD backend /root/zetikettes ADD backend /root/zetikettes
@@ -8,6 +9,7 @@ RUN mkdir -p /usr/share/fonts/TTF \
&& cp /root/zetikettes/fonts/*.ttf /usr/share/fonts/TTF/ \ && cp /root/zetikettes/fonts/*.ttf /usr/share/fonts/TTF/ \
&& fc-cache -fv && fc-cache -fv
# the script will look for templates in /data # the script will look for templates in /data
WORKDIR /root/zetikettes WORKDIR /root/zetikettes/zetikettes
CMD /usr/bin/python3 web.py CMD /usr/bin/gunicorn zetikettes.wsgi -b 0.0.0.0:8000 --timeout 600 --forwarded-allow-ips="*"

View File

@@ -9,6 +9,9 @@ Initial setup
``` ```
docker build -t zetikettes . docker build -t zetikettes .
sudo mkdir -p /etc/docker/compose/zetikettes
sudo cp docker-compose.yml /etc/docker/compose/zetikettes/
sudo systemctl enable --now docker-compose@zetikettes
``` ```
Nginx is configured to: Nginx is configured to:
@@ -21,7 +24,7 @@ Test
---- ----
``` ```
docker run --rm -it -v $PWD/templates:/data zetikettes /bin/bash /root/zetikettes/mkjam.sh docker run --rm -it -v $PWD/templates:/data zetikettes /bin/bash /root/zetikettes/old/mkjam.sh
``` ```
This should produce a .pdf in `templates/`. Open it to check that This should produce a .pdf in `templates/`. Open it to check that
@@ -31,13 +34,31 @@ Run
--- ---
``` ```
docker run -d --rm -p 127.0.0.1:8000:8000 -v /var/lib/zetikettes/templates:/data zetikettes docker-compose up
``` ```
Notes for deploying
-------------------
.h3 Initialize empty database
```
python manage.py migrate
```
.h3 Prepare static files
```
python manage.py collectstatic
```
The files will be in `www_static/` and need to be moved to `/var/lib/zetikettes/www_static`
.h3 Change host settings
If not deploying on `aerith.ponteilla.net`, you'll need to edit `backend/zetikettes/zetikettes/settings.py` to change a couple things in there.
Change available templates Change available templates
-------------------------- --------------------------
1. go to /zetikettes/newtikette.html or konami code from main app 1. go to /zetikettes/admin
1. add the newtikette 1. add the newtikette
1. still no need to restart the container (magic!) 1. still no need to restart the container (magic!)
2. profit. 2. profit.

View File

@@ -0,0 +1,51 @@
# Generated by Django 4.2.2 on 2023-07-03 14:37
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Tikategory',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
('landscape', models.BooleanField()),
],
options={
'verbose_name_plural': 'tikategoriez',
},
),
migrations.CreateModel(
name='Tisub',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
('descritpion', models.TextField()),
('default', models.TextField()),
],
options={
'verbose_name_plural': 'tisubz',
},
),
migrations.CreateModel(
name='Tikette',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=100)),
('svg', models.FileField(upload_to='')),
('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tikette.tikategory')),
('subs', models.ManyToManyField(to='tikette.tisub')),
],
options={
'verbose_name_plural': 'tikettz',
},
),
]

View File

@@ -1,16 +1,5 @@
from django.db import models from django.db import models
class Tikategory(models.Model):
name = models.CharField(max_length=50)
landscape = models.BooleanField()
def __str__(self):
return self.name
class Meta:
verbose_name_plural = "tikategoriez"
class Tisub(models.Model): class Tisub(models.Model):
name = models.CharField(max_length=50) name = models.CharField(max_length=50)
descritpion = models.TextField() descritpion = models.TextField()
@@ -23,11 +12,22 @@ class Tisub(models.Model):
verbose_name_plural = "tisubz" verbose_name_plural = "tisubz"
class Tikategory(models.Model):
name = models.CharField(max_length=50)
landscape = models.BooleanField()
subs = models.ManyToManyField(Tisub)
def __str__(self):
return self.name
class Meta:
verbose_name_plural = "tikategoriez"
class Tikette(models.Model): class Tikette(models.Model):
title = models.CharField(max_length=100) title = models.CharField(max_length=100)
category = models.ForeignKey(Tikategory, on_delete=models.CASCADE) category = models.ForeignKey(Tikategory, on_delete=models.CASCADE)
svg = models.FileField() svg = models.FileField()
subs = models.ManyToManyField(Tisub)
def __str__(self): def __str__(self):
return self.title return self.title

View File

@@ -5,20 +5,20 @@
width="210mm"> width="210mm">
<g transform="translate(3, 4.5)"> <g transform="translate(3, 4.5)">
<g transform="translate(-42,144) rotate(-90,144,0)"> <g transform="translate(-42,144) rotate(-90,144,0)">
<g transform="translate( 0,0)">$right0</g> <g transform="translate( 0,0) scale(0.26458)">$right0</g>
<g transform="translate( 48,0)">$right1</g> <g transform="translate( 48,0) scale(0.26458)">$right1</g>
<g transform="translate( 96,0)">$right2</g> <g transform="translate( 96,0) scale(0.26458)">$right2</g>
<g transform="translate(144,0)">$right3</g> <g transform="translate(144,0) scale(0.26458)">$right3</g>
<g transform="translate(192,0)">$right4</g> <g transform="translate(192,0) scale(0.26458)">$right4</g>
<g transform="translate(240,0)">$right5</g> <g transform="translate(240,0) scale(0.26458)">$right5</g>
</g> </g>
<g transform="translate(-42,144) rotate(90,144,0)"> <g transform="translate(-42,144) rotate(90,144,0)">
<g transform="translate( 0,0)">$left0</g> <g transform="translate( 0,0) scale(0.26458)">$left0</g>
<g transform="translate( 48,0)">$left1</g> <g transform="translate( 48,0) scale(0.26458)">$left1</g>
<g transform="translate( 96,0)">$left2</g> <g transform="translate( 96,0) scale(0.26458)">$left2</g>
<g transform="translate(144,0)">$left3</g> <g transform="translate(144,0) scale(0.26458)">$left3</g>
<g transform="translate(192,0)">$left4</g> <g transform="translate(192,0) scale(0.26458)">$left4</g>
<g transform="translate(240,0)">$left5</g> <g transform="translate(240,0) scale(0.26458)">$left5</g>
</g> </g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 896 B

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -16,7 +16,7 @@ def index(request):
'category': x.category.name, 'category': x.category.name,
'sticker': x.svg.name, 'sticker': x.svg.name,
'landscape': x.category.landscape, 'landscape': x.category.landscape,
'subs': {x.name: x.default for x in x.subs.all()}, 'subs': {x.name: x.default for x in x.category.subs.all()},
} for x in Tikette.objects.all()] } for x in Tikette.objects.all()]
return JsonResponse({'status': 'ok', 'tikettes': tikettes}, headers=CORS) return JsonResponse({'status': 'ok', 'tikettes': tikettes}, headers=CORS)

View File

@@ -18,7 +18,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent
#TIKETTE_OUT_DIR = BASE_DIR / 'data' #TIKETTE_OUT_DIR = BASE_DIR / 'data'
TIKETTE_OUT_DIR = Path('/data') TIKETTE_OUT_DIR = Path('/data')
MEDIA_ROOT = TIKETTE_OUT_DIR MEDIA_ROOT = TIKETTE_OUT_DIR
MEDIA_URL = 'data/' MEDIA_URL = '/data/'
# Quick-start development settings - unsuitable for production # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ # See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
@@ -29,7 +29,8 @@ SECRET_KEY = 'django-insecure-64qxpe55#9wy=5@#dl0)3w7ywxh48m!f&!slp9e7v4lh@hjdct
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True DEBUG = True
ALLOWED_HOSTS = [] ALLOWED_HOSTS = ['*']
CSRF_TRUSTED_ORIGINS = ['https://*.ponteilla.net']
# Application definition # Application definition
@@ -81,7 +82,7 @@ WSGI_APPLICATION = 'zetikettes.wsgi.application'
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3', 'NAME': TIKETTE_OUT_DIR / 'db.sqlite3',
} }
} }
@@ -120,7 +121,9 @@ USE_TZ = True
# Static files (CSS, JavaScript, Images) # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/ # https://docs.djangoproject.com/en/4.2/howto/static-files/
STATIC_URL = 'static/' STATIC_URL = '/zetikettes/srv/static/'
STATIC_ROOT = 'www_static'
# Default primary key field type # Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field # https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field

11
docker-compose.yml Normal file
View File

@@ -0,0 +1,11 @@
version: '3.1'
services:
zetikettes:
image: zetikettes
restart: always
ports:
- 127.0.0.1:8000:8000
volumes:
- /var/lib/zetikettes/data:/data

View File

@@ -1 +1 @@
const backend_api = 'http://localhost:8001/' const backend_api = 'http://jenova.ponteilla.net:8001/'

View File

@@ -35,7 +35,7 @@ function loadAll(zetikettes) {
$.post(backend_api, JSON.stringify(req)) $.post(backend_api, JSON.stringify(req))
.then(data => { .then(data => {
console.log(data); console.log(data);
const pdfbtn = $(`<a class="btn" href="${backend_api}/data/${data.file}" target="_blank">open pdf</a>`); const pdfbtn = $(`<a class="btn" href="${backend_api}data/${data.file}" target="_blank">open pdf</a>`);
action.append(pdfbtn); action.append(pdfbtn);
}) })
.catch(err => { .catch(err => {
@@ -67,7 +67,7 @@ function konami() {
$(document).keydown(function (e) { $(document).keydown(function (e) {
if (e.keyCode === k[n++]) { if (e.keyCode === k[n++]) {
if (n === k.length) { if (n === k.length) {
document.location.href = 'newtikette.html'; document.location.href = backend_api + 'admin';
} }
} }
else { else {
@@ -82,7 +82,7 @@ $(document).ready(async () => {
url: backend_api + 'list', url: backend_api + 'list',
timeout: 1000, timeout: 1000,
}); });
loadAll(resp.tikettes); loadAll(resp.tikettes.sort((a, b) => (a.title < b.title) ? -1 : 1));
} catch(e) { } catch(e) {
const appbody = $("#appbody"); const appbody = $("#appbody");
appbody.append(`<li>Could not reach backend server`); appbody.append(`<li>Could not reach backend server`);

18
nginx_locations Normal file
View File

@@ -0,0 +1,18 @@
# prod site
location /zetikettes {
alias /var/lib/zetikettes/frontend;
}
location /zetikettes/srv/static {
alias /var/lib/zetikettes/www_static;
}
location ^~ /zetikettes/srv {
proxy_pass http://127.0.0.1:8000;
proxy_set_header SCRIPT_NAME /zetikettes/srv;
proxy_set_header Host $http_host;
# generating stuff takes time
proxy_read_timeout 10m;
client_max_body_size 10M;
}

33
product_definitions.csv Normal file
View File

@@ -0,0 +1,33 @@
aromate;Herbes de Provence;Thym*, Sarriette*, Origan*;Le classique des herbes aromatiques pour donner une touche méditerranéenne à vos plats.;6307a6;Aromate - Herbes de Provence - Thym Sarriette Origan.svg;True
aromate;Origan;Origan*;La fameuse herbe à pizza, mais qui peut aussi assaisonner vos soupes, plats mijotés, poissons ou charcuteries.;4800b9;Aromate - Origan.svg;True
aromate;Sarriette;Sarriette des montagnes*;Le pèbre d'aï s'utilise en cuisine dans les pommes de terre, champignons, ragoûts de légumes, riz...;00d40e;Aromate - Sarriette.svg;True
aromate;Sauge;Sauge officinale*;La plante qui sauve peut être utilisée en cuisine, dans vos viandes en sauce, légumes, vinaigrettes...;d00676;Aromate - Sauge.svg;True
aromate;Thym;Thym*;Le roi des aromates, à utiliser en branche ou effeuillé, pour agrémenter vos grillades, plats en sauce, poêlées...;0048ff;Aromate - Thym.svg;True
confiture;Confiture d'Abricot;Abricot*, Sucre de canne*;;ff5d00;Confiture - Abricot.svg;True
confiture;Confiture d'Abricot;Abricot, Sucre de canne*;;ff5d00;Confiture - Abricot - Non Bio.svg;False
confiture;Confiture d'Abricot Lavande;Abricot, Lavande*, Sucre de canne*;;9683ec;Confiture - Abricot Lavande - Non Bio.svg;False
confiture;Gelée Extra de Groseille;Groseille*, Sucre de canne*;;ec001a;Gelée Extra - Groseille.svg;True
confiture;Gelée Extra de Cassis;Cassis*, Sucre de canne*;;9b00ff;Gelée Extra - Cassis.svg;True
confiture;Marmelade d'Orange Amère; Oranges amères, Sucre de canne*, eau;;ff5d00;Marmelade - Orange Amère - Non Bio.svg;False
pesto;Pesto de Livèche;Huile d'olive*, Livèche* (34%), *amandes*, jus de citron*, ail*, sel;;119200;Pesto - Livèche.svg;True
pesto;Pesto d'Ail des Ours;Huile d'olive*, Ail des ours* (34%), *Amandes*, Jus de citron*, Sel;;196b00;Pesto - Ail des Ours.svg;True
sirop;Lavande;Sucre* (55%), Infusion de lavande* (42%), Jus de citron* (3%);;4200ff;Sirop - Lavande.svg;True
sirop;Thym;Sucre* (55%), Infusion de thym* (42%), Jus de citron* (3%);;0048ff;Sirop - Thym.svg;True
sirop;Mélisse;Sucre* (55%), Infusion de mélisse* (42%), Jus de citron* (3%);;d00676;Sirop - Mélisse.svg;True
sirop;Menthe Verte;Sucre* (55%), Infusion de menthe verte* (42%), Jus de citron* (3%);;007e49;Sirop - Menthe Verte.svg;True
sirop;Menthe et Mélisse;Sucre* (55%), Infusion de menthe verte* et mélisse* (42%), Jus de citron* (3%);;fabf12;Sirop - Menthe et Mélisse.svg;True
sirop;Sureau;Sucre* (55%), Infusion de sureau* (42%), Jus de citron* (3%);;8aa700;Sirop - Sureau.svg;True
sirop;Romarin;Sucre* (55%), Infusion de romarin* (42%), Jus de citron* (3%);;007d87;Sirop - Romarin.svg;True
tisane;J'ai Bien Mangé...; Thym*, Sauge*, Romarin*, Soucis*;;0c7c00;Tisane - Digestion - Thym Sauge Romarin Soucis.svg;True
tisane;Nuit Étoilée;Agastache*, Mélisse*, Aubépine*;;5b7aff;Tisane - Nuit Étoilée - Agastache Mélisse Aubépine.svg;True
tisane;Nuit Étoilée;Mélisse*, Lavande*, Aubépine*;;5b7aff;Tisane - Nuit Étoilée - Mélisse Lavande Aubépine.svg;True
tisane;Réconfort de la Gorge; Origan*, Agastache*, Thym*, Bleuet*;;00a07b;Tisane - Réconfort de la Gorge - Origan Agastache Thym Bleuet.svg;True
tisane;Équilibre Féminin;Achillée millefeuille*, Lavande vraie*, Cynorhodon*;;64139f;Tisane - Équilibre Féminin - Achillée millefeuille Lavande vraie Cynorhodon.svg;True
tisane;Équilibre Féminin;Achillée millefeuille*, Lavande vraie*, Ortie piquante*;;64139f;Tisane - Équilibre Féminin - Achillée millefeuille Lavande vraie Ortie piquante.svg;True
tisane;Équilibre Féminin;Achillée millefeuille*, Lavande vraie*, Pétales de Cynorhodon*;;64139f;Tisane - Équilibre Féminin - Achillée millefeuille Lavande vraie Pétales de Cynorhodon.svg;True
tisane;Équilibre Féminin;Achillée millefeuille*, Lavande vraie*, Sauge officinale*, Ortie piquante*;;64139f;Tisane - Équilibre Féminin - Achillée millefeuille Lavande vraie Sauge officinale Ortie piquante.svg;True
tisane;Joie de Vivre;Basilic sacré*, Sarriette des montagnes*, Lavande vraie*;;ff6d00;Tisane - Joie de Vivre - Basilic Sacré Sarriette des Montagnes Lavande Vraie.svg;True
sel;Grillades - Viande et Légumes;Sel de Camargue, Thym*, Origan*, Sarriette*, Mélisse*, Souci*;;c80003;Sel - Grillades.svg;True
sel;Herbes de Provence;Sel de Camargue, Thym*, Origan*, Sarriette*, Romarin*;;6307a6;Sel - Herbes de Provence.svg;True
sel;Poisson et Viande Blanche;Sel de Camargue, Thym*, Sauge*, Agastache*, Bleuet*;;5b7aff;Sel - Poisson et Viande Blanche.svg;True
chocolat;Menthe Poivrée;"Chocolat de couverture noir* (pâte de cacao*, sucre de canne*, beurre de cacao*; peut contenir : *lait), *crème entière* (crème de lait à 30% de matière grasse*, stabilisants : carraghénanes), menthe poivrée*";;007e49;Chocolat - Menthe Poivrée.svg;True
1 aromate Herbes de Provence Thym*, Sarriette*, Origan* Le classique des herbes aromatiques pour donner une touche méditerranéenne à vos plats. 6307a6 Aromate - Herbes de Provence - Thym Sarriette Origan.svg True
2 aromate Origan Origan* La fameuse herbe à pizza, mais qui peut aussi assaisonner vos soupes, plats mijotés, poissons ou charcuteries. 4800b9 Aromate - Origan.svg True
3 aromate Sarriette Sarriette des montagnes* Le pèbre d'aï s'utilise en cuisine dans les pommes de terre, champignons, ragoûts de légumes, riz... 00d40e Aromate - Sarriette.svg True
4 aromate Sauge Sauge officinale* La plante qui sauve peut être utilisée en cuisine, dans vos viandes en sauce, légumes, vinaigrettes... d00676 Aromate - Sauge.svg True
5 aromate Thym Thym* Le roi des aromates, à utiliser en branche ou effeuillé, pour agrémenter vos grillades, plats en sauce, poêlées... 0048ff Aromate - Thym.svg True
6 confiture Confiture d'Abricot Abricot*, Sucre de canne* ff5d00 Confiture - Abricot.svg True
7 confiture Confiture d'Abricot Abricot, Sucre de canne* ff5d00 Confiture - Abricot - Non Bio.svg False
8 confiture Confiture d'Abricot Lavande Abricot, Lavande*, Sucre de canne* 9683ec Confiture - Abricot Lavande - Non Bio.svg False
9 confiture Gelée Extra de Groseille Groseille*, Sucre de canne* ec001a Gelée Extra - Groseille.svg True
10 confiture Gelée Extra de Cassis Cassis*, Sucre de canne* 9b00ff Gelée Extra - Cassis.svg True
11 confiture Marmelade d'Orange Amère Oranges amères, Sucre de canne*, eau ff5d00 Marmelade - Orange Amère - Non Bio.svg False
12 pesto Pesto de Livèche Huile d'olive*, Livèche* (34%), *amandes*, jus de citron*, ail*, sel 119200 Pesto - Livèche.svg True
13 pesto Pesto d'Ail des Ours Huile d'olive*, Ail des ours* (34%), *Amandes*, Jus de citron*, Sel 196b00 Pesto - Ail des Ours.svg True
14 sirop Lavande Sucre* (55%), Infusion de lavande* (42%), Jus de citron* (3%) 4200ff Sirop - Lavande.svg True
15 sirop Thym Sucre* (55%), Infusion de thym* (42%), Jus de citron* (3%) 0048ff Sirop - Thym.svg True
16 sirop Mélisse Sucre* (55%), Infusion de mélisse* (42%), Jus de citron* (3%) d00676 Sirop - Mélisse.svg True
17 sirop Menthe Verte Sucre* (55%), Infusion de menthe verte* (42%), Jus de citron* (3%) 007e49 Sirop - Menthe Verte.svg True
18 sirop Menthe et Mélisse Sucre* (55%), Infusion de menthe verte* et mélisse* (42%), Jus de citron* (3%) fabf12 Sirop - Menthe et Mélisse.svg True
19 sirop Sureau Sucre* (55%), Infusion de sureau* (42%), Jus de citron* (3%) 8aa700 Sirop - Sureau.svg True
20 sirop Romarin Sucre* (55%), Infusion de romarin* (42%), Jus de citron* (3%) 007d87 Sirop - Romarin.svg True
21 tisane J'ai Bien Mangé... Thym*, Sauge*, Romarin*, Soucis* 0c7c00 Tisane - Digestion - Thym Sauge Romarin Soucis.svg True
22 tisane Nuit Étoilée Agastache*, Mélisse*, Aubépine* 5b7aff Tisane - Nuit Étoilée - Agastache Mélisse Aubépine.svg True
23 tisane Nuit Étoilée Mélisse*, Lavande*, Aubépine* 5b7aff Tisane - Nuit Étoilée - Mélisse Lavande Aubépine.svg True
24 tisane Réconfort de la Gorge Origan*, Agastache*, Thym*, Bleuet* 00a07b Tisane - Réconfort de la Gorge - Origan Agastache Thym Bleuet.svg True
25 tisane Équilibre Féminin Achillée millefeuille*, Lavande vraie*, Cynorhodon* 64139f Tisane - Équilibre Féminin - Achillée millefeuille Lavande vraie Cynorhodon.svg True
26 tisane Équilibre Féminin Achillée millefeuille*, Lavande vraie*, Ortie piquante* 64139f Tisane - Équilibre Féminin - Achillée millefeuille Lavande vraie Ortie piquante.svg True
27 tisane Équilibre Féminin Achillée millefeuille*, Lavande vraie*, Pétales de Cynorhodon* 64139f Tisane - Équilibre Féminin - Achillée millefeuille Lavande vraie Pétales de Cynorhodon.svg True
28 tisane Équilibre Féminin Achillée millefeuille*, Lavande vraie*, Sauge officinale*, Ortie piquante* 64139f Tisane - Équilibre Féminin - Achillée millefeuille Lavande vraie Sauge officinale Ortie piquante.svg True
29 tisane Joie de Vivre Basilic sacré*, Sarriette des montagnes*, Lavande vraie* ff6d00 Tisane - Joie de Vivre - Basilic Sacré Sarriette des Montagnes Lavande Vraie.svg True
30 sel Grillades - Viande et Légumes Sel de Camargue, Thym*, Origan*, Sarriette*, Mélisse*, Souci* c80003 Sel - Grillades.svg True
31 sel Herbes de Provence Sel de Camargue, Thym*, Origan*, Sarriette*, Romarin* 6307a6 Sel - Herbes de Provence.svg True
32 sel Poisson et Viande Blanche Sel de Camargue, Thym*, Sauge*, Agastache*, Bleuet* 5b7aff Sel - Poisson et Viande Blanche.svg True
33 chocolat Menthe Poivrée Chocolat de couverture noir* (pâte de cacao*, sucre de canne*, beurre de cacao*; peut contenir : *lait), *crème entière* (crème de lait à 30% de matière grasse*, stabilisants : carraghénanes), menthe poivrée* 007e49 Chocolat - Menthe Poivrée.svg True

65
scripts/renew_lineup.py Executable file
View File

@@ -0,0 +1,65 @@
#!/usr/bin/env python3
import argparse
from string import Template
import sys
import os
import csv
from subber import Subber
TEMPLATES_DIR = "/home/maxime/Documents/Anne/Etiquettes/Source SVGs/templates"
OUT_DIR = "/home/maxime/Documents/Anne/Etiquettes/Source SVGs/autogenerated_svgs"
JAM_DESIGNATION_FONTSIZE_DEFAULT = 42.6667
JAM_DESIGNATION_FONTSIZE_SMALL = 36
templates = {
'aromate': f"{TEMPLATES_DIR}/Aromate.svg",
'chocolat': f"{TEMPLATES_DIR}/Chocolat.svg",
'confiture': f"{TEMPLATES_DIR}/Confiture.svg",
'pesto': f"{TEMPLATES_DIR}/Pesto.svg",
'sirop': f"{TEMPLATES_DIR}/Sirop.svg",
'tisane': f"{TEMPLATES_DIR}/Tisane.svg",
'sel': f"{TEMPLATES_DIR}/Sel.svg",
}
ALLERGEN_BEGIN_STYLE = '<tspan style="font-weight:bold">'
ALLERGEN_END_STYLE = '</tspan>'
def parse_args():
parser = argparse.ArgumentParser(description='Renew whole lineup from template and list of subs')
parser.add_argument('--list', required=True, help='Lineup file')
return parser.parse_args()
def main():
args = parse_args()
with open(args.list) as csvfile:
reader = csv.reader(csvfile, delimiter=';', quotechar='"')
for row in reader:
template = templates[row[0]]
outfile = f"{OUT_DIR}/{row[5]}"
with open(outfile, 'w') as out:
# TODO Fix bold formatting with allergen and parenthesis
ingredients = [e.strip() for e in row[2].split(',')]
ingredients = [e if not e.startswith('*') else ALLERGEN_BEGIN_STYLE + e[1:] + ALLERGEN_END_STYLE for e in ingredients]
ingredients_sub = ", ".join(ingredients)
AB_logo_visibility = 'inline' if row[6] == 'True' else 'none'
subs = {
'designation': row[1].strip(),
'ingredients': ingredients_sub,
'description': row[3].strip(),
'color': row[4],
'AB': AB_logo_visibility,
'designation_fontsize': JAM_DESIGNATION_FONTSIZE_DEFAULT,
}
s = Subber(subs)
s.sub(template, out)
if __name__ == "__main__":
main()

14
scripts/subber.py Normal file
View File

@@ -0,0 +1,14 @@
from string import Template
class Subber():
def __init__(self, subs):
self.subs = subs
def sub(self, infile, outfile):
with open(infile) as template:
lines = template.readlines()
data = ''.join(lines)
outfile.write(Template(data).safe_substitute(self.subs))

1373
templates/Aromate.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.1 MiB

1291
templates/Chocolat.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.1 MiB

1440
templates/Confiture.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.3 MiB

1424
templates/Pesto.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.3 MiB

1431
templates/Sel.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.2 MiB

2249
templates/Sirop.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.2 MiB

1392
templates/Tisane.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.1 MiB

16
zetikettes.service Normal file
View File

@@ -0,0 +1,16 @@
[Unit]
Description=Zetikettes backend service
After=docker.service
Requires=docker.service
[Service]
ExecStart=/usr/bin/docker run --rm --name %n \
-p 127.0.0.1:8000:8000 \
-v /var/lib/zetikettes/data:/data \
zetikettes
Restart=on-failure
ExecStartPre=-/usr/bin/docker exec %n stop
ExecStartPre=-/usr/bin/docker rm %n
[Install]
WantedBy=multi-user.target