# -*- coding: utf-8 -*- # Use ReportLab package to create PDF poster from reportlab.pdfbase import pdfmetrics from reportlab.lib.pagesizes import A4 from reportlab.lib.styles import getSampleStyleSheet from reportlab.lib.units import cm from reportlab.platypus import ( SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, Image, Flowable, ListFlowable, ListItem, ) from reportlab.lib import colors from reportlab.pdfbase.cidfonts import UnicodeCIDFont import yt_dlp import cv2 from PIL import Image as PILImage import os import tempfile import re import uuid import pymupdf ''' # UnicodeCIDfont names $chs$ = Chinese Simplified (mainland): '$STSong-Light$' $cht$ = Chinese Traditional (Taiwan): '$MSung-Light$', '$MHei-Medium$' $kor$ = Korean: '$HYSMyeongJoStd-Medium$','$HYGothic-Medium$' $jpn$ = Japanese: '$HeiseiMin-W3$', '$HeiseiKakuGo-W5$' ''' # Configuration # Register the Chinese font with Reportlab pdfmetrics.registerFont(UnicodeCIDFont('STSong-Light')) pdfmetrics.registerFont(UnicodeCIDFont('MSung-Light')) PAGE_SIZE = A4 MARGIN = 1.0 * cm COLUMNS = 3 # Now using 3 columns STYLE = getSampleStyleSheet() style_body = STYLE["BodyText"] style_title = STYLE['Title'] style_title.alignment = 1 # center the title # Calculate available width for tables page_width = PAGE_SIZE[0] - 2*MARGIN col_width = page_width / COLUMNS img_width = col_width - 1*cm # Leave some padding img_height = 5*cm #========================================================================== def create_poster(filename, images, lang, summary, url = None): print("Output language is:", lang) #generate PDF file doc = SimpleDocTemplate(filename, pagesize=PAGE_SIZE, leftMargin=MARGIN, rightMargin=MARGIN, topMargin=MARGIN, bottomMargin=MARGIN) story = [] # Define a style with the detected language font if lang.lower() == 'chinese': style_body.fontName = 'STSong-Light' style_title.fontName = 'STSong-Light' else: style_body.fontName = 'Helvetica' style_title.fontName = 'Helvetica-Bold' # Create table data for detected images table_data = [] list_content = [] with tempfile.TemporaryDirectory() as temp_dir: # Process output summary question = [] current_answer = [] answers_part = summary.strip().split("\n") title_text = "Summary" # initialize title title = Paragraph(f"{title_text}", style_title) for line in answers_part: #.split("\n"): if re.search("0.", line): #title line clean_line = line.replace("*", "") title_text = clean_line.split("0.") if len(title_text) > 1: title_text = title_text[1] else: title_text = title_text[0] index = title_text.find(':') if index != -1: title_text = title_text[index+1:] title = Paragraph(f"{title_text}", style_title) elif re.search(r'\d\.', line): # Start of a new question-answer section list_content.append(Spacer(1, 0.3*cm)) if current_answer: list_item = Paragraph(f"{current_answer}", style_body), list_content.append(list_item) current_answer = [] line_content = line.replace("*", "").split(":") question = str(line_content[0]) question = Paragraph(f"{question}", style_body) list_content.append(question) if len(line_content) > 1: #handle same line answer list_item = Paragraph(f"{line_content[1]}", style_body) list_content.append(list_item) elif line.strip() and question: list_item = Paragraph(f"{line}", style_body) list_content.append(list_item) #add last section if current_answer: list_item = Paragraph(f"{line}", style_body) list_content.append(list_item) # construct the full list markdown_output = ListFlowable(list_content, bulletType='bullet', bulletColor='white', value='circle' ), output_list = markdown_output[0] #workaround for converting tuple to list # Insert images into a table row_cells = [] for id, image in enumerate(images): face_filename = f'{id}.jpg' image_path = os.path.join(temp_dir, face_filename) cv2.imwrite(image_path, image) # Load the image back into memory because Image object needs filepath input pil_img = PILImage.open(image_path) # Create cell content cell_content = [ Spacer(1, 0.3*cm), Image(image_path, width=img_width, height=img_height), Spacer(1, 0.3*cm), ] row_cells.append(cell_content) # Add row to table table_data.append(row_cells) # Create table with styling tbl = Table(table_data, colWidths=[col_width]*COLUMNS, rowHeights=img_height+0.5*cm) tbl.setStyle(TableStyle([ ('ALIGN', (0,0), (-1,-1), 'CENTER'), ('VALIGN', (0,0), (-1,-1), 'CENTER'), ('PADDING', (0,0), (-1,-1), 10), ('BOX', (0,0), (-1,-1), 0.5, colors.white), ('INNERGRID', (0,0), (-1,-1), 0.5, colors.white), ])) # add flowables story.append(title) story.append(tbl) story.append(Spacer(1,0.3*cm)) story.append(output_list) story.append(Spacer(1,0.5*cm)) # Clickable video link if url: link_text = f'View Original Video' link_paragraph = Paragraph(link_text, style_body) story.append(link_paragraph) # build a page doc.build(story) return filename def generate_unique_filename(extension): return f"{uuid.uuid4()}{extension}" def generate_tmp_filename(basename, extension): return f"{basename}{extension}" def pdf_to_jpg(pdf_path, output_path): doc = pymupdf.open(pdf_path) page = doc.load_page(0) pix = page.get_pixmap() pix.save(output_path, "JPEG") image = PILImage.open(output_path) doc.close() return image, output_path def download_youtube_video(url): """Downloads a Youtube video using yt-dlp.""" basename = os.path.basename(url) output_path = generate_tmp_filename(basename, ".mp4") ydl_opts = { 'outtmpl': output_path, # Path where the video will be saved 'format': 'best', # Download the best quality available 'cookiefile': 'cookies.txt', # Path to your cookies file #JW 20250115 } try: with yt_dlp.YoutubeDL(ydl_opts) as ydl: ydl.download([url]) return output_path except Exception as e: print("load yt_dlp:", e) return str(e)