Files

180 lines
5.9 KiB
Python

import fpdf
from flask import Flask, render_template, request
import flask
import io
import zipfile
from werkzeug.datastructures import FileStorage
from PIL import Image
from pdf2image import convert_from_bytes
from PyPDF2 import PdfReader
VALID_KIND = ["all", "tc", "zc", "zip"]
ALLOWED_EXTENSIONS = ["png", "jpeg", "jpg", "pdf"]
# Function to get the dimensions of the source PDF page
def get_page_dimensions(pdfData, page_number=0):
reader = PdfReader(pdfData)
page = reader.pages[page_number]
width = float(page.mediabox.width)
height = float(page.mediabox.height)
width = width * (page.user_unit / 72) * 25.4
height = height * (page.user_unit / 72) * 25.4
return width, height
def generateTemplate(width: int, height: int, fondPerdu: int, zoneTranquille: int, marge: int, kind: str = "all", image: FileStorage = None, aFondPerdu: bool = False) -> fpdf.FPDF:
margeDuContenue = marge + fondPerdu
pdf = fpdf.FPDF("P", "mm", (width + margeDuContenue *
2, height + margeDuContenue * 2))
pdf.set_font("helvetica", "B", 16) # dummy font
pdf.set_margins(0, 0)
pdf.set_auto_page_break(False)
pdf.add_page()
xy, w, h = margeDuContenue, width, height
if (aFondPerdu == True):
xy = xy - fondPerdu
w = w + fondPerdu*2
h = h + fondPerdu*2
if (image and image.mimetype in ["image/jpeg", "image/png"]):
if 'inMemoryImage' not in flask.g:
flask.g.inMemoryImage = io.BytesIO()
image.save(flask.g.inMemoryImage)
if (image and image.mimetype in ["application/pdf", "application/x-pdf"]):
if 'inMemoryImage' not in flask.g:
pdfData = image.stream.read()
pdfW, pdfH = get_page_dimensions(io.BytesIO(pdfData))
scale = min(pdfW/w, pdfH/h)
imageFromPDF = convert_from_bytes(
pdfData, dpi=600, size=(w*scale, h*scale), single_file=True)
flask.g.inMemoryImage = imageFromPDF[0]
if ('inMemoryImage' in flask.g):
pdf.image(flask.g.inMemoryImage, xy, xy, w, h, keep_aspect_ratio=True)
if (kind in ["all", "zc"]):
pdf.set_draw_color(255, 0, 0) # red
pdf.rect(margeDuContenue, margeDuContenue, width, height)
pdf.set_draw_color(0, 0, 255) # blue
pdf.rect(
margeDuContenue - fondPerdu,
margeDuContenue - fondPerdu,
width + fondPerdu * 2,
height + fondPerdu * 2,
)
pdf.set_draw_color(0, 255, 0) # green
pdf.rect(
margeDuContenue + zoneTranquille,
margeDuContenue + zoneTranquille,
width - zoneTranquille * 2,
height - zoneTranquille * 2,
)
if (kind in ["all", "tc"]):
pdf.set_draw_color(0, 0, 0)
LINES = [
(margeDuContenue, 0, margeDuContenue, marge),
(margeDuContenue + width, 0, margeDuContenue + width, marge),
(
margeDuContenue,
height + margeDuContenue * 2,
margeDuContenue,
height + margeDuContenue * 2 - marge,
),
(
margeDuContenue + width,
height + margeDuContenue * 2,
margeDuContenue + width,
height + margeDuContenue * 2 - marge,
),
(0, margeDuContenue, marge, margeDuContenue),
(0, margeDuContenue + height, marge, margeDuContenue + height),
(
width + margeDuContenue * 2,
margeDuContenue,
width + margeDuContenue * 2 - marge,
margeDuContenue,
),
(
width + margeDuContenue * 2,
margeDuContenue + height,
width + margeDuContenue * 2 - marge,
margeDuContenue + height,
),
]
for line in LINES:
pdf.line(*line)
# pdf.set_author("template.ar2000.me")
pdf.set_creator("template.ar2000.me")
pdf.set_title(f'{width}x{height}_{kind}')
return pdf
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
app = Flask(__name__)
@app.route("/")
def index():
return render_template("index.html")
@app.route("/generate", methods=['GET', 'POST'])
def generate():
try:
w = int(request.form.get("width", ""))
h = int(request.form.get("height", ""))
fp = int(request.form.get("fp", ""))
zt = int(request.form.get("zt", ""))
m = int(request.form.get("margin", ""))
k = request.form.get("kind", "all")
ffp = request.form.get("ffp", "off")
ffp = {"on": True, "off": False}[ffp]
if k not in VALID_KIND:
raise ValueError("kind is not valid")
image = None
if 'file' in request.files and allowed_file(request.files['file'].filename):
image = request.files['file']
except (KeyError, ValueError) as e:
flask.abort(400)
app.logger.info(
"w %d ; h %d ; fp %d ; zt %d ; m %d ; ffp %s", w, h, fp, zt, m, ffp)
if k != "zip":
pdf = generateTemplate(w, h, fp, zt, m, k, image, ffp).output()
return flask.send_file(
io.BytesIO(pdf),
mimetype="application/pdf",
download_name=f'{w}x{h}_{k}.pdf',
)
else:
zipBuffer = io.BytesIO()
zipHandle = zipfile.ZipFile(
zipBuffer, "a", zipfile.ZIP_DEFLATED, False, 9)
for kk in [x for x in VALID_KIND if x != "zip"]:
pdf = generateTemplate(w, h, fp, zt, m, kk, image, ffp).output()
zipHandle.writestr(f'{w}x{h}_{kk}.pdf', pdf)
zipHandle.close()
return flask.send_file(
io.BytesIO(zipBuffer.getvalue()),
mimetype="application/zip",
download_name=f'{w}x{h}.zip',
)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)