DavidFernandes commited on
Commit
449c102
Β·
verified Β·
1 Parent(s): e624137

Update pages/1_πŸ“_Document_Analysis.py

Browse files
Files changed (1) hide show
  1. pages/1_πŸ“_Document_Analysis.py +238 -262
pages/1_πŸ“_Document_Analysis.py CHANGED
@@ -1,263 +1,239 @@
1
- import streamlit as st
2
- from PIL import Image
3
- import datetime
4
- from theme import apply_dark_theme, show_page_header, show_footer
5
- from utils import (
6
- process_image,
7
- process_pdf,
8
- initialize_session_state,
9
- create_chat_engine,
10
- save_to_history,
11
- generate_pdf_analysis,
12
- process_captured_image,
13
- format_analysis_results
14
- )
15
-
16
- # Page config
17
- st.set_page_config(
18
- page_title="Document Analysis | CiviDoc AI",
19
- page_icon="πŸ“",
20
- layout="centered",
21
- initial_sidebar_state="collapsed",
22
- )
23
-
24
- # Apply dark theme
25
- st.markdown(apply_dark_theme(), unsafe_allow_html=True)
26
-
27
- def document_analysis_page():
28
- # Initialize states
29
- initialize_session_state()
30
-
31
- # Header
32
- st.markdown(show_page_header(
33
- "πŸ“ Document Analysis",
34
- "Upload or capture documents for instant analysis"
35
- ), unsafe_allow_html=True)
36
-
37
- # Main content tabs - Mobile friendly
38
- tabs = st.tabs([
39
- "πŸ“€ Upload ",
40
- "πŸ“Έ Capture",
41
- "πŸ“Š Results"
42
- ])
43
-
44
- with tabs[0]:
45
- st.markdown(
46
- "<div class='card'>"
47
- "<h3>Upload Documents</h3>"
48
- "<p style='margin-bottom: 2rem;'>Support for PDF, JPG, JPEG, and PNG files.</p>"
49
- "<div class='status-badge status-success'>Multiple files supported</div>"
50
- "</div>",
51
- unsafe_allow_html=True
52
- )
53
-
54
- # Mobile-friendly file uploader
55
- uploaded_files = st.file_uploader(
56
- "Drop files or tap to browse",
57
- type=["jpg", "jpeg", "png", "pdf"],
58
- accept_multiple_files=True,
59
- key="doc_uploader"
60
- )
61
-
62
- if uploaded_files:
63
- st.markdown(
64
- f"<div class='status-badge status-success' style='margin: 1rem 0;'>"
65
- f"πŸ“Ž {len(uploaded_files)} file(s) uploaded"
66
- f"</div>",
67
- unsafe_allow_html=True
68
- )
69
-
70
- # File list - Mobile friendly
71
- st.markdown(
72
- "<div class='card'>"
73
- "<h4>Selected Files:</h4>"
74
- "<div class='touch-spacing'>",
75
- unsafe_allow_html=True
76
- )
77
-
78
- for file in uploaded_files:
79
- st.markdown(
80
- f"<div style='display: flex; align-items: center; padding: 0.5rem 0;'>"
81
- f"<span style='margin-right: 0.5rem;'>πŸ“„</span>{file.name}"
82
- f"</div>",
83
- unsafe_allow_html=True
84
- )
85
-
86
- st.markdown("</div></div>", unsafe_allow_html=True)
87
-
88
- # Analysis button - Touch friendly
89
- if st.button("πŸ” Analyze Documents", use_container_width=True):
90
- process_uploaded_files(uploaded_files)
91
-
92
- with tabs[1]:
93
- st.markdown(
94
- "<div class='card'>"
95
- "<h3>Capture Document</h3>"
96
- "<p>Take a clear photo of your document using your camera.</p>"
97
- "</div>",
98
- unsafe_allow_html=True
99
- )
100
-
101
- # Mobile-optimized camera input
102
- picture = st.camera_input(
103
- "πŸ“Έ Tap to capture",
104
- help="Make sure the document is well-lit and clearly visible"
105
- )
106
-
107
- if picture:
108
- st.markdown(
109
- "<div class='status-badge status-success' style='margin: 1rem 0;'>"
110
- "πŸ“Έ Image captured successfully"
111
- "</div>",
112
- unsafe_allow_html=True
113
- )
114
-
115
- # Analysis button - Touch friendly
116
- if st.button("πŸ” Analyze Photo", use_container_width=True):
117
- process_captured_image(picture)
118
-
119
- with tabs[2]:
120
- display_analysis_results()
121
-
122
- def process_uploaded_files(files):
123
- """Process multiple uploaded files with mobile-friendly progress tracking"""
124
- progress_text = "Processing documents..."
125
- total_files = len(files)
126
-
127
- # Progress tracking
128
- progress_placeholder = st.empty()
129
- progress_bar = st.progress(0)
130
- status_text = st.empty()
131
-
132
- for idx, uploaded_file in enumerate(files, 1):
133
- try:
134
- # Update progress
135
- progress_placeholder.markdown(
136
- f"<div style='text-align: center; margin: 1rem 0;'>"
137
- f"Processing file {idx} of {total_files}"
138
- f"</div>",
139
- unsafe_allow_html=True
140
- )
141
-
142
- status_text.markdown(
143
- f"<div class='status-badge status-warning'>"
144
- f"πŸ“ Processing: {uploaded_file.name}"
145
- f"</div>",
146
- unsafe_allow_html=True
147
- )
148
-
149
- if uploaded_file.type in ['image/jpeg', 'image/png']:
150
- # Process image
151
- image = Image.open(uploaded_file)
152
- analysis = process_image(image)
153
-
154
- # Save results
155
- st.session_state.analyses[uploaded_file.name] = {
156
- 'type': uploaded_file.type,
157
- 'analysis': analysis,
158
- 'timestamp': datetime.datetime.now()
159
- }
160
-
161
- # Create chat engine
162
- st.session_state.chat_engines[uploaded_file.name] = create_chat_engine(analysis)
163
-
164
- elif uploaded_file.type == 'application/pdf':
165
- # Process PDF
166
- documents = process_pdf(uploaded_file)
167
- analysis = generate_pdf_analysis(documents)
168
-
169
- # Save results
170
- st.session_state.analyses[uploaded_file.name] = {
171
- 'type': uploaded_file.type,
172
- 'analysis': analysis,
173
- 'timestamp': datetime.datetime.now()
174
- }
175
-
176
- # Create chat engine
177
- st.session_state.chat_engines[uploaded_file.name] = create_chat_engine(documents)
178
-
179
- # Update progress
180
- progress_bar.progress(idx/total_files)
181
-
182
- # Save to history
183
- save_to_history(
184
- uploaded_file.name,
185
- uploaded_file.type.split('/')[1].upper(),
186
- analysis,
187
- datetime.datetime.now()
188
- )
189
-
190
- except Exception as e:
191
- st.error(
192
- f"❌ Error processing {uploaded_file.name}\n"
193
- f"Details: {str(e)}"
194
- )
195
-
196
- # Clear progress indicators
197
- progress_placeholder.empty()
198
- progress_bar.empty()
199
-
200
- # Show completion message
201
- status_text.markdown(
202
- "<div class='status-badge status-success' style='margin: 1rem 0;'>"
203
- "βœ… All documents processed successfully!"
204
- "</div>",
205
- unsafe_allow_html=True
206
- )
207
-
208
- # Mobile-friendly action buttons
209
- st.markdown("<div class='touch-spacing'>", unsafe_allow_html=True)
210
- if st.button("πŸ’¬ Start Chat", use_container_width=True):
211
- st.switch_page("pages/2_πŸ’¬_Document_Chat.py")
212
- if st.button("πŸ“€ Process More", use_container_width=True):
213
- st.rerun()
214
- st.markdown("</div>", unsafe_allow_html=True)
215
-
216
- def display_analysis_results():
217
- """Display analysis results with mobile-friendly layout"""
218
- if st.session_state.analyses:
219
- # Mobile-friendly filters
220
- st.markdown(
221
- "<div class='card' style='margin-bottom: 1rem;'>"
222
- "<h4>Filter Results</h4>",
223
- unsafe_allow_html=True
224
- )
225
-
226
- # Touch-friendly filter options
227
- filter_type = st.multiselect(
228
- "Document Type",
229
- ["Image", "PDF", "Captured"],
230
- default=["Image", "PDF", "Captured"]
231
- )
232
-
233
-
234
- st.markdown("</div>", unsafe_allow_html=True)
235
-
236
- # Display results
237
- if st.session_state.analyses:
238
- for filename, data in st.session_state.analyses.items():
239
- st.markdown(
240
- f"<div class='card'>"
241
- f"<div style='display: flex; justify-content: space-between; align-items: center;'>"
242
- f"<h4>{filename}</h4>"
243
- f"<div class='status-badge status-success'>{data['type'].split('/')[1].upper()}</div>"
244
- f"</div>"
245
- f"<hr style='margin: 0.5rem 0;'>"
246
- f"{format_analysis_results(data['analysis'])}" # Use the formatting function
247
- f"<div class='touch-spacing'>"
248
- f"</div>"
249
- f"</div>",
250
- unsafe_allow_html=True
251
- )
252
- else:
253
- st.markdown(
254
- "<div class='card' style='text-align: center;'>"
255
- "<h3>No Documents Analyzed</h3>"
256
- "<p>Upload or capture documents to see analysis results here.</p>"
257
- "</div>",
258
- unsafe_allow_html=True
259
- )
260
-
261
-
262
- if __name__ == "__main__":
263
  document_analysis_page()
 
