Spaces:
Sleeping
Sleeping
# app.py (streamlined and modularized for clarity and maintainability) | |
import streamlit as st | |
import os | |
import glob | |
import base64 | |
import pandas as pd | |
import fitz | |
from PIL import Image | |
from io import BytesIO | |
from datetime import datetime | |
from reportlab.pdfgen import canvas | |
from reportlab.lib.utils import ImageReader | |
from markdown2 import markdown | |
# --- Config --- | |
st.set_page_config( | |
page_title="Vision & Layout Titans ๐", | |
page_icon="๐ค", | |
layout="wide" | |
) | |
# --- Helper Functions --- | |
def get_files(exts): | |
files = [] | |
for ext in exts: | |
files.extend(glob.glob(f'*.{ext}')) | |
return sorted([f for f in files if f.lower() != "readme.md"]) | |
def image_to_pdf(images, md_files): | |
buffer = BytesIO() | |
c = canvas.Canvas(buffer) | |
for img_path in images: | |
img = Image.open(img_path) | |
width, height = img.size | |
c.setPageSize((width, height)) | |
c.drawImage(ImageReader(img), 0, 0, width, height) | |
c.showPage() | |
for md_path in md_files: | |
with open(md_path, 'r', encoding='utf-8') as f: | |
md_content = f.read() | |
html = markdown(md_content) | |
c.setPageSize((595, 842)) # A4 size | |
c.setFont("Helvetica", 10) | |
c.drawString(50, 800, md_content[:1000]) # Simplified render | |
c.showPage() | |
c.save() | |
buffer.seek(0) | |
return buffer | |
def render_pdf_gallery(pdf_files): | |
for pdf_file in pdf_files: | |
doc = fitz.open(pdf_file) | |
page = doc.load_page(0) | |
pix = page.get_pixmap(matrix=fitz.Matrix(0.5, 0.5)) | |
img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples) | |
st.image(img, caption=os.path.basename(pdf_file)) | |
# --- Sidebar Management --- | |
st.sidebar.header("Content Management") | |
image_files = get_files(['png', 'jpg', 'jpeg']) | |
pdf_files = get_files(['pdf']) | |
md_files = get_files(['md']) | |
selected_images = st.sidebar.multiselect("Select Images", image_files) | |
selected_md_files = st.sidebar.multiselect("Select Markdown Files", md_files) | |
# PDF Gallery | |
if st.sidebar.checkbox("Show PDF Gallery"): | |
render_pdf_gallery(pdf_files) | |
# PDF Generation with rearrangement | |
st.sidebar.subheader("Reorder Content for PDF") | |
content_df = pd.DataFrame({ | |
"Content": selected_images + selected_md_files, | |
"Type": ["Image"] * len(selected_images) + ["Markdown"] * len(selected_md_files), | |
"Order": range(len(selected_images) + len(selected_md_files)) | |
}) | |
edited_df = st.sidebar.data_editor(content_df, use_container_width=True) | |
sorted_contents = edited_df.sort_values('Order')['Content'].tolist() | |
if st.sidebar.button("Generate PDF"): | |
sorted_images = [item for item in sorted_contents if item in selected_images] | |
sorted_md_files = [item for item in sorted_contents if item in selected_md_files] | |
pdf_buffer = image_to_pdf(sorted_images, sorted_md_files) | |
st.sidebar.download_button("Download PDF", pdf_buffer, "output.pdf") | |
# Deletion | |
st.sidebar.subheader("Delete Files") | |
file_to_delete = st.sidebar.selectbox("Select file to delete", image_files + pdf_files + md_files) | |
if st.sidebar.button("Delete Selected File"): | |
os.remove(file_to_delete) | |
st.sidebar.success(f"Deleted {file_to_delete}") | |
st.rerun() | |
# --- Main Page --- | |
st.title("Vision & Layout Titans ๐") | |
st.markdown("### Manage, View, and Export Your Files Easily!") | |
# Display selected images | |
st.subheader("Selected Images") | |
for img_path in selected_images: | |
img = Image.open(img_path) | |
st.image(img, caption=os.path.basename(img_path)) | |
# Display selected markdown | |
st.subheader("Selected Markdown") | |
for md_path in selected_md_files: | |
with open(md_path, 'r', encoding='utf-8') as f: | |
md_content = f.read() | |
st.markdown(md_content[:500] + '...') | |