awacke1 commited on
Commit
8d67e66
Β·
verified Β·
1 Parent(s): 92897ad

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +202 -292
app.py CHANGED
@@ -1,5 +1,5 @@
1
  import streamlit as st
2
- from streamlit.components.v1 import html
3
  from pathlib import Path
4
  import json
5
  import time
@@ -7,322 +7,232 @@ 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
- # File type definitions
18
- FILE_TYPES = {
19
- "md": "πŸ“ Markdown",
20
- "txt": "πŸ“„ Text",
21
- "json": "πŸ”§ JSON",
22
- "csv": "πŸ“Š CSV",
23
- "xlsx": "πŸ“— Excel",
24
- "yaml": "βš™οΈ YAML",
25
- "xml": "πŸ”— XML"
26
- }
27
-
28
- # Initialize session state
29
- for key in ['file_data', 'file_types', 'md_outline', 'rendered_content',
30
- 'file_history', 'md_versions', 'md_files_history', 'combined_markdown']:
31
- if key not in st.session_state:
32
- st.session_state[key] = {} if key in ['file_data', 'file_types', 'md_outline',
33
- 'rendered_content', 'md_versions'] else [] if key in ['file_history',
34
- 'md_files_history'] else ""
35
-
36
- def encode_content(content):
37
- """Encode content to base64"""
38
- return base64.b64encode(content.encode()).decode()
39
-
40
- def decode_content(encoded_content):
41
- """Decode content from base64"""
42
- return base64.b64decode(encoded_content.encode()).decode()
43
-
44
- def parse_markdown_outline(content):
45
- """Generate an outline from markdown content"""
46
- return [{'level': len(line.split()[0]), 'title': line.strip('#').strip(),
47
- 'indent': ' ' * (len(line.split()[0]) - 1)}
48
- for line in content.split('\n') if line.strip().startswith('#')]
49
-
50
- def get_binary_file_downloader_html(bin_file, file_label='File'):
51
- """Generate download link"""
52
- b64 = encode_content(bin_file)
53
- return f'<a href="data:text/plain;base64,{b64}" download="{file_label}">πŸ“₯ Download {file_label}</a>'
54
-
55
- def add_to_history(filename, content, action="uploaded"):
56
- """Add a file action to history with timestamp"""
57
- timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
58
- encoded_content = encode_content(content)
 
 
59
 
60
- st.session_state.file_history.insert(0, {
61
- "timestamp": timestamp,
62
- "filename": filename,
63
- "action": action,
64
- "content": encoded_content
65
- })
66
 
67
- if filename.endswith('.md'):
68
- if filename not in st.session_state.md_versions:
69
- st.session_state.md_versions[filename] = []
70
-
71
- st.session_state.md_versions[filename].append({
72
- "timestamp": timestamp,
73
- "content": encoded_content,
74
- "action": action
75
- })
76
-
77
- if filename not in [f["filename"] for f in st.session_state.md_files_history]:
78
- st.session_state.md_files_history.append({
79
- "filename": filename,
80
- "timestamp": timestamp,
81
- "content": encoded_content
82
- })
83
-
84
- st.session_state.combined_markdown = combine_markdown_files()
85
-
86
- def combine_markdown_files():
87
- """Combine markdown files into a single document"""
88
- return "".join([f"# {md_file['filename']}\n\n{decode_content(md_file['content'])}\n\n---\n\n"
89
- for md_file in sorted(st.session_state.md_files_history,
90
- key=lambda x: x["filename"])])
91
-
92
- def scan_and_load_files():
93
- """Scan directory for supported files and load them"""
94
- loaded_files = []
95
- for ext in FILE_TYPES.keys():
96
- for filepath in glob.glob(f"*.{ext}"):
97
- try:
98
- with open(filepath, 'r', encoding='utf-8') as f:
99
- content = f.read()
100
- file_type = filepath.split('.')[-1].lower()
101
-
102
- st.session_state.file_data[filepath] = content
103
- st.session_state.file_types[filepath] = file_type
104
-
105
- if file_type == 'md':
106
- st.session_state.md_outline[filepath] = parse_markdown_outline(content)
107
- st.session_state.rendered_content[filepath] = content
108
- if filepath not in [f["filename"] for f in st.session_state.md_files_history]:
109
- add_to_history(filepath, content, "auto-loaded")
110
-
111
- loaded_files.append(filepath)
112
- except Exception as e:
113
- st.error(f"🚨 Error loading {filepath}: {str(e)}")
114
 
