awacke1 commited on
Commit
51c1918
Β·
verified Β·
1 Parent(s): f61c483

Create app-backup3.py

Browse files
Files changed (1) hide show
  1. app-backup3.py +584 -0
app-backup3.py ADDED
@@ -0,0 +1,584 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from streamlit.components.v1 import html
3
+ from pathlib import Path
4
+ import json
5
+ import time
6
+ from datetime import datetime
7
+ import re
8
+ import pandas as pd
9
+ import yaml
10
+ from io import StringIO
11
+ import openpyxl
12
+ import csv
13
+ import base64
14
+ import glob
15
+ import os
16
+
17
+ # Add this function after the imports and before other functions
18
+ def scan_and_load_files():
19
+ """πŸ” File Detective - Scans directory for supported files and loads them automatically"""
20
+ loaded_files = []
21
+
22
+ # Get all files with supported extensions
23
+ for ext in FILE_TYPES.keys():
24
+ files = glob.glob(f"*.{ext}")
25
+ for filepath in files:
26
+ try:
27
+ with open(filepath, 'r', encoding='utf-8') as f:
28
+ content = f.read()
29
+ file_type = filepath.split('.')[-1].lower()
30
+
31
+ # Store file content and type
32
+ st.session_state.file_data[filepath] = content
33
+ st.session_state.file_types[filepath] = file_type
34
+
35
+ # Special handling for markdown files
36
+ if file_type == 'md':
37
+ st.session_state.md_outline[filepath] = parse_markdown_outline(content)
38
+ st.session_state.rendered_content[filepath] = content
39
+
40
+ # Add to markdown files history if not already present
41
+ if filepath not in [f["filename"] for f in st.session_state.md_files_history]:
42
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
43
+ encoded_content = encode_content(content)
44
+ st.session_state.md_files_history.append({
45
+ "filename": filepath,
46
+ "timestamp": timestamp,
47
+ "content": encoded_content
48
+ })
49
+
50
+ # Create initial version history
51
+ if filepath not in st.session_state.md_versions:
52
+ st.session_state.md_versions[filepath] = []
53
+ st.session_state.md_versions[filepath].append({
54
+ "timestamp": timestamp,
55
+ "content": encoded_content,
56
+ "action": "auto-loaded"
57
+ })
58
+
59
+ loaded_files.append(filepath)
60
+ except Exception as e:
61
+ st.error(f"🚨 Error loading {filepath}: {str(e)}")
62
+
63
+ # Update combined markdown after loading all files
64
+ if loaded_files:
65
+ st.session_state.combined_markdown = combine_markdown_files()
66
+
67
+ return loaded_files
68
+
69
+
70
+
71
+
72
+ # Modify the main function to include initial file scanning
73
+ def main():
74
+
75
+ # Add a reset button in sidebar
76
+ if st.sidebar.button("πŸ”„ Reset & Rescan Files"):
77
+ # Clear all session state
78
+ for key in list(st.session_state.keys()):
79
+ del st.session_state[key]
80
+ st.experimental_rerun()
81
+
82
+ st.title("πŸ“šβœ¨ Super Smart File Handler with Markdown Magic! βœ¨πŸ“š")
83
+
84
+ # Initialize session state
85
+ if 'file_data' not in st.session_state:
86
+ st.session_state.file_data = {}
87
+ if 'file_types' not in st.session_state:
88
+ st.session_state.file_types = {}
89
+ if 'md_outline' not in st.session_state:
90
+ st.session_state.md_outline = {}
91
+ if 'rendered_content' not in st.session_state:
92
+ st.session_state.rendered_content = {}
93
+ if 'file_history' not in st.session_state:
94
+ st.session_state.file_history = []
95
+ if 'md_versions' not in st.session_state:
96
+ st.session_state.md_versions = {}
97
+ if 'md_files_history' not in st.session_state:
98
+ st.session_state.md_files_history = []
99
+ if 'combined_markdown' not in st.session_state:
100
+ st.session_state.combined_markdown = ""
101
+
102
+ # Scan for existing files on startup
103
+ if 'files_scanned' not in st.session_state:
104
+ loaded_files = scan_and_load_files()
105
+ if loaded_files:
106
+ st.success(f"πŸŽ‰ Auto-loaded {len(loaded_files)} existing files: {', '.join(loaded_files)}")
107
+ st.session_state.files_scanned = True
108
+
109
+
110
+ st.title("πŸ“šβœ¨ Super Smart File Handler with Markdown Magic! βœ¨πŸ“š")
111
+
112
+ # Scan for existing files on startup
113
+ if 'files_scanned' not in st.session_state:
114
+ loaded_files = scan_and_load_files()
115
+ if loaded_files:
116
+ st.success(f"πŸŽ‰ Auto-loaded {len(loaded_files)} existing files: {', '.join(loaded_files)}")
117
+ st.session_state.files_scanned = True
118
+
119
+ # Show markdown history in sidebar
120
+ show_sidebar_history()
121
+
122
+ # Add tabs for different upload methods
123
+ upload_tab, book_tab = st.tabs(["πŸ“€ File Upload", "πŸ“– Book View"])
124
+
125
+ with upload_tab:
126
+ # Add a rescan button
127
+ if st.button("πŸ”„ Rescan Directory"):
128
+ st.session_state.files_scanned = False
129
+ st.experimental_rerun()
130
+
131
+ col1, col2 = st.columns(2)
132
+
133
+ with col1:
134
+ single_uploaded_file = st.file_uploader(
135
+ "πŸ“€ Upload single file",
136
+ type=list(FILE_TYPES.keys()),
137
+ help="Supports: " + ", ".join([f"{v} (.{k})" for k, v in FILE_TYPES.items()]),
138
+ key="single_uploader"
139
+ )
140
+
141
+ with col2:
142
+ multiple_uploaded_files = st.file_uploader(
143
+ "πŸ“š Upload multiple files",
144
+ type=list(FILE_TYPES.keys()),
145
+ accept_multiple_files=True,
146
+ help="Upload multiple files to view as a book",
147
+ key="multiple_uploader"
148
+ )
149
+
150
+ # Process single file upload
151
+ if single_uploaded_file:
152
+ content, file_type = read_file_content(single_uploaded_file)
153
+ if content is not None:
154
+ st.session_state.file_data[single_uploaded_file.name] = content
155
+ st.session_state.file_types[single_uploaded_file.name] = file_type
156
+ st.success(f"πŸŽ‰ Loaded {FILE_TYPES.get(file_type, 'πŸ“„')} file: {single_uploaded_file.name}")
157
+
158
+ # Process multiple file upload
159
+ if multiple_uploaded_files:
160
+ for uploaded_file in multiple_uploaded_files:
161
+ content, file_type = read_file_content(uploaded_file)
162
+ if content is not None:
163
+ st.session_state.file_data[uploaded_file.name] = content
164
+ st.session_state.file_types[uploaded_file.name] = file_type
165
+ st.success(f"πŸŽ‰ Loaded {len(multiple_uploaded_files)} files")
166
+
167
+ # Show file history
168
+ show_file_history()
169
+
170
+ # Show individual files
171
+ if st.session_state.file_data:
172
+ st.subheader("πŸ“‚ Your Files")
173
+ for filename, content in st.session_state.file_data.items():
174
+ file_type = st.session_state.file_types[filename]
175
+ with st.expander(f"{FILE_TYPES.get(file_type, 'πŸ“„')} {filename}"):
176
+ if file_type == "md":
177
+ content = create_markdown_tabs(content, filename)
178
+ else:
179
+ edited_content = st.text_area(
180
+ "Content",
181
+ content,
182
+ height=300,
183
+ key=f"edit_{filename}"
184
+ )
185
+ if edited_content != content:
186
+ st.session_state.file_data[filename] = edited_content
187
+ content = edited_content
188
+
189
+ if st.button(f"πŸ’Ύ Save {filename}"):
190
+ if save_file_content(content, filename, file_type):
191
+ st.success(f"✨ Saved {filename} successfully!")
192
+
193
+ with book_tab:
194
+ show_book_view()
195
+
196
+ # 🎨 File type emojis - Making file types fun and visual!
197
+ FILE_TYPES = {
198
+ "md": "πŸ“ Markdown",
199
+ "txt": "πŸ“„ Text",
200
+ "json": "πŸ”§ JSON",
201
+ "csv": "πŸ“Š CSV",
202
+ "xlsx": "πŸ“— Excel",
203
+ "yaml": "βš™οΈ YAML",
204
+ "xml": "πŸ”— XML"
205
+ }
206
+
207
+ # 🧠 Brain initialization - Setting up our app's memory!
208
+ if 'file_data' not in st.session_state:
209
+ st.session_state.file_data = {}
210
+ if 'file_types' not in st.session_state:
211
+ st.session_state.file_types = {}
212
+ if 'md_outline' not in st.session_state:
213
+ st.session_state.md_outline = {}
214
+ if 'rendered_content' not in st.session_state:
215
+ st.session_state.rendered_content = {}
216
+ if 'file_history' not in st.session_state:
217
+ st.session_state.file_history = []
218
+ if 'md_versions' not in st.session_state:
219
+ st.session_state.md_versions = {}
220
+ if 'md_files_history' not in st.session_state:
221
+ st.session_state.md_files_history = []
222
+ if 'combined_markdown' not in st.session_state:
223
+ st.session_state.combined_markdown = ""
224
+
225
+ # 🧹 Clean Sweep! - Decluttering our markdown files
226
+ def delete_all_md_files():
227
+ """Delete all markdown files except README.md"""
228
+ files_to_remove = [
229
+ f for f in st.session_state.md_files_history
230
+ if f["filename"] != "README.md"
231
+ ]
232
+ for file in files_to_remove:
233
+ filename = file["filename"]
234
+ if filename in st.session_state.file_data:
235
+ del st.session_state.file_data[filename]
236
+ if filename in st.session_state.file_types:
237
+ del st.session_state.file_types[filename]
238
+ if filename in st.session_state.md_outline:
239
+ del st.session_state.md_outline[filename]
240
+ if filename in st.session_state.rendered_content:
241
+ del st.session_state.rendered_content[filename]
242
+ if filename in st.session_state.md_versions:
243
+ del st.session_state.md_versions[filename]
244
+
245
+ st.session_state.md_files_history = [
246
+ f for f in st.session_state.md_files_history
247
+ if f["filename"] == "README.md"
248
+ ]
249
+ st.session_state.combined_markdown = ""
250
+ return len(files_to_remove)
251
+
252
+ # 🎁 Download Gift Wrapper - Making files downloadable with style!
253
+ def get_binary_file_downloader_html(bin_file, file_label='File'):
254
+ """Generate a link allowing the data in a given file to be downloaded"""
255
+ b64 = base64.b64encode(bin_file.encode()).decode()
256
+ return f'<a href="data:text/plain;base64,{b64}" download="{file_label}">πŸ“₯ Download {file_label}</a>'
257
+
258
+ # πŸ” Secret Keeper - Encoding our content safely
259
+ def encode_content(content):
260
+ """Encode content to base64"""
261
+ return base64.b64encode(content.encode()).decode()
262
+
263
+ # πŸ”“ Mystery Solver - Decoding our secret content
264
+ def decode_content(encoded_content):
265
+ """Decode content from base64"""
266
+ return base64.b64decode(encoded_content.encode()).decode()
267
+
268
+ # πŸ“š Book Maker - Combining markdown files into a beautiful book
269
+ def combine_markdown_files():
270
+ """Combine all markdown files into a single document"""
271
+ combined = []
272
+ for md_file in sorted(st.session_state.md_files_history, key=lambda x: x["filename"]):
273
+ content = decode_content(md_file["content"])
274
+ combined.append(f"# {md_file['filename']}\n\n{content}\n\n---\n\n")
275
+ return "".join(combined)
276
+
277
+ # πŸ“ History Scribe - Recording every file action with precision
278
+ def add_to_history(filename, content, action="uploaded"):
279
+ """Add a file action to the history with timestamp"""
280
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
281
+ encoded_content = encode_content(content)
282
+ history_entry = {
283
+ "timestamp": timestamp,
284
+ "filename": filename,
285
+ "action": action,
286
+ "content": encoded_content
287
+ }
288
+ st.session_state.file_history.insert(0, history_entry)
289
+
290
+ if filename.endswith('.md'):
291
+ if filename not in st.session_state.md_versions:
292
+ st.session_state.md_versions[filename] = []
293
+ st.session_state.md_versions[filename].append({
294
+ "timestamp": timestamp,
295
+ "content": encoded_content,
296
+ "action": action
297
+ })
298
+
299
+ if filename not in [f["filename"] for f in st.session_state.md_files_history]:
300
+ st.session_state.md_files_history.append({
301
+ "filename": filename,
302
+ "timestamp": timestamp,
303
+ "content": encoded_content
304
+ })
305
+
306
+ st.session_state.combined_markdown = combine_markdown_files()
307
+
308
+ # πŸ“š Shelf Display - Showing our markdown collection in the sidebar
309
+ def show_sidebar_history():
310
+ """Display markdown file history in the sidebar"""
311
+ st.sidebar.markdown("### πŸ“š Markdown Files History")
312
+
313
+ if st.sidebar.button("🧹 Delete All (except README.md)"):
314
+ deleted_count = delete_all_md_files()
315
+ st.sidebar.success(f"Deleted {deleted_count} markdown files")
316
+ st.rerun()
317
+
318
+ for md_file in st.session_state.md_files_history:
319
+ col1, col2, col3 = st.sidebar.columns([2, 1, 1])
320
+
321
+ with col1:
322
+ st.markdown(f"**{md_file['filename']}**")
323
+
324
+ with col2:
325
+ if st.button("πŸ“‚ Open", key=f"open_{md_file['filename']}"):
326
+ content = decode_content(md_file['content'])
327
+ st.session_state.file_data[md_file['filename']] = content
328
+ st.session_state.file_types[md_file['filename']] = "md"
329
+ st.session_state.md_outline[md_file['filename']] = parse_markdown_outline(content)
330
+ st.rerun()
331
+
332
+ with col3:
333
+ download_link = get_binary_file_downloader_html(
334
+ decode_content(md_file['content']),
335
+ md_file['filename']
336
+ )
337
+ st.markdown(download_link, unsafe_allow_html=True)
338
+
339
+ # πŸ“– Book Display - Showing our combined markdown masterpiece
340
+ def show_book_view():
341
+ """Display all markdown files in a book-like format"""
342
+ if st.session_state.combined_markdown:
343
+ st.markdown("## πŸ“– Book View")
344
+ st.markdown(st.session_state.combined_markdown)
345
+
346
+ # πŸ“‹ Time Traveler - Showing our file's journey through time
347
+ def show_file_history():
348
+ """Display the file history in a collapsible section"""
349
+ if st.session_state.file_history:
350
+ with st.expander("πŸ“‹ File History", expanded=False):
351
+ st.markdown("### Recent File Activities")
352
+ for entry in st.session_state.file_history:
353
+ col1, col2 = st.columns([2, 3])
354
+ with col1:
355
+ st.markdown(f"**{entry['timestamp']}**")
356
+ with col2:
357
+ st.markdown(f"{entry['action'].title()}: {entry['filename']}")
358
+
359
+ # ⏰ Time Machine - Exploring previous versions of our files
360
+ def show_markdown_versions(filename):
361
+ """Display previous versions of a markdown file"""
362
+ if filename in st.session_state.md_versions:
363
+ versions = st.session_state.md_versions[filename]
364
+ if len(versions) > 1:
365
+ st.markdown("### οΏ½οΏ½ Previous Versions")
366
+ version_idx = st.selectbox(
367
+ "Select version to view",
368
+ range(len(versions)-1),
369
+ format_func=lambda x: f"Version {len(versions)-1-x} - {versions[x]['timestamp']}"
370
+ )
371
+
372
+ if version_idx is not None:
373
+ version = versions[version_idx]
374
+ decoded_content = decode_content(version['content'])
375
+ st.text_area(
376
+ "Content",
377
+ decoded_content,
378
+ height=200,
379
+ key=f"version_{filename}_{version_idx}",
380
+ disabled=True
381
+ )
382
+ if st.button(f"Restore to this version", key=f"restore_{filename}_{version_idx}"):
383
+ st.session_state.file_data[filename] = decoded_content
384
+ st.session_state.md_outline[filename] = parse_markdown_outline(decoded_content)
385
+ add_to_history(filename, decoded_content, "restored")
386
+ st.rerun()
387
+
388
+ # πŸ—ΊοΈ Map Maker - Creating a beautiful outline of our markdown
389
+ def parse_markdown_outline(content):
390
+ """Generate an outline from markdown content"""
391
+ lines = content.split('\n')
392
+ outline = []
393
+ for line in lines:
394
+ if line.strip().startswith('#'):
395
+ level = len(line.split()[0])
396
+ title = line.strip('#').strip()
397
+ outline.append({
398
+ 'level': level,
399
+ 'title': title,
400
+ 'indent': ' ' * (level - 1)
401
+ })
402
+ return outline
403
+
404
+ # πŸ“‘ Tab Master - Creating beautiful tabs for our markdown content
405
+ def create_markdown_tabs(content, filename):
406
+ """Create tabs for markdown content viewing and editing"""
407
+ tab1, tab2, tab3 = st.tabs(["πŸ“ Editor", "πŸ‘€ Preview", "πŸ•’ History"])
408
+
409
+ with tab1:
410
+ edited_content = st.text_area(
411
+ "Edit your markdown",
412
+ content,
413
+ height=300,
414
+ key=f"edit_{filename}"
415
+ )
416
+
417
+ if edited_content != content:
418
+ st.session_state.file_data[filename] = edited_content
419
+ st.session_state.md_outline[filename] = parse_markdown_outline(edited_content)
420
+ add_to_history(filename, edited_content, "edited")
421
+ content = edited_content
422
+
423
+ with tab2:
424
+ st.markdown("### Preview")
425
+ st.markdown(content)
426
+
427
+ if filename in st.session_state.md_outline:
428
+ st.markdown("---")
429
+ st.markdown("### πŸ“‘ Document Outline")
430
+ for item in st.session_state.md_outline[filename]:
431
+ st.markdown(f"{item['indent']}β€’ {item['title']}")
432
+
433
+ with tab3:
434
+ show_markdown_versions(filename)
435
+
436
+ return content
437
+
438
+ # πŸ“€ File Reader - Smart file reading with a smile!
439
+ def read_file_content(uploaded_file):
440
+ """Smart file reader with enhanced markdown handling"""
441
+ file_type = uploaded_file.name.split('.')[-1].lower()
442
+ try:
443
+ if file_type == 'md':
444
+ content = uploaded_file.getvalue().decode()
445
+ st.session_state.md_outline[uploaded_file.name] = parse_markdown_outline(content)
446
+ st.session_state.rendered_content[uploaded_file.name] = content
447
+ add_to_history(uploaded_file.name, content)
448
+ return content, "md"
449
+
450
+ elif file_type == 'csv':
451
+ df = pd.read_csv(uploaded_file)
452
+ return df.to_string(), "csv"
453
+
454
+ elif file_type == 'xlsx':
455
+ df = pd.read_excel(uploaded_file)
456
+ return df.to_string(), "xlsx"
457
+
458
+ elif file_type == 'json':
459
+ content = json.load(uploaded_file)
460
+ return json.dumps(content, indent=2), "json"
461
+
462
+ elif file_type == 'yaml':
463
+ content = yaml.safe_load(uploaded_file)
464
+ return yaml.dump(content), "yaml"
465
+
466
+ else: # Default text handling
467
+ return uploaded_file.getvalue().decode(), "txt"
468
+
469
+ except Exception as e:
470
+ st.error(f"🚨 Oops! Error reading {uploaded_file.name}: {str(e)}")
471
+ return None, None
472
+
473
+ # πŸ’Ύ File Saver - Keeping our files safe and sound
474
+ def save_file_content(content, filename, file_type):
475
+ """Smart file saver with enhanced markdown handling"""
476
+ try:
477
+ if file_type == "md":
478
+ with open(filename, 'w') as f:
479
+ f.write(content)
480
+ st.session_state.rendered_content[filename] = content
481
+ add_to_history(filename, content, "saved")
482
+
483
+ elif file_type in ["csv", "xlsx"]:
484
+ df = pd.read_csv(StringIO(content)) if file_type == "csv" else pd.read_excel(StringIO(content))
485
+ if file_type == "csv":
486
+ df.to_csv(filename, index=False)
487
+ else:
488
+ df.to_excel(filename, index=False)
489
+
490
+ elif file_type == "json":
491
+ with open(filename, 'w') as f:
492
+ json.dump(json.loads(content), f, indent=2)
493
+
494
+ elif file_type == "yaml":
495
+ with open(filename, 'w') as f:
496
+ yaml.dump(yaml.safe_load(content), f)
497
+
498
+ else: # Default text handling
499
+ with open(filename, 'w') as f:
500
+ f.write(content)
501
+
502
+ return True
503
+ except Exception as e:
504
+ st.error(f"🚨 Error saving {filename}: {str(e)}")
505
+ return False
506
+
507
+ # 🎭 Main Show - Where the magic happens!
508
+ def main():
509
+ st.title("πŸ“šβœ¨ Super Smart File Handler with Markdown Magic! βœ¨πŸ“š")
510
+
511
+ # Show markdown history in sidebar
512
+ show_sidebar_history()
513
+
514
+ # Add tabs for different upload methods
515
+ upload_tab, book_tab = st.tabs(["πŸ“€ File Upload", "πŸ“– Book View"])
516
+
517
+ with upload_tab:
518
+ col1, col2 = st.columns(2)
519
+
520
+ with col1:
521
+ single_uploaded_file = st.file_uploader(
522
+ "πŸ“€ Upload single file",
523
+ type=list(FILE_TYPES.keys()),
524
+ help="Supports: " + ", ".join([f"{v} (.{k})" for k, v in FILE_TYPES.items()]),
525
+ key="single_uploader"
526
+ )
527
+
528
+ with col2:
529
+ multiple_uploaded_files = st.file_uploader(
530
+ "πŸ“š Upload multiple files",
531
+ type=list(FILE_TYPES.keys()),
532
+ accept_multiple_files=True,
533
+ help="Upload multiple files to view as a book",
534
+ key="multiple_uploader"
535
+ )
536
+
537
+ # Process single file upload
538
+ if single_uploaded_file:
539
+ content, file_type = read_file_content(single_uploaded_file)
540
+ if content is not None:
541
+ st.session_state.file_data[single_uploaded_file.name] = content
542
+ st.session_state.file_types[single_uploaded_file.name] = file_type
543
+ st.success(f"πŸŽ‰ Loaded {FILE_TYPES.get(file_type, 'πŸ“„')} file: {single_uploaded_file.name}")
544
+
545
+ # Process multiple file upload
546
+ if multiple_uploaded_files:
547
+ for uploaded_file in multiple_uploaded_files:
548
+ content, file_type = read_file_content(uploaded_file)
549
+ if content is not None:
550
+ st.session_state.file_data[uploaded_file.name] = content
551
+ st.session_state.file_types[uploaded_file.name] = file_type
552
+ st.success(f"πŸŽ‰ Loaded {len(multiple_uploaded_files)} files")
553
+
554
+ # Show file history
555
+ show_file_history()
556
+
557
+ # Show individual files
558
+ if st.session_state.file_data:
559
+ st.subheader("πŸ“‚ Your Files")
560
+ for filename, content in st.session_state.file_data.items():
561
+ file_type = st.session_state.file_types[filename]
562
+ with st.expander(f"{FILE_TYPES.get(file_type, 'πŸ“„')} {filename}"):
563
+ if file_type == "md":
564
+ content = create_markdown_tabs(content, filename)
565
+ else:
566
+ edited_content = st.text_area(
567
+ "Content",
568
+ content,
569
+ height=300,
570
+ key=f"edit_{filename}"
571
+ )
572
+ if edited_content != content:
573
+ st.session_state.file_data[filename] = edited_content
574
+ content = edited_content
575
+
576
+ if st.button(f"πŸ’Ύ Save {filename}"):
577
+ if save_file_content(content, filename, file_type):
578
+ st.success(f"✨ Saved {filename} successfully!")
579
+
580
+ with book_tab:
581
+ show_book_view()
582
+
583
+ if __name__ == "__main__":
584
+ main()