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 # 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 date_pattern = re.compile(r'(\d{4}-\d{2}-\d{2})') # List to store the dates dates = [] # Iterate over each file in the images directory for filename in os.listdir(image_directory): # Search for the pattern in the filename match = date_pattern.search(filename) if match: # Extract the date from the filename try: date = datetime.strptime(match.group(), '%Y-%m-%d') dates.append(date) except ValueError: # If the date format is incorrect, ignore the file continue # Return the sorted list of dates return sorted(dates) def get_image_and_text_for_date(date, image_directory, text_directory): formatted_date = date.strftime('%Y-%m-%d') image_file = None text_content = None # Check for image file for ext in ['jpg', 'jpeg', 'png']: # Check using full path, but store relative path for HTML image_full_path = os.path.join(image_directory, f"{formatted_date}.{ext}") if os.path.isfile(image_full_path): # Store the relative path from within the 'static' directory image_file = f"images/{formatted_date}.{ext}" break # Check for text file text_path = os.path.join(text_directory, f"{formatted_date}.txt") if os.path.isfile(text_path): with open(text_path, 'r') as file: text_content = file.read() return image_file, text_content def draw_circle(c, x, y): c.circle(x, y, CIRCLE_RADIUS, stroke=1, fill=0) 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, '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: print("No images found with the correct date format in the name.") return # Generate data for each date pages_data = [] days_data = [] for date in dates: image_file, text_content = get_image_and_text_for_date(date, image_directory, text_directory) days_data.append({ 'date': date, 'image_file': image_file, 'text_content': text_content }) # Check if we have collected data for 4 days, then start a new page if len(days_data) == 4: pages_data.append(days_data) days_data = [] # Add any remaining days to the last page if days_data: pages_data.append(days_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__': main()