changed from flask to generate the pdf directly with reportLab

This commit is contained in:
lorenz 2024-02-13 22:30:57 +01:00
parent 6c3937ae6a
commit 7b18fb10f1
7 changed files with 94 additions and 116 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.pdf

97
app.py
View File

@ -1,9 +1,23 @@
from flask import Flask, render_template
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.pdfgen import canvas
from reportlab.lib.units import mm
from datetime import datetime
import os
import re
import textwrap
app = Flask(__name__)
# Konstanten für die Abmessungen
CIRCLE_RADIUS = 3 * mm
CIRCLE_DISTANCE = 80 * mm
TOP_MARGIN_TO_CENTER = 12 * mm
IMAGE_TOP_MARGIN = 28 * mm
IMAGE_HEIGHT = 60 * mm
TEXT_MARGIN = 5 * mm
LEFT_MARGIN_TO_CENTER = (A4[0] / 4) - (CIRCLE_DISTANCE / 2) # Zentriert zwischen den Tagen
IMAGE_SHIFT_UP = 1 * mm # Bild nach oben verschieben
DATE_SHIFT_DOWN = 8 * mm # Datum nach unten verschieben
TEXT_SHIFT_DOWN = 8 * mm # Text nach unten verschieben
def get_dates_from_images(image_directory):
# Regular expression to match files with a date format YYYY-MM-DD
@ -50,18 +64,81 @@ def get_image_and_text_for_date(date, image_directory, text_directory):
return image_file, text_content
def draw_circle(c, x, y):
c.circle(x, y, CIRCLE_RADIUS, stroke=1, fill=0)
@app.route('/')
def calendar():
def create_pdf(pages_data, output_filename):
c = canvas.Canvas(output_filename, pagesize=A4)
c.setCreator('Lorenz B.')
c.setTitle('Calendar')
c.setAuthor('Lorenz B.')
c.setSubject('calendar generator')
width, height = A4
max_text_width = (width / 2) - (2 * TEXT_MARGIN)
DATE_FONT_SIZE = 20
DATE_FONT = "Helvetica-Bold"
for page in pages_data:
for index, day in enumerate(page):
c.setDash(1, 0)
c.setStrokeColor(colors.black)
# Berechnung der Positionen für jeden Tag
x = (index % 2) * (width / 2)
y = height - (index // 2 + 1) * (height / 2)
# Höhere Position für das Bild
image_y_position = y + (height / 2 - IMAGE_TOP_MARGIN - IMAGE_HEIGHT) + IMAGE_SHIFT_UP
# Kreise zeichnen
draw_circle(c, x + LEFT_MARGIN_TO_CENTER, y + height / 2 - TOP_MARGIN_TO_CENTER)
draw_circle(c, x + width / 2 - LEFT_MARGIN_TO_CENTER, y + height / 2 - TOP_MARGIN_TO_CENTER)
# Bild einfügen
if day['image_file']:
c.drawImage(day['image_file'], x, image_y_position, width=width / 2, height=IMAGE_HEIGHT, preserveAspectRatio=True, anchor='n')
# Datum direkt unter dem Bild einfügen
date_x_position = x + (width / 4) # Zentrum des Tagesbereichs
date_y_position = image_y_position - DATE_SHIFT_DOWN
date_str = day['date'].strftime('%A, %d.%m.%Y')
c.setFont(DATE_FONT, DATE_FONT_SIZE) # Schriftart und Schriftgröße setzen
date_width = c.stringWidth(date_str, DATE_FONT, DATE_FONT_SIZE)
c.drawString(date_x_position - (date_width / 2), date_y_position, date_str)
# Text unter dem Datum einfügen
text_y_position = date_y_position - TEXT_SHIFT_DOWN - 5 * mm # Extra Abstand nach einem größeren Datum
if day['text_content']:
c.setFont("Helvetica", 12) # Schriftart zurücksetzen für den Text
wrapped_text = textwrap.fill(day['text_content'], width=50) # Anpassen für die passende Zeilenlänge
text = c.beginText(x + TEXT_MARGIN, text_y_position)
for line in wrapped_text.split('\n'):
text.textLine(line)
c.drawText(text)
# Gestrichelte Linien zeichnen, falls notwendig
c.setDash(1, 2)
c.setStrokeColor(colors.grey)
if index % 2 == 0: # Vertikale Linie rechts für den Tag
c.line(x + width / 2, y, x + width / 2, y + height / 2)
if index < 2: # Horizontale Linie unten für den Tag
c.line(x, y, x + width / 2, y)
c.showPage()
c.save()
def main():
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
image_directory = os.path.join(BASE_DIR, 'static', 'images')
image_directory = os.path.join(BASE_DIR, 'images')
text_directory = os.path.join(BASE_DIR, 'texts')
# Get sorted dates from image files
dates = get_dates_from_images(image_directory)
if not dates:
return "No images found with the correct date format in the name.", 404
print("No images found with the correct date format in the name.")
return
# Generate data for each date
pages_data = []
@ -83,7 +160,11 @@ def calendar():
if days_data:
pages_data.append(days_data)
return render_template('index.html', pages=pages_data)
# Create the PDF
output_filename = os.path.join(BASE_DIR, 'calendar.pdf')
create_pdf(pages_data, output_filename)
print("PDF created successfully.")
if __name__ == '__main__':
app.run(debug=True)
main()

3
images/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.png
*.jpeg
*.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 KiB

View File

@ -1,107 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<style>
@media print,
screen {
body {
width: 210mm;
height: 297mm;
margin: 0mm 0mm 0mm 0mm;
padding: 0;
}
.page {
width: 210mm;
height: 297mm;
display: flex;
flex-wrap: wrap;
page-break-after: always;
}
.day {
width: 50%;
height: 50%;
box-sizing: border-box;
position: relative;
}
.circle {
width: 10mm;
height: 10mm;
position: absolute;
border-radius: 50%;
border: 1px solid black;
background-color: transparent;
}
.circle.top-left {
top: 10mm;
left: 10mm;
}
.circle.top-right {
top: 10mm;
right: 10mm;
}
.image-container {
margin-top: 28mm;
text-align: center;
height: 60mm;
}
.image-container img {
max-width: 100%;
max-height: 60mm;
height: auto;
width: auto;
object-fit: contain;
}
.date-info {
text-align: center;
font-family: Arial, Helvetica, sans-serif;
}
.text {
padding-left: 5mm;
padding-right: 5mm;
font-family: 'Courier New', Courier, monospace;
color: #666666;
}
}
</style>
</head>
<body>
{% for page in pages %}
<div class="page">
{% for day in page %}
<div class="day" style="{{ 'border-right: 1px dashed grey; border-bottom: 1px dashed grey;' if loop.index0 == 0 else '' }}
{{ 'border-bottom: 1px dashed grey;' if loop.index0 == 1 else '' }}
{{ 'border-right: 1px dashed grey;' if loop.index0 == 2 else '' }}">
<div class="circle top-left"></div>
<div class="circle top-right"></div>
<div class="image-container">
{% if day.image_file %}
<img src="{{ url_for('static', filename=day.image_file) }}" alt="Bild für {{ day.date.strftime('%d. %B %Y') }}" />
{% endif %}
</div>
<div class="date-info">
<h1>{{ day.date.strftime('%A %d.%m.%Y') }}</h1>
</div>
<div class="text">
{% if day.text_content %}
<p>{{ day.text_content }}</p>
{% endif %}
</div>
</div>
{% endfor %}
</div>
{% endfor %}
</body>
</html>

1
texts/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.txt

View File

@ -1 +0,0 @@
Beispiel Text