import io import os import re import glob from datetime import datetime from pathlib import Path import streamlit as st import pandas as pd from PIL import Image from reportlab.pdfgen import canvas from reportlab.lib.utils import ImageReader import mistune from gtts import gTTS # Page config st.set_page_config(page_title="PDF & Code Interpreter", layout="wide", page_icon="๐Ÿš€") def delete_asset(path): try: os.remove(path) except: pass st.rerun() # Tabs setup tab1, tab2 = st.tabs(["๐Ÿ“„ PDF Composer", "๐Ÿงช CodeInterpreter"]) with tab1: st.header("๐Ÿ“„ PDF Composer & Voice Generator ๐Ÿš€") md_file = st.file_uploader("Upload Markdown (.md)", type=["md"]) if md_file: md_text = md_file.getvalue().decode("utf-8") else: md_text = st.text_area("Or enter markdown text directly", height=200) renderer = mistune.HTMLRenderer() markdown = mistune.create_markdown(renderer=renderer) html = markdown(md_text or "") plain_text = re.sub(r'<[^>]+>', '', html) if st.button("๐Ÿ”Š Generate Voice MP3 from Text"): if plain_text.strip(): voice_file = f"voice_{datetime.now().strftime('%Y%m%d_%H%M%S')}.mp3" tts = gTTS(text=plain_text, lang='en') tts.save(voice_file) st.audio(voice_file) else: st.warning("No text to generate voice from.") imgs = st.file_uploader("Upload Images for PDF", type=["png", "jpg", "jpeg"], accept_multiple_files=True) ordered_images = [] if imgs: df_imgs = pd.DataFrame([{"name": f.name, "order": i} for i, f in enumerate(imgs)]) edited = st.data_editor(df_imgs, use_container_width=True) for _, row in edited.sort_values('order').iterrows(): for f in imgs: if f.name == row['name']: ordered_images.append(f) break if st.button("๐Ÿ–‹๏ธ Generate PDF with Markdown & Images"): buf = io.BytesIO() c = canvas.Canvas(buf) y = 800 for line in plain_text.split('\n'): c.drawString(40, y, line) y -= 15 if y < 50: c.showPage() y = 800 for img_f in ordered_images: try: img = Image.open(img_f) w, h = img.size c.showPage() c.drawImage(ImageReader(img), 0, 0, w, h, preserveAspectRatio=True, mask='auto') except: continue c.save() buf.seek(0) pdf_name = f"doc_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf" st.download_button("โฌ‡๏ธ Download PDF", data=buf, file_name=pdf_name, mime="application/pdf") st.markdown("---") st.subheader("๐Ÿ“‚ Available Assets") assets = sorted(glob.glob("*.*")) for a in assets: ext = a.split('.')[-1].lower() cols = st.columns([3, 1, 1]) cols[0].write(a) if ext == 'pdf': with open(a, 'rb') as fp: cols[1].download_button("๐Ÿ“ฅ", data=fp, file_name=a, mime="application/pdf") elif ext == 'mp3': cols[1].audio(a) cols[2].button("๐Ÿ—‘๏ธ", key=f"del_{a}", on_click=delete_asset, args=(a,)) with tab2: st.header("๐Ÿงช Python Code Executor & Demo") import io, sys from contextlib import redirect_stdout DEFAULT_CODE = '''import streamlit as st import random st.title("๐Ÿ“Š Demo App") st.markdown("Random number and color demo") col1, col2 = st.columns(2) with col1: num = st.number_input("Number:", 1, 100, 10) mul = st.slider("Multiplier:", 1, 10, 2) if st.button("Calc"): st.write(num * mul) with col2: color = st.color_picker("Pick color","#ff0000") st.markdown(f'
Color
', unsafe_allow_html=True) ''' # noqa def extract_python_code(md: str) -> list: return re.findall(r"```python\s*(.*?)```", md, re.DOTALL) def execute_code(code: str) -> tuple: buf = io.StringIO() local_vars = {} try: with redirect_stdout(buf): exec(code, {}, local_vars) return buf.getvalue(), None except Exception as e: return None, str(e) up = st.file_uploader("Upload .py or .md", type=['py', 'md']) if 'code' not in st.session_state: st.session_state.code = DEFAULT_CODE if up: text = up.getvalue().decode() if up.type == 'text/markdown': codes = extract_python_code(text) st.session_state.code = codes[0] if codes else '' else: st.session_state.code = text st.code(st.session_state.code, language='python') else: st.session_state.code = st.text_area("๐Ÿ’ป Code Editor", value=st.session_state.code, height=300) c1, c2 = st.columns([1, 1]) if c1.button("โ–ถ๏ธ Run Code"): out, err = execute_code(st.session_state.code) if err: st.error(err) elif out: st.code(out) else: st.success("Executed with no output.") if c2.button("๐Ÿ—‘๏ธ Clear Code"): st.session_state.code = '' st.rerun()