diff --git a/app.py b/app.py index 1ff595f..0325e0f 100644 --- a/app.py +++ b/app.py @@ -5,6 +5,7 @@ import requests from flask import Flask, render_template_string, request, send_from_directory from PIL import Image, ImageDraw, ImageFont import re +import argparse app = Flask(__name__) app.secret_key = 'TpfxYMxUJxJMtCCTraBSg1rbd6NLz38JTmIfpBLsotcI47EqXU' @@ -254,6 +255,7 @@ HTML_FORM = '''

+
@@ -289,6 +291,7 @@ HTML_FORM = '''
  • Lista numerada: 1. Elemento
  • Imágen: ![Texto alternativo](Enlace a imágen)
  • Salto de línea: Deje una línea vacía
  • +
  • Imagen subida: !(img) (usa la imagen cargada abajo)
  • @@ -309,7 +312,22 @@ def bleh_image_from_url(url): img = img.resize((IMAGE_WIDTH, img.height), Image.LANCZOS) return img +def bleh_image_from_bytes(image_bytes): + bleh = subprocess.Popen( + ["./bleh", "-o", "-", "-mode", "1bpp", "-d", "floyd", "-"], + stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE + ) + out, err = bleh.communicate(image_bytes) + if bleh.returncode != 0: + raise RuntimeError(f"Driver failed: {err.decode()}") + img = Image.open(io.BytesIO(out)).convert("L") + if img.width != IMAGE_WIDTH: + img = img.resize((IMAGE_WIDTH, img.height), Image.LANCZOS) + return img + def parse_line(line): + if re.match(r"!\(img\)", line) or re.match(r"!\[.*\]\(img\)", line): + return ('userimage', None) image_match = re.match(r"^!\[(.*?)\]\((.+?)\)", line) if image_match: alt = image_match.group(1) @@ -406,7 +424,7 @@ def wrap_segments(segments, font, font_bold, font_italic, font_bolditalic, max_w if line: yield line -def render(md): +def render(md, uploaded_img_bytes=None): font = ImageFont.truetype(FONT_PATH, FONT_SIZE) font_bold = ImageFont.truetype(FONT_PATH_BOLD, FONT_SIZE) font_italic = ImageFont.truetype(FONT_PATH_OBLIQUE, FONT_SIZE) @@ -422,13 +440,22 @@ def render(md): if src_line.strip() == '': lines_out.append(('blank', [])) continue - tag = parse_line(src_line) + tag = parse_line(src_line) if tag[0] == 'image': try: image = bleh_image_from_url(tag[1]) lines_out.append(('image', image)) except Exception as e: lines_out.append(('text', [('text', f"[Imagen inválida: {e}]")], font, FONT_SIZE)) + elif tag[0] == 'userimage': + if uploaded_img_bytes: + try: + image = bleh_image_from_bytes(uploaded_img_bytes) + lines_out.append(('image', image)) + except Exception as e: + lines_out.append(('text', [('text', f"[Error al procesar imágen subida: {e}]")], font, FONT_SIZE)) + else: + lines_out.append(('text', [('text', "[No se subió una imagen]")], font, FONT_SIZE)) elif tag[0] == 'hr': lines_out.append(('hr',)) elif tag[0] == 'header': @@ -549,8 +576,12 @@ def index(): printed = False error = None if request.method == "POST": + userimg = request.files.get("userimg") + uploaded_img_bytes = None + if userimg and userimg.filename: + uploaded_img_bytes = userimg.read() md = request.form["md"] - image = render(md) + image = render(md, uploaded_img_bytes) buf = io.BytesIO() image.save(buf, format="PNG") buf.seek(0) @@ -593,4 +624,7 @@ def icon_rounded(): return send_from_directory('static', 'icon512_rounded.png') if __name__ == "__main__": - app.run(host="0.0.0.0") + parser = argparse.ArgumentParser(description='CatNote: Server for Markdown to MXW01 Cat Printer') + parser.add_argument('-p', '--port', type=int, default=5000, help='Port to run the server on (default: 5000)') + args = parser.parse_args() + app.run(host='0.0.0.0', port=args.port)