115
- return loaded_files
116
-
117
- def show_markdown_versions(filename):
118
- """Display previous versions of a markdown file"""
119
- if filename in st.session_state.md_versions and len(st.session_state.md_versions[filename]) > 1:
120
- st.markdown("### πŸ“š Previous Versions")
121
- version_idx = st.selectbox(
122
- "Select version to view",
123
- range(len(st.session_state.md_versions[filename])-1),
124
- format_func=lambda x: f"Version {len(st.session_state.md_versions[filename])-1-x} - {st.session_state.md_versions[filename][x]['timestamp']}"
125
- )
126
 
127
- if version_idx is not None:
128
- version = st.session_state.md_versions[filename][version_idx]
129
- decoded_content = decode_content(version['content'])
130
- st.text_area("Content", decoded_content, height=200,
131
- key=f"version_{filename}_{version_idx}", disabled=True)
132
-
133
- if st.button(f"Restore to this version", key=f"restore_{filename}_{version_idx}"):
134
- st.session_state.file_data[filename] = decoded_content
135
- st.session_state.md_outline[filename] = parse_markdown_outline(decoded_content)
136
- add_to_history(filename, decoded_content, "restored")
 
 
 
 
137
  st.rerun()
138
 
139
- def create_markdown_tabs(content, filename):
140
- """Create tabs for markdown content viewing and editing"""
141
- tab1, tab2, tab3 = st.tabs(["πŸ“ Editor", "πŸ‘€ Preview", "πŸ•’ History"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
 
143
  with tab1:
144
- edited_content = st.text_area("Edit your markdown", content, height=300,
145
- key=f"edit_{filename}")
146
- if edited_content != content:
147
- st.session_state.file_data[filename] = edited_content
148
- st.session_state.md_outline[filename] = parse_markdown_outline(edited_content)
149
- add_to_history(filename, edited_content, "edited")
150
- content = edited_content
151
 
152
  with tab2:
153
- st.markdown("### Preview")
154
- st.markdown(content)
155
- if filename in st.session_state.md_outline:
156
- st.markdown("---\n### πŸ“‘ Document Outline")
157
- for item in st.session_state.md_outline[filename]:
158
- st.markdown(f"{item['indent']}β€’ {item['title']}")
 
 
 
159
 
160
- with tab3:
161
- show_markdown_versions(filename)
 
162
 
163
- return content
164
-
165
- def show_sidebar_history():
166
- """Display markdown file history in sidebar"""
167
- st.sidebar.markdown("### πŸ“š Markdown Files History")
168
-
169
- if st.sidebar.button("πŸ—‘οΈ Delete All (except README.md)"):
170
- files_to_remove = [f for f in st.session_state.md_files_history if f["filename"] != "README.md"]
171
- for file in files_to_remove:
172
- filename = file["filename"]
173
- for key in ['file_data', 'file_types', 'md_outline', 'rendered_content', 'md_versions']:
174
- if filename in st.session_state[key]:
175
- del st.session_state[key][filename]
176
-
177
- st.session_state.md_files_history = [f for f in st.session_state.md_files_history
178
- if f["filename"] == "README.md"]
179
- st.session_state.combined_markdown = ""
180
- st.sidebar.success(f"Deleted {len(files_to_remove)} markdown files")
181
- st.rerun()
182
-
183
- for md_file in st.session_state.md_files_history:
184
- col1, col2, col3 = st.sidebar.columns([2, 1, 1])
185
- with col1:
186
- st.markdown(f"**{md_file['filename']}**")
187
  with col2:
188
- if st.button("πŸ“‚", key=f"open_{md_file['filename']}"):
189
- content = decode_content(md_file['content'])
190
- st.session_state.file_data[md_file['filename']] = content
191
- st.session_state.file_types[md_file['filename']] = "md"
192
- st.session_state.md_outline[md_file['filename']] = parse_markdown_outline(content)
193
- st.rerun()
 
 
 
 
 
194
  with col3:
195
- st.markdown(get_binary_file_downloader_html(
196
- decode_content(md_file['content']), md_file['filename']), unsafe_allow_html=True)
197
-
198
- def show_file_history():
199
- """Display file history in collapsible section"""
200
- if st.session_state.file_history:
201
- with st.expander("πŸ“‹ File History", expanded=False):
202
- st.markdown("### Recent File Activities")
203
- for entry in st.session_state.file_history:
204
- col1, col2 = st.columns([2, 3])
205
- with col1:
206
- st.markdown(f"**{entry['timestamp']}**")
207
- with col2:
208
- st.markdown(f"{entry['action'].title()}: {entry['filename']}")
209
-
210
- def read_file_content(uploaded_file):
211
- """Smart file reader with enhanced markdown handling"""
212
- file_type = uploaded_file.name.split('.')[-1].lower()
213
- try:
214
- if file_type == 'md':
215
- content = uploaded_file.getvalue().decode()
216
- st.session_state.md_outline[uploaded_file.name] = parse_markdown_outline(content)
217
- st.session_state.rendered_content[uploaded_file.name] = content
218
- add_to_history(uploaded_file.name, content)
219
- return content, "md"
220
- elif file_type in ['csv', 'xlsx']:
221
- df = pd.read_csv(uploaded_file) if file_type == 'csv' else pd.read_excel(uploaded_file)
222
- return df.to_string(), file_type
223
- elif file_type == 'json':
224
- return json.dumps(json.load(uploaded_file), indent=2), "json"
225
- elif file_type == 'yaml':
226
- return yaml.dump(yaml.safe_load(uploaded_file)), "yaml"
227
- else:
228
- return uploaded_file.getvalue().decode(), "txt"
229
- except Exception as e:
230
- st.error(f"🚨 Error reading {uploaded_file.name}: {str(e)}")
231
- return None, None
232
-
233
- def save_file_content(content, filename, file_type):
234
- """Smart file saver with enhanced markdown handling"""
235
- try:
236
- if file_type == "md":
237
- with open(filename, 'w') as f:
238
- f.write(content)
239
- st.session_state.rendered_content[filename] = content
240
- add_to_history(filename, content, "saved")
241
- elif file_type in ["csv", "xlsx"]:
242
- df = pd.read_csv(StringIO(content)) if file_type == "csv" else pd.read_excel(StringIO(content))
243
- df.to_csv(filename, index=False) if file_type == "csv" else df.to_excel(filename, index=False)
244
- elif file_type == "json":
245
- with open(filename, 'w') as f:
246
- json.dump(json.loads(content), f, indent=2)
247
- elif file_type == "yaml":
248
- with open(filename, 'w') as f:
249
- yaml.dump(yaml.safe_load(content), f)
250
- else:
251
- with open(filename, 'w') as f:
252
- f.write(content)
253
- return True
254
- except Exception as e:
255
- st.error(f"🚨 Error saving {filename}: {str(e)}")
256
- return False
257
 
258
  def main():
259
- # Perform initial file scan
260
- loaded_files = scan_and_load_files()
261
 
262
- st.title("πŸ“šβœ¨ Super Smart File Handler with Markdown Magic! βœ¨πŸ“š")
263
- show_sidebar_history()
264
 
265
- upload_tab, book_tab = st.tabs(["πŸ“€ File Upload", "πŸ“– Book View"])
 
 
 
 
266
 
267
- with upload_tab:
268
- col1, col2 = st.columns(2)
269
- with col1:
270
- single_uploaded_file = st.file_uploader(
271
- "πŸ“€ Upload single file",
272
- type=list(FILE_TYPES.keys()),
273
- help="Supports: " + ", ".join([f"{v} (.{k})" for k, v in FILE_TYPES.items()]),
274
- key="single_uploader"
275
- )
276
-
277
- with col2:
278
- multiple_uploaded_files = st.file_uploader(
279
- "πŸ“š Upload multiple files",
280
- type=list(FILE_TYPES.keys()),
281
- accept_multiple_files=True,
282
- help="Upload multiple files to view as a book",
283
- key="multiple_uploader"
284
- )
285
-
286
- if single_uploaded_file:
287
- content, file_type = read_file_content(single_uploaded_file)
288
- if content is not None:
289
- st.session_state.file_data[single_uploaded_file.name] = content
290
- st.session_state.file_types[single_uploaded_file.name] = file_type
291
- st.success(f"πŸŽ‰ Loaded {FILE_TYPES.get(file_type, 'πŸ“„')} file: {single_uploaded_file.name}")
292
-
293
- if multiple_uploaded_files:
294
- for uploaded_file in multiple_uploaded_files:
295
- content, file_type = read_file_content(uploaded_file)
296
- if content is not None:
297
- st.session_state.file_data[uploaded_file.name] = content
298
- st.session_state.file_types[uploaded_file.name] = file_type
299
- st.success(f"πŸŽ‰ Loaded {len(multiple_uploaded_files)} files")
300
- st.rerun()
301
-
302
- show_file_history()
303
 
304
- if st.session_state.file_data:
305
- st.subheader("πŸ“‚ Your Files")
306
- for filename, content in st.session_state.file_data.items():
307
- file_type = st.session_state.file_types[filename]
308
- with st.expander(f"{FILE_TYPES.get(file_type, 'πŸ“„')} {filename}"):
309
- if file_type == "md":
310
- content = create_markdown_tabs(content, filename)
311
- else:
312
- edited_content = st.text_area(
313
- "Content", content, height=300, key=f"edit_{filename}")
314
- if edited_content != content:
315
- st.session_state.file_data[filename] = edited_content
316
- content = edited_content
317
-
318
- if st.button(f"πŸ’Ύ Save {filename}"):
319
- if save_file_content(content, filename, file_type):
320
- st.success(f"✨ Saved {filename} successfully!")
321
-
322
- with book_tab:
323
- if st.session_state.combined_markdown:
324
- st.markdown("## πŸ“– Book View")
325
- st.markdown(st.session_state.combined_markdown)
326
 
327
  if __name__ == "__main__":
328
  main()
 
1
  import streamlit as st
2
+ from streamlit.components.v1 import components
3
  from pathlib import Path
4
  import json
5
  import time
 
7
  import re
8
  import pandas as pd
9
  import yaml
10
+ from io import StringIO, BytesIO
11
  import openpyxl
12
  import csv
13
  import base64
14
  import glob
15
  import os
16
+ import zipfile
17
+
18
+ # Initialize session state for chat history if not exists
19
+ if 'chat_history' not in st.session_state:
20
+ st.session_state.chat_history = []
21
+ if 'messages' not in st.session_state:
22
+ st.session_state.messages = []
23
+ if 'current_file' not in st.session_state:
24
+ st.session_state.current_file = None
25
+ if 'file_content' not in st.session_state:
26
+ st.session_state.file_content = None
27
+
28
+ def create_zip_of_files(files):
29
+ """Create a zip file containing all markdown files"""
30
+ zip_buffer = BytesIO()
31
+ with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:
32
+ for file in files:
33
+ with open(file, 'r', encoding='utf-8') as f:
34
+ zip_file.writestr(file, f.read())
35
+ return zip_buffer.getvalue()
36
+
37
+ def get_download_link(file_path):
38
+ """Create a download link for a file"""
39
+ if isinstance(file_path, bytes): # For zip files
40
+ b64 = base64.b64encode(file_path).decode()
41
+ href = f'data:application/zip;base64,{b64}'
42
+ filename = 'all_files.zip'
43
+ else: # For individual files
44
+ with open(file_path, 'r', encoding='utf-8') as f:
45
+ content = f.read()
46
+ b64 = base64.b64encode(content.encode()).decode()
47
+ href = f'data:text/markdown;base64,{b64}'
48
+ filename = os.path.basename(file_path)
49
+ return f'<a href="{href}" download="{filename}">{filename}</a>'
50
+
51
+ def load_file(filepath):
52
+ """Load file content"""
53
+ with open(filepath, 'r', encoding='utf-8') as f:
54
+ return f.read()
55
+
56
+ def display_file_manager():
57
+ """Display file management sidebar with guaranteed unique button keys."""
58
+ st.sidebar.title("πŸ“ File Management")
59
+ all_files = glob.glob("*.md")
60
+ all_files.sort(reverse=True)
61
 
62
+ if st.sidebar.button("πŸ—‘ Delete All", key="delete_all_files_button"):
63
+ for file in all_files:
64
+ os.remove(file)
65
+ st.rerun()
 
 
66
 
67
+ if st.sidebar.button("⬇️ Download All", key="download_all_files_button"):
68
+ zip_file = create_zip_of_files(all_files)
69
+ st.sidebar.markdown(get_download_link(zip_file), unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
+ for idx, file in enumerate(all_files):
72
+ file_stat = os.stat(file)
73
+ unique_id = f"{idx}_{file_stat.st_size}_{file_stat.st_mtime}"
 
 
 
 
 
 
 
 
74
 
75
+ col1, col2, col3, col4 = st.sidebar.columns([1,3,1,1])
76
+ with col1:
77
+ if st.button("🌐", key=f"view_{unique_id}"):
78
+ st.session_state.current_file = file
79
+ st.session_state.file_content = load_file(file)
80
+ with col2:
81
+ st.markdown(get_download_link(file), unsafe_allow_html=True)
82
+ with col3:
83
+ if st.button("πŸ“‚", key=f"edit_{unique_id}"):
84
+ st.session_state.current_file = file
85
+ st.session_state.file_content = load_file(file)
86
+ with col4:
87
+ if st.button("πŸ—‘", key=f"delete_{unique_id}"):
88
+ os.remove(file)
89
  st.rerun()
90
 
91
+ def process_with_gpt(user_input):
92
+ """Process input with GPT-4"""
93
+ # Add your GPT processing logic here
94
+ response = f"GPT-4 Response to: {user_input}"
95
+ st.session_state.messages.append({"role": "user", "content": user_input})
96
+ st.session_state.messages.append({"role": "assistant", "content": response})
97
+ return response
98
+
99
+ def process_with_claude(user_input):
100
+ """Process input with Claude"""
101
+ # Add your Claude processing logic here
102
+ response = f"Claude Response to: {user_input}"
103
+ st.session_state.chat_history.append({
104
+ "user": user_input,
105
+ "claude": response
106
+ })
107
+ return response
108
+
109
+ def perform_ai_lookup(query):
110
+ """Perform AI lookup with ArXiv"""
111
+ # Add your ArXiv lookup logic here
112
+ return f"ArXiv results for: {query}"
113
+
114
+ def search_arxiv(query):
115
+ """Search ArXiv papers"""
116
+ # Add your ArXiv search logic here
117
+ return f"ArXiv search results for: {query}"
118
+
119
+ def create_media_gallery():
120
+ """Create media gallery interface"""
121
+ st.subheader("Media Gallery")
122
+ st.write("Media gallery functionality goes here")
123
+
124
+ def show_chat_history():
125
+ """Display chat history for both models"""
126
+ st.subheader("Chat History πŸ“œ")
127
+ tab1, tab2 = st.tabs(["Claude History", "GPT-4o History"])
128
 
129
  with tab1:
130
+ for chat in st.session_state.chat_history:
131
+ st.text_area("You:", chat["user"], height=100)
132
+ st.text_area("Claude:", chat["claude"], height=200)
133
+ st.markdown(chat["claude"])
 
 
 
134
 
135
  with tab2:
136
+ for message in st.session_state.messages:
137
+ with st.chat_message(message["role"]):
138
+ st.markdown(message["content"])
139
+
140
+ def handle_voice_input(model_choice):
141
+ """Handle voice input tab logic"""
142
+ st.subheader("Voice Recognition")
143
+ if 'voice_transcript' not in st.session_state:
144
+ st.session_state.voice_transcript = ""
145
 
146
+ user_input = st.text_area("Message:", height=100)
147
+ if st.button("Send πŸ“¨") and user_input:
148
+ process_ai_input(user_input, model_choice)
149
 
150
+ show_chat_history()
151
+
152
+ def handle_file_editor():
153
+ """Handle file editor tab logic"""
154
+ if st.session_state.current_file:
155
+ st.subheader(f"Editing: {st.session_state.current_file}")
156
+ new_content = st.text_area("Content:", st.session_state.file_content, height=300)
157
+ if st.button("Save Changes"):
158
+ with open(st.session_state.current_file, 'w', encoding='utf-8') as file:
159
+ file.write(new_content)
160
+ st.success("File updated successfully!")
161
+
162
+ def process_ai_input(user_input, model_choice):
163
+ """Handle AI processing based on model choice"""
164
+ if model_choice == "GPT-4o":
165
+ gpt_response = process_with_gpt(user_input)
166
+ elif model_choice == "Claude-3":
167
+ claude_response = process_with_claude(user_input)
168
+ else: # All Three AIs
169
+ col1, col2, col3 = st.columns(3)
 
 
 
 
170
  with col2:
171
+ st.subheader("Claude-3.5 Sonnet:")
172
+ try:
173
+ claude_response = process_with_claude(user_input)
174
+ except:
175
+ st.write('Claude 3.5 Sonnet out of tokens.')
176
+ with col1:
177
+ st.subheader("GPT-4o Omni:")
178
+ try:
179
+ gpt_response = process_with_gpt(user_input)
180
+ except:
181
+ st.write('GPT 4o out of tokens')
182
  with col3:
183
+ st.subheader("Arxiv and Mistral Research:")
184
+ with st.spinner("Searching ArXiv..."):
185
+ try:
186
+ results = perform_ai_lookup(user_input)
187
+ st.markdown(results)
188
+ except:
189
+ st.write("Arxiv Mistral too busy - try again.")
190
+
191
+ def handle_arxiv_search():
192
+ """Handle ArXiv search tab logic"""
193
+ query = st.text_input("Enter your research query:")
194
+ if query:
195
+ with st.spinner("Searching ArXiv..."):
196
+ results = search_arxiv(query)
197
+ st.markdown(results)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
 
199
  def main():
200
+ st.sidebar.markdown("### 🚲BikeAIπŸ† Claude and GPT Multi-Agent Research AI")
 
201
 
202
+ # Display file manager in sidebar first
203
+ display_file_manager()
204
 
205
+ # Model Selection
206
+ model_choice = st.sidebar.radio(
207
+ "Choose AI Model:",
208
+ ["GPT+Claude+Arxiv", "GPT-4o", "Claude-3"]
209
+ )
210
 
211
+ # Main navigation
212
+ tab_main = st.radio("Choose Action:",
213
+ ["🎀 Voice Input", "πŸ“Έ Media Gallery", "πŸ” Search ArXiv", "πŸ“ File Editor"],
214
+ horizontal=True)
215
+
216
+ try:
217
+ # Component Magic section - wrapped in try/except in case component isn't available
218
+ mycomponent = components.declare_component("mycomponent", path="mycomponent")
219
+ value = mycomponent(my_input_value="hello there")
220
+ st.write("Received", value)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
 
222
+ if value is not None:
223
+ process_ai_input(value, model_choice)
224
+ except:
225
+ st.warning("Voice component not available")
226
+
227
+ # Handle main tab navigation
228
+ if tab_main == "🎀 Voice Input":
229
+ handle_voice_input(model_choice)
230
+ elif tab_main == "πŸ“Έ Media Gallery":
231
+ create_media_gallery()
232
+ elif tab_main == "πŸ” Search ArXiv":
233
+ handle_arxiv_search()
234
+ elif tab_main == "πŸ“ File Editor":
235
+ handle_file_editor()
 
 
 
 
 
 
 
 
236
 
237
  if __name__ == "__main__":
238
  main()