awacke1 commited on
Commit
d0b625e
Β·
verified Β·
1 Parent(s): 7ad575c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +120 -85
app.py CHANGED
@@ -13,114 +13,149 @@ from reportlab.lib.utils import ImageReader
13
  import mistune
14
  from gtts import gTTS
15
 
16
- # Page setup
17
  st.set_page_config(page_title="PDF & Code Interpreter", layout="wide", page_icon="πŸš€")
18
 
19
- # Tabs
20
- tab1, tab2 = st.tabs(["πŸ“„ PDF Composer","πŸ§ͺ CodeInterpreter"])
 
 
 
 
 
 
 
21
 
22
- # --- Tab 1: PDF Composer ---
23
  with tab1:
24
- st.title("πŸ–ΌοΈπŸ“ PDF Composer & Voice Generator")
25
- # Upload Markdown
26
- md_file = st.file_uploader("Upload Markdown (.md)", type=["md"] )
27
- md_text = ""
28
  if md_file:
29
  md_text = md_file.getvalue().decode("utf-8")
30
  else:
31
- md_text = st.text_area("Or enter markdown text", height=200)
32
- # Convert markdown to plain text
33
- plain = mistune.HTMLRenderer().render(mistune.create_markdown()) if not md_text.strip() else mistune.markdown(md_text)
34
-
35
- # Generate audio
36
- if st.button("πŸ”Š Generate Voice Track MP3"):
37
- tts = gTTS(text=re.sub(r'<[^>]+>','', plain), lang='en')
38
- fname = f"voice_{datetime.now().strftime('%Y%m%d_%H%M%S')}.mp3"
39
- tts.save(fname)
40
- st.audio(fname)
41
-
42
- # Upload Images
43
- imgs = st.file_uploader("Upload Images", type=["png","jpg","jpeg"], accept_multiple_files=True)
44
- # Reorder images
 
 
 
 
45
  if imgs:
46
- df = pd.DataFrame([{"name":f.name,"order":i} for i,f in enumerate(imgs)])
47
- edited = st.experimental_data_editor(df, num_rows="fixed")
48
- ordered = [imgs[df.loc[i,'name'] == f.name][0] for i in range(len(df))]
49
- else:
50
- ordered = []
 
 
51
 
52
- # Generate PDF
53
- if st.button("πŸ–‹οΈ Generate PDF"):
54
  buf = io.BytesIO()
55
  c = canvas.Canvas(buf)
56
- # Add markdown text
57
  y = 800
58
- for line in re.sub(r'<[^>]+>','', plain).split('\n'):
59
- c.drawString(40,y,line)
60
  y -= 15
61
- if y<50:
62
- c.showPage(); y=800
63
- # Add images
64
- for imgf in ordered:
65
- img = Image.open(imgf)
66
- w,h = img.size
67
- c.showPage()
68
- c.drawImage(ImageReader(img),0,0,w,h)
69
- c.save(); buf.seek(0)
70
- pname = f"document_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"
71
- st.download_button("⬇️ Download PDF", data=buf, file_name=pname, mime="application/pdf")
72
-
73
- # Show existing PDF files
74
- st.markdown("### Available PDFs")
75
- pdfs = sorted(glob.glob("*.pdf"))
76
- for p in pdfs:
77
- st.write(p, st.button("Download", key=p, args=(), kwargs={}, help="Download PDF"))
78
-
79
- # --- Tab 2: CodeInterpreter ---
 
 
 
 
 
 
 
 
 
 
 
80
  with tab2:
 
81
  import io, sys
82
  from contextlib import redirect_stdout
 