1
+ import streamlit as st
2
+ from PIL import Image
3
+ import datetime
4
+ from theme import apply_dark_theme, show_page_header, show_footer
5
+ from utils import (
6
+ process_image,
7
+ process_pdf,
8
+ initialize_session_state,
9
+ create_chat_engine,
10
+ save_to_history,
11
+ generate_pdf_analysis,
12
+ process_captured_image,
13
+ format_analysis_results
14
+ )
15
+
16
+ # Page config
17
+ st.set_page_config(
18
+ page_title="Document Analysis | CiviDoc AI",
19
+ page_icon="πŸ“",
20
+ layout="centered",
21
+ initial_sidebar_state="collapsed",
22
+ )
23
+
24
+ # Apply dark theme
25
+ st.markdown(apply_dark_theme(), unsafe_allow_html=True)
26
+
27
+ def document_analysis_page():
28
+ # Initialize states
29
+ initialize_session_state()
30
+
31
+ # Header
32
+ st.markdown(show_page_header(
33
+ "πŸ“ Document Analysis",
34
+ "Upload or capture documents for instant analysis"
35
+ ), unsafe_allow_html=True)
36
+
37
+ # Main content tabs - Mobile friendly
38
+ tabs = st.tabs([
39
+ "πŸ“€ Upload ",
40
+ "πŸ“Έ Capture",
41
+ "πŸ“Š Results"
42
+ ])
43
+
44
+ with tabs[0]:
45
+ st.markdown(
46
+ "<div class='card'>"
47
+ "<h3>Upload Documents</h3>"
48
+ "<p style='margin-bottom: 2rem;'>Support for PDF, JPG, JPEG, and PNG files.</p>"
49
+ "<div class='status-badge status-success'>Multiple files supported</div>"
50
+ "</div>",
51
+ unsafe_allow_html=True
52
+ )
53
+
54
+ # Mobile-friendly file uploader
55
+ uploaded_files = st.file_uploader(
56
+ "Drop files or tap to browse",
57
+ type=["jpg", "jpeg", "png", "pdf"],
58
+ accept_multiple_files=True,
59
+ key="doc_uploader"
60
+ )
61
+
62
+ if uploaded_files:
63
+ st.markdown(
64
+ f"<div class='status-badge status-success' style='margin: 1rem 0;'>"
65
+ f"πŸ“Ž {len(uploaded_files)} file(s) uploaded"
66
+ f"</div>",
67
+ unsafe_allow_html=True
68
+ )
69
+
70
+ # File list - Mobile friendly
71
+ st.markdown(
72
+ "<div class='card'>"
73
+ "<h4>Selected Files:</h4>"
74
+ "<div class='touch-spacing'>",
75
+ unsafe_allow_html=True
76
+ )
77
+
78
+ for file in uploaded_files:
79
+ st.markdown(
80
+ f"<div style='display: flex; align-items: center; padding: 0.5rem 0;'>"
81
+ f"<span style='margin-right: 0.5rem;'>πŸ“„</span>{file.name}"
82
+ f"</div>",
83
+ unsafe_allow_html=True
84
+ )
85
+
86
+ st.markdown("</div></div>", unsafe_allow_html=True)
87
+
88
+ # Analysis button - Touch friendly
89
+ if st.button("πŸ” Analyze Documents", use_container_width=True):
90
+ process_uploaded_files(uploaded_files)
91
+
92
+ with tabs[1]:
93
+ st.markdown(
94
+ "<div class='card'>"
95
+ "<h3>Capture Document</h3>"
96
+ "<p>Take a clear photo of your document using your camera.</p>"
97
+ "</div>",
98
+ unsafe_allow_html=True
99
+ )
100
+
101
+ # Mobile-optimized camera input
102
+ picture = st.camera_input(
103
+ "πŸ“Έ Tap to capture",
104
+ help="Make sure the document is well-lit and clearly visible"
105
+ )
106
+
107
+ if picture:
108
+ st.markdown(
109
+ "<div class='status-badge status-success' style='margin: 1rem 0;'>"
110
+ "πŸ“Έ Image captured successfully"
111
+ "</div>",
112
+ unsafe_allow_html=True
113
+ )
114
+
115
+ # Analysis button - Touch friendly
116
+ if st.button("πŸ” Analyze Photo", use_container_width=True):
117
+ process_captured_image(picture)
118
+
119
+ with tabs[2]:
120
+ display_analysis_results()
121
+
122
+ def process_uploaded_files(files):
123
+ """Process multiple uploaded files with mobile-friendly progress tracking"""
124
+ progress_text = "Processing documents..."
125
+ total_files = len(files)
126
+
127
+ # Progress tracking
128
+ progress_placeholder = st.empty()
129
+ progress_bar = st.progress(0)
130
+ status_text = st.empty()
131
+
132
+ for idx, uploaded_file in enumerate(files, 1):
133
+ try:
134
+ # Update progress
135
+ progress_placeholder.markdown(
136
+ f"<div style='text-align: center; margin: 1rem 0;'>"
137
+ f"Processing file {idx} of {total_files}"
138
+ f"</div>",
139
+ unsafe_allow_html=True
140
+ )
141
+
142
+ status_text.markdown(
143
+ f"<div class='status-badge status-warning'>"
144
+ f"πŸ“ Processing: {uploaded_file.name}"
145
+ f"</div>",
146
+ unsafe_allow_html=True
147
+ )
148
+
149
+ if uploaded_file.type in ['image/jpeg', 'image/png']:
150
+ # Process image
151
+ image = Image.open(uploaded_file)
152
+ analysis = process_image(image)
153
+
154
+ # Save results
155
+ st.session_state.analyses[uploaded_file.name] = {
156
+ 'type': uploaded_file.type,
157
+ 'analysis': analysis,
158
+ 'timestamp': datetime.datetime.now()
159
+ }
160
+
161
+ # Create chat engine
162
+ st.session_state.chat_engines[uploaded_file.name] = create_chat_engine(analysis)
163
+
164
+ elif uploaded_file.type == 'application/pdf':
165
+ # Process PDF
166
+ documents = process_pdf(uploaded_file)
167
+ analysis = generate_pdf_analysis(documents)
168
+
169
+ # Save results
170
+ st.session_state.analyses[uploaded_file.name] = {
171
+ 'type': uploaded_file.type,
172
+ 'analysis': analysis,
173
+ 'timestamp': datetime.datetime.now()
174
+ }
175
+
176
+ # Create chat engine
177
+ st.session_state.chat_engines[uploaded_file.name] = create_chat_engine(documents)
178
+
179
+ # Update progress
180
+ progress_bar.progress(idx/total_files)
181
+
182
+ # Save to history
183
+ save_to_history(
184
+ uploaded_file.name,
185
+ uploaded_file.type.split('/')[1].upper(),
186
+ analysis,
187
+ datetime.datetime.now()
188
+ )
189
+
190
+ except Exception as e:
191
+ st.error(
192
+ f"❌ Error processing {uploaded_file.name}\n"
193
+ f"Details: {str(e)}"
194
+ )
195
+
196
+ # Clear progress indicators
197
+ progress_placeholder.empty()
198
+ progress_bar.empty()
199
+
200
+ # Show completion message
201
+ status_text.markdown(
202
+ "<div class='status-badge status-success' style='margin: 1rem 0;'>"
203
+ "βœ… All documents processed successfully!"
204
+ "</div>",
205
+ unsafe_allow_html=True
206
+ )
207
+
208
+ def display_analysis_results():
209
+ """Display analysis results with mobile-friendly layout"""
210
+ if st.session_state.analyses:
211
+
212
+ # Display results
213
+ if st.session_state.analyses:
214
+ for filename, data in st.session_state.analyses.items():
215
+ st.markdown(
216
+ f"<div class='card'>"
217
+ f"<div style='display: flex; justify-content: space-between; align-items: center;'>"
218
+ f"<h4>{filename}</h4>"
219
+ f"<div class='status-badge status-success'>{data['type'].split('/')[1].upper()}</div>"
220
+ f"</div>"
221
+ f"<hr style='margin: 0.5rem 0;'>"
222
+ f"{format_analysis_results(data['analysis'])}" # Use the formatting function
223
+ f"<div class='touch-spacing'>"
224
+ f"</div>"
225
+ f"</div>",
226
+ unsafe_allow_html=True
227
+ )
228
+ else:
229
+ st.markdown(
230
+ "<div class='card' style='text-align: center;'>"
231
+ "<h3>No Documents Analyzed</h3>"
232
+ "<p>Upload or capture documents to see analysis results here.</p>"
233
+ "</div>",
234
+ unsafe_allow_html=True
235
+ )
236
+
237
+
238
+ if __name__ == "__main__":
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
  document_analysis_page()