diff --git a/Dockerfile b/Dockerfile index 0c13b1f..a84f5bf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ -FROM alpine +FROM alpine:3.18 -RUN apk --no-cache add python3 inkscape bash imagemagick ghostscript ttf-opensans +RUN apk --no-cache add python3 inkscape bash imagemagick ghostscript font-droid RUN apk --no-cache add py3-pip && pip3 install --break-system-packages django tzdata gunicorn ADD backend /zetikettes diff --git a/backend/fonts/DejaVuMathTeXGyre.ttf b/backend/fonts/DejaVuMathTeXGyre.ttf deleted file mode 100644 index 8a24f06..0000000 Binary files a/backend/fonts/DejaVuMathTeXGyre.ttf and /dev/null differ diff --git a/backend/fonts/DejaVuSans-Bold.ttf b/backend/fonts/DejaVuSans-Bold.ttf deleted file mode 100644 index 6d65fa7..0000000 Binary files a/backend/fonts/DejaVuSans-Bold.ttf and /dev/null differ diff --git a/backend/fonts/DejaVuSans-BoldOblique.ttf b/backend/fonts/DejaVuSans-BoldOblique.ttf deleted file mode 100644 index 753f2d8..0000000 Binary files a/backend/fonts/DejaVuSans-BoldOblique.ttf and /dev/null differ diff --git a/backend/fonts/DejaVuSans-ExtraLight.ttf b/backend/fonts/DejaVuSans-ExtraLight.ttf deleted file mode 100644 index b09f32d..0000000 Binary files a/backend/fonts/DejaVuSans-ExtraLight.ttf and /dev/null differ diff --git a/backend/fonts/DejaVuSans-Oblique.ttf b/backend/fonts/DejaVuSans-Oblique.ttf deleted file mode 100644 index 999bac7..0000000 Binary files a/backend/fonts/DejaVuSans-Oblique.ttf and /dev/null differ diff --git a/backend/fonts/DejaVuSans.ttf b/backend/fonts/DejaVuSans.ttf deleted file mode 100644 index e5f7eec..0000000 Binary files a/backend/fonts/DejaVuSans.ttf and /dev/null differ diff --git a/backend/fonts/DejaVuSansCondensed-Bold.ttf b/backend/fonts/DejaVuSansCondensed-Bold.ttf deleted file mode 100644 index 22987c6..0000000 Binary files a/backend/fonts/DejaVuSansCondensed-Bold.ttf and /dev/null differ diff --git a/backend/fonts/DejaVuSansCondensed-BoldOblique.ttf b/backend/fonts/DejaVuSansCondensed-BoldOblique.ttf deleted file mode 100644 index f5fa0ca..0000000 Binary files a/backend/fonts/DejaVuSansCondensed-BoldOblique.ttf and /dev/null differ diff --git a/backend/fonts/DejaVuSansCondensed-Oblique.ttf b/backend/fonts/DejaVuSansCondensed-Oblique.ttf deleted file mode 100644 index 7fde907..0000000 Binary files a/backend/fonts/DejaVuSansCondensed-Oblique.ttf and /dev/null differ diff --git a/backend/fonts/DejaVuSansCondensed.ttf b/backend/fonts/DejaVuSansCondensed.ttf deleted file mode 100644 index 3259bc2..0000000 Binary files a/backend/fonts/DejaVuSansCondensed.ttf and /dev/null differ diff --git a/backend/fonts/DejaVuSansMono-Bold.ttf b/backend/fonts/DejaVuSansMono-Bold.ttf deleted file mode 100644 index 8184ced..0000000 Binary files a/backend/fonts/DejaVuSansMono-Bold.ttf and /dev/null differ diff --git a/backend/fonts/DejaVuSansMono-BoldOblique.ttf b/backend/fonts/DejaVuSansMono-BoldOblique.ttf deleted file mode 100644 index 754dca7..0000000 Binary files a/backend/fonts/DejaVuSansMono-BoldOblique.ttf and /dev/null differ diff --git a/backend/fonts/DejaVuSansMono-Oblique.ttf b/backend/fonts/DejaVuSansMono-Oblique.ttf deleted file mode 100644 index 4c858d4..0000000 Binary files a/backend/fonts/DejaVuSansMono-Oblique.ttf and /dev/null differ diff --git a/backend/fonts/DejaVuSansMono.ttf b/backend/fonts/DejaVuSansMono.ttf deleted file mode 100644 index f578602..0000000 Binary files a/backend/fonts/DejaVuSansMono.ttf and /dev/null differ diff --git a/backend/zetikettes/initial_db.json b/backend/zetikettes/initial_db.json index 197ca3d..19ffe96 100644 --- a/backend/zetikettes/initial_db.json +++ b/backend/zetikettes/initial_db.json @@ -23,7 +23,7 @@ "model": "tikette.tisub", "pk": 4, "fields": { - "name": "qty", + "name": "q", "descritpion": "Poids net (g)", "default": "370", "type": "ST" @@ -43,7 +43,7 @@ "model": "tikette.tisub", "pk": 6, "fields": { - "name": "fruit", + "name": "f", "descritpion": "Quantité de fruits pour 100g (g)", "default": "60", "type": "ST" diff --git a/backend/zetikettes/tikette/models.py b/backend/zetikettes/tikette/models.py index 9e8f1a0..32a29f3 100644 --- a/backend/zetikettes/tikette/models.py +++ b/backend/zetikettes/tikette/models.py @@ -50,7 +50,7 @@ class Tikette(models.Model): description = models.TextField() color = models.CharField(max_length=6) ab = models.CharField(max_length=7, choices=AbVisibility) - # designation_fontsize is hardcoded to 42.6667 + # designation_fontsize is hardcoded to 42.6667 in planche/generate.py def __str__(self): return self.title diff --git a/backend/zetikettes/tikette/planche.svg.in b/backend/zetikettes/tikette/planche.svg.in deleted file mode 100644 index 7fa6d85..0000000 --- a/backend/zetikettes/tikette/planche.svg.in +++ /dev/null @@ -1,24 +0,0 @@ - - - - - $right0 - $right1 - $right2 - $right3 - $right4 - $right5 - - - $left0 - $left1 - $left2 - $left3 - $left4 - $left5 - - - diff --git a/backend/zetikettes/tikette/planche/__init__.py b/backend/zetikettes/tikette/planche/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/zetikettes/tikette/generate.py b/backend/zetikettes/tikette/planche/generate.py similarity index 70% rename from backend/zetikettes/tikette/generate.py rename to backend/zetikettes/tikette/planche/generate.py index 2211b03..164eb22 100644 --- a/backend/zetikettes/tikette/generate.py +++ b/backend/zetikettes/tikette/planche/generate.py @@ -7,6 +7,8 @@ from .makeplanche import makeplanche OUT_DIR = tempfile.gettempdir() DEFAULT_DPI = 300 +DESIGNATION_FONTSIZE = 42.6667 + def inkscapize(svg_in, pdf_out): png_out = tempfile.mktemp(suffix='.png') @@ -22,31 +24,31 @@ def inkscapize(svg_in, pdf_out): os.unlink(png_out) -def generate(request, out_dir): +def generate(template, subs, out_dir, landscape=False): """ Generate a sticker sheet. - request: dict-like with the following fields: - sticker: mandatory. filename for the sticker - subs: mandatory. dict-like with key-value template subtitution fields - landscape: optional. defaults to False - + template: file name for the sticker template + subs: dict-like with key-value template subtitution fields out_dir: you get it + landscape: optional. defaults to False """ + # default designation font size + subs['designation_fontsize'] = subs.get('designation_fontsize', + DESIGNATION_FONTSIZE) + # fill in sticker details sticker_out = tempfile.mktemp(suffix='.svg') try: with open(sticker_out, 'w') as stickout: - landscape = request.get('landscape', False) - makesticker(os.path.join(out_dir, request['sticker']), stickout, - request['subs'], landscape=landscape) + makesticker(os.path.join(out_dir, template), stickout, subs) # make sticker sheet planche_out = tempfile.mktemp(suffix='.svg') with open(sticker_out, 'r') as stickin: with open(planche_out, 'w') as planchout: - makeplanche(stickin, planchout) + makeplanche(stickin, planchout, landscape=landscape) # process to printable pdf pdf_out = tempfile.mktemp(dir=out_dir, suffix='.pdf') diff --git a/backend/zetikettes/tikette/makeplanche.py b/backend/zetikettes/tikette/planche/makeplanche.py similarity index 74% rename from backend/zetikettes/tikette/makeplanche.py rename to backend/zetikettes/tikette/planche/makeplanche.py index c0639d9..93df040 100755 --- a/backend/zetikettes/tikette/makeplanche.py +++ b/backend/zetikettes/tikette/planche/makeplanche.py @@ -20,6 +20,9 @@ def parse_args(): default=sys.stdout, type=argparse.FileType('w'), help='output path (default: stdout)') + parser.add_argument('--landscape', + action='store_true', + help='input sticker is in landscape orientation') parser.add_argument('sticker', type=argparse.FileType('r'), default=sys.stdin, @@ -29,7 +32,7 @@ def parse_args(): return parser.parse_args() -def makeplanche(sticker, out, template=DEFAULT_SHEET_TEMPLATE): +def makeplanche(sticker, out, template=DEFAULT_SHEET_TEMPLATE ,landscape=False): with open(template) as tpl: tpl_data = tpl.read() @@ -38,19 +41,11 @@ def makeplanche(sticker, out, template=DEFAULT_SHEET_TEMPLATE): lines = lines[1:] sticker_data = ''.join(lines) + rotate = "translate(102, 0) rotate(90)" if not landscape else "" + subs = { - 'left0': sticker_data, - 'left1': sticker_data, - 'left2': sticker_data, - 'left3': sticker_data, - 'left4': sticker_data, - 'left5': sticker_data, - 'right0': sticker_data, - 'right1': sticker_data, - 'right2': sticker_data, - 'right3': sticker_data, - 'right4': sticker_data, - 'right5': sticker_data, + 'sticker': sticker_data, + 'rotate': rotate, } out.write(Template(tpl_data).substitute(subs)) diff --git a/backend/zetikettes/tikette/makesticker.py b/backend/zetikettes/tikette/planche/makesticker.py similarity index 77% rename from backend/zetikettes/tikette/makesticker.py rename to backend/zetikettes/tikette/planche/makesticker.py index 356dfab..8231285 100755 --- a/backend/zetikettes/tikette/makesticker.py +++ b/backend/zetikettes/tikette/planche/makesticker.py @@ -22,25 +22,18 @@ def parse_args(): parser.add_argument('--teneur', '-t', required=False, help='Teneur en sucre') parser.add_argument('--fruit', '-f', required=False, help='Quantité de fruits') parser.add_argument('--size', '-s', required=False, help='Masse de produit') - parser.add_argument('--landscape', - action='store_true', - help='input sticker is in landscape orientation') parser.add_argument('sticker', help='path to the sticker template') return parser.parse_args() -def makesticker(sticker: str, out: typing.IO, subs: dict, landscape=False): +def makesticker(sticker: str, out: typing.IO, subs: dict): with open(sticker) as fin: lines = fin.readlines() if lines[0].startswith('{}".format(sticker_data) - out.write(Template(sticker_data).substitute(subs)) @@ -50,8 +43,8 @@ if __name__ == "__main__": 'dluo': args.pop('dluo'), 'lot': args.pop('lot'), 'teneur': args.pop('teneur'), - 'fruit': args.pop('fruit'), - 'qty': args.pop('quantite'), + 'f': args.pop('fruit'), + 'q': args.pop('quantite'), 'size': args.pop('size'), } args['subs'] = subs diff --git a/backend/zetikettes/tikette/planche/planche.svg.in b/backend/zetikettes/tikette/planche/planche.svg.in new file mode 100644 index 0000000..ec8a553 --- /dev/null +++ b/backend/zetikettes/tikette/planche/planche.svg.in @@ -0,0 +1,24 @@ + + + + + ${sticker} + ${sticker} + ${sticker} + ${sticker} + ${sticker} + ${sticker} + + + ${sticker} + ${sticker} + ${sticker} + ${sticker} + ${sticker} + ${sticker} + + + diff --git a/backend/zetikettes/tikette/views.py b/backend/zetikettes/tikette/views.py index 1dd56bb..99a7835 100644 --- a/backend/zetikettes/tikette/views.py +++ b/backend/zetikettes/tikette/views.py @@ -5,18 +5,34 @@ from django.http import JsonResponse from django.shortcuts import render from django.views.decorators.csrf import csrf_exempt -from . import generate as stickersheet +from .planche import generate as stickersheet from .models import Tikette, Tikategory CORS={'access-control-allow-origin': '*'} +def quirk_bold_allergens(ingredients): + out = [] + for ing in (x.strip() for x in ingredients.split(',')): + if ing.startswith('*'): + out.append(f'{ing[1:]}') + else: + out.append(ing) + return ", ".join(out) + + def get_list(request): tikettes = [{ 'id': x.id, 'title': x.title, 'category': x.category.name, + 'prototempalte': x.category.prototempalte.name, 'landscape': x.category.landscape, + 'designation': x.designation, + 'ingredients': quirk_bold_allergens(x.ingredients), + 'description': x.description, + 'ab': x.ab, + 'color': x.color, 'subs': {x.name: x.default for x in x.category.subs.all()}, } for x in Tikette.objects.all()] return JsonResponse({'status': 'ok', 'tikettes': tikettes}, headers=CORS) @@ -36,7 +52,14 @@ def generate(request): return JsonResponse({'status': 'notok', 'message': 'this isn\'t the way'}) payload = json.loads(request.body) - pdfpath = stickersheet.generate(payload, out_dir=settings.TIKETTE_OUT_DIR) + + subs = dict(payload['subs']) + for key in ('designation', 'ingredients', 'description', 'color', 'AB'): + subs[key] = payload[key] + + pdfpath = stickersheet.generate(template=payload['template'], subs=subs, + out_dir=settings.TIKETTE_OUT_DIR, + landscape=payload['landscape']) return JsonResponse({'status': 'ok', 'file': pdfpath}, headers=CORS) diff --git a/frontend/zetikettes.js b/frontend/zetikettes.js index 33ef6a8..b7b8376 100644 --- a/frontend/zetikettes.js +++ b/frontend/zetikettes.js @@ -1,10 +1,9 @@ const params = { 'dluo': 'DLUO', 'lot': 'Nº de lot', - 'qty': 'Poids net (g)', - 'vol': 'Volume net (cL)', + 'q': 'Poids net (g)', 'teneur': 'Teneur en fruits (%)', - 'fruit': 'Quantité de fruits pour 100g (g)', + 'f': 'Quantité de fruits pour 100g (g)', } var tikats; @@ -26,7 +25,12 @@ function addProduct(tikette) { .toArray() .reduce((obj, el) => ({...obj, [el.name]: el.value}), {}); const req = { - sticker: zett.sticker, + template: zett.prototempalte, + designation: zett.designation, + description: zett.description, + ingredients: zett.ingredients, + color: zett.color, + AB: zett.ab, // mind the capitalization here subs, landscape: zett.landscape, };