83
  DEFAULT_CODE = '''import streamlit as st
84
  import random
85
 
86
- st.title("πŸ§ͺ Test Program")
87
- st.markdown("Welcome to this simple test application!")
88
 
89
  col1, col2 = st.columns(2)
90
  with col1:
91
- number = st.number_input("Enter a number:",1,100,50)
92
- mult = st.slider("Select multiplier:",1,10,5)
93
- if st.button("Calculate"):
94
- st.success(f"Result: {number*mult}")
95
  with col2:
96
- color = st.color_picker("Pick a color","#00f900")
97
- st.markdown(f'<div style="background-color:{color};padding:20px;">Color {color}</div>',unsafe_allow_html=True)
98
- if st.button("Random Number"):
99
- st.balloons(); st.write(random.randint(1,100))
100
- '''
101
- def extract_python_code(md): return re.findall(r"```python\s*(.*?)```",md,re.DOTALL)
102
- def execute_code(code):
103
- buf = io.StringIO(); lv={}
 
 
104
  try:
105
- with redirect_stdout(buf): exec(code,{},lv)
106
- return buf.getvalue(),None
107
- except Exception as e: return None,str(e)
108
- st.title("πŸ“ Python Code Executor")
109
- up = st.file_uploader("Upload .py or .md",type=['py','md'])
110
- code = DEFAULT_CODE if 'code' not in st.session_state else st.session_state.code
 
 
 
 
111
  if up:
112
- txt=up.getvalue().decode();
113
- if up.type=='text/markdown':
114
- blocks=extract_python_code(txt)
115
- code=blocks[0] if blocks else ''
116
- else: code=txt
117
- st.code(code,language='python')
 
118
  else:
119
- code=st.text_area("Code:",value=code,height=300)
120
- st.session_state.code=code
121
- if st.button("▢️ Run Code"):
122
- out,err=execute_code(code)
123
- if err: st.error(err)
124
- elif out: st.code(out)
125
- else: st.success("Executed with no output.")
126
- if st.button("πŸ—‘οΈ Clear Code"): st.session_state.code=''; st.rerun()
 
 
 
 
 
 
 
13
  import mistune
14
  from gtts import gTTS
15
 
16
+ # Page config
17
  st.set_page_config(page_title="PDF & Code Interpreter", layout="wide", page_icon="πŸš€")
18
 
19
+ def delete_asset(path):
20
+ try:
21
+ os.remove(path)
22
+ except:
23
+ pass
24
+ st.rerun()
25
+
26
+ # Tabs setup
27
+ tab1, tab2 = st.tabs(["πŸ“„ PDF Composer", "πŸ§ͺ CodeInterpreter"])
28
 
 
29
  with tab1:
30
+ st.header("πŸ“„ PDF Composer & Voice Generator πŸš€")
31
+
32
+ md_file = st.file_uploader("Upload Markdown (.md)", type=["md"])
 
33
  if md_file:
34
  md_text = md_file.getvalue().decode("utf-8")
35
  else:
36
+ md_text = st.text_area("Or enter markdown text directly", height=200)
37
+
38
+ renderer = mistune.HTMLRenderer()
39
+ markdown = mistune.create_markdown(renderer=renderer)
40
+ html = markdown(md_text or "")
41
+ plain_text = re.sub(r'<[^>]+>', '', html)
42
+
43
+ if st.button("πŸ”Š Generate Voice MP3 from Text"):
44
+ if plain_text.strip():
45
+ voice_file = f"voice_{datetime.now().strftime('%Y%m%d_%H%M%S')}.mp3"
46
+ tts = gTTS(text=plain_text, lang='en')
47
+ tts.save(voice_file)
48
+ st.audio(voice_file)
49
+ else:
50
+ st.warning("No text to generate voice from.")
51
+
52
+ imgs = st.file_uploader("Upload Images for PDF", type=["png", "jpg", "jpeg"], accept_multiple_files=True)
53
+ ordered_images = []
54
  if imgs:
55
+ df_imgs = pd.DataFrame([{"name": f.name, "order": i} for i, f in enumerate(imgs)])
56
+ edited = st.data_editor(df_imgs, use_container_width=True)
57
+ for _, row in edited.sort_values('order').iterrows():
58
+ for f in imgs:
59
+ if f.name == row['name']:
60
+ ordered_images.append(f)
61
+ break
62
 
63
+ if st.button("πŸ–‹οΈ Generate PDF with Markdown & Images"):
 
64
  buf = io.BytesIO()
65
  c = canvas.Canvas(buf)
 
66
  y = 800
67
+ for line in plain_text.split('\n'):
68
+ c.drawString(40, y, line)
69
  y -= 15
70
+ if y < 50:
71
+ c.showPage()
72
+ y = 800
73
+ for img_f in ordered_images:
74
+ try:
75
+ img = Image.open(img_f)
76
+ w, h = img.size
77
+ c.showPage()
78
+ c.drawImage(ImageReader(img), 0, 0, w, h, preserveAspectRatio=True, mask='auto')
79
+ except:
80
+ continue
81
+ c.save()
82
+ buf.seek(0)
83
+ pdf_name = f"doc_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"
84
+ st.download_button("⬇️ Download PDF", data=buf, file_name=pdf_name, mime="application/pdf")
85
+
86
+ st.markdown("---")
87
+ st.subheader("πŸ“‚ Available Assets")
88
+ assets = sorted(glob.glob("*.*"))
89
+ for a in assets:
90
+ ext = a.split('.')[-1].lower()
91
+ cols = st.columns([3, 1, 1])
92
+ cols[0].write(a)
93
+ if ext == 'pdf':
94
+ with open(a, 'rb') as fp:
95
+ cols[1].download_button("πŸ“₯", data=fp, file_name=a, mime="application/pdf")
96
+ elif ext == 'mp3':
97
+ cols[1].audio(a)
98
+ cols[2].button("πŸ—‘οΈ", key=f"del_{a}", on_click=delete_asset, args=(a,))
99
+
100
  with tab2:
101
+ st.header("πŸ§ͺ Python Code Executor & Demo")
102
  import io, sys
103
  from contextlib import redirect_stdout
104
+
105
  DEFAULT_CODE = '''import streamlit as st
106
  import random
107
 
108
+ st.title("πŸ“Š Demo App")
109
+ st.markdown("Random number and color demo")
110
 
111
  col1, col2 = st.columns(2)
112
  with col1:
113
+ num = st.number_input("Number:", 1, 100, 10)
114
+ mul = st.slider("Multiplier:", 1, 10, 2)
115
+ if st.button("Calc"):
116
+ st.write(num * mul)
117
  with col2:
118
+ color = st.color_picker("Pick color","#ff0000")
119
+ st.markdown(f'<div style="background:{color};padding:10px;">Color</div>', unsafe_allow_html=True)
120
+ ''' # noqa
121
+
122
+ def extract_python_code(md: str) -> list:
123
+ return re.findall(r"```python\s*(.*?)```", md, re.DOTALL)
124
+
125
+ def execute_code(code: str) -> tuple:
126
+ buf = io.StringIO()
127
+ local_vars = {}
128
  try:
129
+ with redirect_stdout(buf):
130
+ exec(code, {}, local_vars)
131
+ return buf.getvalue(), None
132
+ except Exception as e:
133
+ return None, str(e)
134
+
135
+ up = st.file_uploader("Upload .py or .md", type=['py', 'md'])
136
+ if 'code' not in st.session_state:
137
+ st.session_state.code = DEFAULT_CODE
138
+
139
  if up:
140
+ text = up.getvalue().decode()
141
+ if up.type == 'text/markdown':
142
+ codes = extract_python_code(text)
143
+ st.session_state.code = codes[0] if codes else ''
144
+ else:
145
+ st.session_state.code = text
146
+ st.code(st.session_state.code, language='python')
147
  else:
148
+ st.session_state.code = st.text_area("πŸ’» Code Editor", value=st.session_state.code, height=300)
149
+
150
+ c1, c2 = st.columns([1, 1])
151
+ if c1.button("▢️ Run Code"):
152
+ out, err = execute_code(st.session_state.code)
153
+ if err:
154
+ st.error(err)
155
+ elif out:
156
+ st.code(out)
157
+ else:
158
+ st.success("Executed with no output.")
159
+ if c2.button("πŸ—‘οΈ Clear Code"):
160
+ st.session_state.code = ''
161
+ st.rerun()