ChakriYamasani commited on
Commit
1d5050d
·
verified ·
1 Parent(s): 1f8daa5

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +695 -0
app.py ADDED
@@ -0,0 +1,695 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import json
3
+ import os
4
+ import datetime
5
+ import pandas as pd
6
+ import folium
7
+ from streamlit_folium import st_folium
8
+ from PIL import Image
9
+ import base64
10
+ from helpers import (
11
+ load_entries, save_entry, get_categories, get_languages,
12
+ text_to_speech, speech_to_text, geocode_location,
13
+ export_to_jsonl, export_to_csv, search_entries,
14
+ register_user, authenticate_user, get_user_info, update_user_entry_count,
15
+ translate_text, detect_language
16
+ )
17
+
18
+ # Set page config
19
+ st.set_page_config(
20
+ page_title="Farming Wisdom Archive",
21
+ page_icon="🌾",
22
+ layout="wide",
23
+ initial_sidebar_state="expanded"
24
+ )
25
+
26
+ # Initialize session state
27
+ if 'entries' not in st.session_state:
28
+ st.session_state.entries = load_entries()
29
+ if 'audio_recording' not in st.session_state:
30
+ st.session_state.audio_recording = False
31
+ if 'selected_location' not in st.session_state:
32
+ st.session_state.selected_location = None
33
+ if 'authenticated' not in st.session_state:
34
+ st.session_state.authenticated = False
35
+ if 'username' not in st.session_state:
36
+ st.session_state.username = None
37
+ if 'show_login' not in st.session_state:
38
+ st.session_state.show_login = True
39
+
40
+ # Authentication check
41
+ if not st.session_state.authenticated:
42
+ st.title("🌾 Farming Wisdom Archive")
43
+ st.markdown("*Preserving Traditional Indian Farming Knowledge*")
44
+
45
+ # Create tabs for login and registration
46
+ tab1, tab2 = st.tabs(["Login", "Register"])
47
+
48
+ with tab1:
49
+ st.subheader("Welcome Back!")
50
+ with st.form("login_form"):
51
+ username = st.text_input("Username")
52
+ password = st.text_input("Password", type="password")
53
+ login_button = st.form_submit_button("Login", type="primary")
54
+
55
+ if login_button:
56
+ if username and password:
57
+ if authenticate_user(username, password):
58
+ st.session_state.authenticated = True
59
+ st.session_state.username = username
60
+ st.success("Login successful!")
61
+ st.rerun()
62
+ else:
63
+ st.error("Invalid username or password")
64
+ else:
65
+ st.error("Please enter both username and password")
66
+
67
+ with tab2:
68
+ st.subheader("Join Our Community")
69
+ with st.form("register_form"):
70
+ full_name = st.text_input("Full Name")
71
+ email = st.text_input("Email")
72
+ reg_username = st.text_input("Choose Username")
73
+ reg_password = st.text_input("Choose Password", type="password")
74
+ confirm_password = st.text_input("Confirm Password", type="password")
75
+ register_button = st.form_submit_button("Register", type="primary")
76
+
77
+ if register_button:
78
+ if full_name and email and reg_username and reg_password and confirm_password:
79
+ if reg_password == confirm_password:
80
+ if register_user(reg_username, email, reg_password, full_name):
81
+ st.success("Registration successful! Please login.")
82
+ else:
83
+ st.error("Registration failed. Please try again.")
84
+ else:
85
+ st.error("Passwords do not match")
86
+ else:
87
+ st.error("Please fill in all fields")
88
+
89
+ # Info about the platform
90
+ st.markdown("---")
91
+ st.markdown("### About This Platform")
92
+ col1, col2 = st.columns(2)
93
+
94
+ with col1:
95
+ st.markdown("""
96
+ **🌱 What We Collect:**
97
+ - Traditional seed selection methods
98
+ - Soil management techniques
99
+ - Natural fertilizer recipes
100
+ - Pest control methods
101
+ - Water conservation practices
102
+ - Seasonal farming wisdom
103
+ """)
104
+
105
+ with col2:
106
+ st.markdown("""
107
+ **🔧 Features:**
108
+ - Multi-language support
109
+ - Speech-to-text input
110
+ - GPS location tracking
111
+ - Automatic translation
112
+ - Audio/visual documentation
113
+ - Offline-ready design
114
+ """)
115
+
116
+ st.stop()
117
+
118
+ # Main application for authenticated users
119
+ user_info = get_user_info(st.session_state.username)
120
+
121
+ # App header with user info
122
+ col1, col2 = st.columns([3, 1])
123
+ with col1:
124
+ st.title("🌾 Farming Wisdom Archive")
125
+ st.markdown("*Preserving Traditional Indian Farming Knowledge*")
126
+ with col2:
127
+ st.write(f"Welcome, **{user_info.get('full_name', st.session_state.username)}**!")
128
+ st.write(f"Entries submitted: {user_info.get('entries_submitted', 0)}")
129
+ if st.button("Logout"):
130
+ st.session_state.authenticated = False
131
+ st.session_state.username = None
132
+ st.rerun()
133
+
134
+ # Sidebar navigation
135
+ st.sidebar.title("Navigation")
136
+ page = st.sidebar.radio("Go to", [
137
+ "🏠 Home",
138
+ "✍️ Submit Farming Wisdom",
139
+ "📖 Browse Farming Knowledge",
140
+ "🗺️ Farming Wisdom Map",
141
+ "🔍 Search Knowledge",
142
+ "🌐 Translation Hub",
143
+ "📊 Export Data",
144
+ "👤 Profile"
145
+ ])
146
+
147
+ # Home Page
148
+ if page == "🏠 Home":
149
+ st.header("Welcome to Farming Wisdom Archive")
150
+
151
+ col1, col2 = st.columns(2)
152
+
153
+ with col1:
154
+ st.markdown("""
155
+ ### 🌱 About This Platform
156
+ This platform is dedicated to collecting, preserving, and sharing traditional Indian farming wisdom:
157
+ - 🌰 Seed selection and storage techniques
158
+ - 🌱 Soil management and natural fertilizers
159
+ - 🔄 Crop rotation and sustainable practices
160
+ - 🐛 Natural pest control methods
161
+ - 💧 Water conservation techniques
162
+ - 🌾 Harvest and post-harvest processing
163
+ - 🌦️ Weather prediction and seasonal farming
164
+ - 🔧 Traditional farming tools and techniques
165
+ """)
166
+
167
+ with col2:
168
+ st.markdown("### 📊 Archive Statistics")
169
+ total_entries = len(st.session_state.entries)
170
+ languages = len(set(entry.get('language', 'Unknown') for entry in st.session_state.entries))
171
+ categories = len(set(entry.get('category', 'Unknown') for entry in st.session_state.entries))
172
+
173
+ st.metric("Total Farming Entries", total_entries)
174
+ st.metric("Languages", languages)
175
+ st.metric("Farming Categories", categories)
176
+
177
+ st.markdown("---")
178
+ st.markdown("### 🚀 Getting Started")
179
+ st.markdown("1. **Submit Farming Wisdom**: Share your traditional farming knowledge")
180
+ st.markdown("2. **Browse Knowledge**: Explore farming wisdom from across India")
181
+ st.markdown("3. **Use Map**: Discover location-based farming practices")
182
+ st.markdown("4. **Search**: Find specific farming techniques and wisdom")
183
+ st.markdown("5. **Translation**: Translate farming knowledge between languages")
184
+
185
+ # Submit Farming Wisdom Page
186
+ elif page == "✍️ Submit Farming Wisdom":
187
+ st.header("Submit Farming Wisdom")
188
+
189
+ # Initialize session state for form data
190
+ if 'form_data' not in st.session_state:
191
+ st.session_state.form_data = {
192
+ 'title': '',
193
+ 'description': '',
194
+ 'language': get_languages()[0],
195
+ 'category': get_categories()[0],
196
+ 'location_name': '',
197
+ 'manual_lat': 0.0,
198
+ 'manual_lon': 0.0
199
+ }
200
+
201
+ # Location helper tools (outside form)
202
+ st.subheader("Location Helper Tools")
203
+ col_help1, col_help2 = st.columns(2)
204
+
205
+ with col_help1:
206
+ if st.button("📍 Get Current Location"):
207
+ st.info("Click on the map below to select location, or use the geocoding tool")
208
+
209
+ with col_help2:
210
+ geocode_location_input = st.text_input("Enter location to geocode",
211
+ placeholder="e.g., Mumbai, Maharashtra")
212
+ if st.button("🌍 Geocode Location") and geocode_location_input:
213
+ coords = geocode_location(geocode_location_input)
214
+ if coords:
215
+ st.session_state.form_data['manual_lat'] = coords[0]
216
+ st.session_state.form_data['manual_lon'] = coords[1]
217
+ st.success(f"Found coordinates: {coords[0]:.6f}, {coords[1]:.6f}")
218
+ else:
219
+ st.error("Could not find coordinates for the location")
220
+
221
+ # Map for location selection (outside form)
222
+ if st.session_state.form_data['manual_lat'] != 0.0 or st.session_state.form_data['manual_lon'] != 0.0:
223
+ st.subheader("Location Map")
224
+ m = folium.Map(location=[st.session_state.form_data['manual_lat'],
225
+ st.session_state.form_data['manual_lon']], zoom_start=10)
226
+ folium.Marker([st.session_state.form_data['manual_lat'],
227
+ st.session_state.form_data['manual_lon']]).add_to(m)
228
+ map_data = st_folium(m, width=700, height=300)
229
+
230
+ if map_data['last_clicked']:
231
+ st.session_state.form_data['manual_lat'] = map_data['last_clicked']['lat']
232
+ st.session_state.form_data['manual_lon'] = map_data['last_clicked']['lng']
233
+ st.success(f"Selected coordinates: {st.session_state.form_data['manual_lat']:.6f}, {st.session_state.form_data['manual_lon']:.6f}")
234
+
235
+ # Speech-to-text tool (outside form)
236
+ st.subheader("Speech Input Helper")
237
+ speech_language = st.selectbox("Language for Speech Recognition", get_languages(), key="speech_lang")
238
+ if st.button("🎤 Record Description"):
239
+ with st.spinner("Listening... Speak now!"):
240
+ recorded_text = speech_to_text(speech_language)
241
+ if recorded_text:
242
+ st.session_state.form_data['description'] = recorded_text
243
+ st.success(f"Recorded: {recorded_text}")
244
+ else:
245
+ st.error("Could not record speech. Please try again.")
246
+
247
+ # Main form
248
+ st.subheader("Entry Details")
249
+ with st.form("entry_form", clear_on_submit=True):
250
+ col1, col2 = st.columns(2)
251
+
252
+ with col1:
253
+ title = st.text_input("Title*",
254
+ value=st.session_state.form_data['title'],
255
+ placeholder="Enter the title of your wisdom")
256
+ language = st.selectbox("Language*", get_languages(),
257
+ index=get_languages().index(st.session_state.form_data['language']))
258
+ category = st.selectbox("Category*", get_categories(),
259
+ index=get_categories().index(st.session_state.form_data['category']))
260
+ location_name = st.text_input("Location",
261
+ value=st.session_state.form_data['location_name'],
262
+ placeholder="e.g., Mumbai, Maharashtra")
263
+
264
+ with col2:
265
+ description = st.text_area("Description*",
266
+ value=st.session_state.form_data['description'],
267
+ height=100,
268
+ placeholder="Describe the wisdom, practice, or story...")
269
+
270
+ # Media upload
271
+ st.subheader("Media (Optional)")
272
+ uploaded_image = st.file_uploader("Upload Image", type=['jpg', 'jpeg', 'png'])
273
+ uploaded_audio = st.file_uploader("Upload Audio", type=['mp3', 'wav', 'ogg'])
274
+
275
+ # Location coordinates (read-only display)
276
+ st.subheader("Location Coordinates")
277
+ col3, col4 = st.columns(2)
278
+
279
+ with col3:
280
+ manual_lat = st.number_input("Latitude",
281
+ value=st.session_state.form_data['manual_lat'],
282
+ format="%.6f",
283
+ help="Use tools above to set coordinates")
284
+ manual_lon = st.number_input("Longitude",
285
+ value=st.session_state.form_data['manual_lon'],
286
+ format="%.6f",
287
+ help="Use tools above to set coordinates")
288
+
289
+ with col4:
290
+ st.info("💡 Use the location helper tools above to set coordinates")
291
+
292
+ # Form submission
293
+ submitted = st.form_submit_button("Submit Entry", type="primary")
294
+
295
+ if submitted:
296
+ if title and description and language and category:
297
+ # Save media files
298
+ image_path = None
299
+ audio_path = None
300
+
301
+ if uploaded_image:
302
+ image_path = f"data_entries/media/{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}_{uploaded_image.name}"
303
+ os.makedirs("data_entries/media", exist_ok=True)
304
+ with open(image_path, "wb") as f:
305
+ f.write(uploaded_image.getbuffer())
306
+
307
+ if uploaded_audio:
308
+ audio_path = f"data_entries/media/{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}_{uploaded_audio.name}"
309
+ os.makedirs("data_entries/media", exist_ok=True)
310
+ with open(audio_path, "wb") as f:
311
+ f.write(uploaded_audio.getbuffer())
312
+
313
+ # Create entry
314
+ entry = {
315
+ 'id': len(st.session_state.entries) + 1,
316
+ 'title': title,
317
+ 'description': description,
318
+ 'language': language,
319
+ 'category': category,
320
+ 'location_name': location_name,
321
+ 'latitude': manual_lat if manual_lat != 0.0 else None,
322
+ 'longitude': manual_lon if manual_lon != 0.0 else None,
323
+ 'image_path': image_path,
324
+ 'audio_path': audio_path,
325
+ 'timestamp': datetime.datetime.now().isoformat(),
326
+ 'contributor': st.session_state.username,
327
+ 'contributor_full_name': user_info.get('full_name', st.session_state.username)
328
+ }
329
+
330
+ if save_entry(entry):
331
+ st.session_state.entries.append(entry)
332
+ update_user_entry_count(st.session_state.username)
333
+ st.success("Farming wisdom submitted successfully!")
334
+ # Reset form data
335
+ st.session_state.form_data = {
336
+ 'title': '',
337
+ 'description': '',
338
+ 'language': get_languages()[0],
339
+ 'category': get_categories()[0],
340
+ 'location_name': '',
341
+ 'manual_lat': 0.0,
342
+ 'manual_lon': 0.0
343
+ }
344
+ st.rerun()
345
+ else:
346
+ st.error("Failed to save entry. Please try again.")
347
+ else:
348
+ st.error("Please fill in all required fields marked with *")
349
+
350
+ # Browse Farming Knowledge Page
351
+ elif page == "📖 Browse Farming Knowledge":
352
+ st.header("Browse Farming Knowledge")
353
+
354
+ # Filters
355
+ col1, col2, col3 = st.columns(3)
356
+
357
+ with col1:
358
+ filter_language = st.selectbox("Filter by Language", ["All"] + get_languages())
359
+ with col2:
360
+ filter_category = st.selectbox("Filter by Category", ["All"] + get_categories())
361
+ with col3:
362
+ sort_by = st.selectbox("Sort by", ["Newest First", "Oldest First", "Title A-Z"])
363
+
364
+ # Filter entries
365
+ filtered_entries = st.session_state.entries.copy()
366
+
367
+ if filter_language != "All":
368
+ filtered_entries = [e for e in filtered_entries if e.get('language') == filter_language]
369
+
370
+ if filter_category != "All":
371
+ filtered_entries = [e for e in filtered_entries if e.get('category') == filter_category]
372
+
373
+ # Sort entries
374
+ if sort_by == "Newest First":
375
+ filtered_entries.sort(key=lambda x: x.get('timestamp', ''), reverse=True)
376
+ elif sort_by == "Oldest First":
377
+ filtered_entries.sort(key=lambda x: x.get('timestamp', ''))
378
+ elif sort_by == "Title A-Z":
379
+ filtered_entries.sort(key=lambda x: x.get('title', '').lower())
380
+
381
+ st.write(f"Showing {len(filtered_entries)} entries")
382
+
383
+ # Display entries
384
+ for entry in filtered_entries:
385
+ with st.expander(f"📖 {entry.get('title', 'Untitled')} ({entry.get('language', 'Unknown')})"):
386
+ col1, col2 = st.columns([2, 1])
387
+
388
+ with col1:
389
+ st.markdown(f"**Category:** {entry.get('category', 'Unknown')}")
390
+ st.markdown(f"**Location:** {entry.get('location_name', 'Not specified')}")
391
+ st.markdown(f"**Description:**")
392
+ st.write(entry.get('description', 'No description'))
393
+
394
+ # TTS button
395
+ if st.button(f"🔊 Listen", key=f"tts_{entry.get('id')}"):
396
+ text_to_speech(entry.get('description', ''), entry.get('language', 'en'))
397
+
398
+ with col2:
399
+ # Display image if available
400
+ if entry.get('image_path') and os.path.exists(entry['image_path']):
401
+ try:
402
+ image = Image.open(entry['image_path'])
403
+ st.image(image, caption="Attached Image", use_column_width=True)
404
+ except Exception as e:
405
+ st.error(f"Error loading image: {str(e)}")
406
+
407
+ # Display audio if available
408
+ if entry.get('audio_path') and os.path.exists(entry['audio_path']):
409
+ try:
410
+ st.audio(entry['audio_path'])
411
+ except Exception as e:
412
+ st.error(f"Error loading audio: {str(e)}")
413
+
414
+ # Metadata
415
+ st.markdown(f"**Submitted:** {entry.get('timestamp', 'Unknown')[:10]}")
416
+ if entry.get('latitude') and entry.get('longitude'):
417
+ st.markdown(f"**Coordinates:** {entry['latitude']:.4f}, {entry['longitude']:.4f}")
418
+
419
+ # Farming Wisdom Map Page
420
+ elif page == "🗺️ Farming Wisdom Map":
421
+ st.header("Farming Wisdom Map")
422
+ st.markdown("Explore traditional farming knowledge geographically")
423
+
424
+ # Get entries with coordinates
425
+ geo_entries = [e for e in st.session_state.entries if e.get('latitude') and e.get('longitude')]
426
+
427
+ if geo_entries:
428
+ # Create map centered on India
429
+ m = folium.Map(location=[20.5937, 78.9629], zoom_start=5)
430
+
431
+ # Add markers for each entry
432
+ for entry in geo_entries:
433
+ folium.Marker(
434
+ [entry['latitude'], entry['longitude']],
435
+ popup=f"<b>{entry.get('title', 'Untitled')}</b><br>"
436
+ f"Category: {entry.get('category', 'Unknown')}<br>"
437
+ f"Language: {entry.get('language', 'Unknown')}<br>"
438
+ f"Location: {entry.get('location_name', 'Unknown')}",
439
+ tooltip=entry.get('title', 'Untitled')
440
+ ).add_to(m)
441
+
442
+ # Display map
443
+ st_folium(m, width=1200, height=600)
444
+
445
+ st.write(f"Showing {len(geo_entries)} entries with location data")
446
+ else:
447
+ st.info("No entries with location data found. Submit entries with coordinates to see them on the map!")
448
+
449
+ # Search Knowledge Page
450
+ elif page == "🔍 Search Knowledge":
451
+ st.header("Search Farming Knowledge")
452
+
453
+ # Search input
454
+ search_query = st.text_input("Search for farming practices, techniques, or knowledge...")
455
+
456
+ # Advanced filters
457
+ with st.expander("Advanced Filters"):
458
+ col1, col2 = st.columns(2)
459
+ with col1:
460
+ search_language = st.selectbox("Language", ["All"] + get_languages(), key="search_lang")
461
+ search_category = st.selectbox("Category", ["All"] + get_categories(), key="search_cat")
462
+ with col2:
463
+ has_media = st.checkbox("Has Media")
464
+ has_location = st.checkbox("Has Location Data")
465
+
466
+ if search_query:
467
+ results = search_entries(
468
+ st.session_state.entries,
469
+ search_query,
470
+ language=search_language if search_language != "All" else None,
471
+ category=search_category if search_category != "All" else None,
472
+ has_media=has_media,
473
+ has_location=has_location
474
+ )
475
+
476
+ st.write(f"Found {len(results)} results")
477
+
478
+ for entry in results:
479
+ with st.expander(f"📖 {entry.get('title', 'Untitled')}"):
480
+ st.markdown(f"**Category:** {entry.get('category', 'Unknown')}")
481
+ st.markdown(f"**Language:** {entry.get('language', 'Unknown')}")
482
+ st.markdown(f"**Location:** {entry.get('location_name', 'Not specified')}")
483
+ st.write(entry.get('description', 'No description'))
484
+
485
+ if st.button(f"🔊 Listen", key=f"search_tts_{entry.get('id')}"):
486
+ text_to_speech(entry.get('description', ''), entry.get('language', 'en'))
487
+
488
+ # Translation Hub Page
489
+ elif page == "🌐 Translation Hub":
490
+ st.header("Translation Hub")
491
+ st.markdown("Translate farming knowledge between different Indian languages")
492
+
493
+ # Translation interface
494
+ col1, col2 = st.columns(2)
495
+
496
+ with col1:
497
+ st.subheader("Original Text")
498
+ source_language = st.selectbox("Source Language", ["Auto-detect"] + get_languages())
499
+ source_text = st.text_area("Text to translate", height=200,
500
+ placeholder="Enter farming knowledge in any Indian language...")
501
+
502
+ if st.button("🔍 Detect Language") and source_text:
503
+ detected_lang = detect_language(source_text)
504
+ st.success(f"Detected language: {detected_lang}")
505
+
506
+ with col2:
507
+ st.subheader("Translation")
508
+ target_language = st.selectbox("Target Language", get_languages())
509
+
510
+ if st.button("🌐 Translate", type="primary") and source_text and target_language:
511
+ source_lang = source_language if source_language != "Auto-detect" else "auto"
512
+ with st.spinner("Translating..."):
513
+ translated_text = translate_text(source_text, target_language, source_lang)
514
+ st.text_area("Translated Text", value=translated_text, height=200)
515
+
516
+ # Option to save as entry
517
+ if st.button("💾 Save as Entry"):
518
+ st.session_state.form_data = {
519
+ 'title': f"Translated: {source_text[:50]}...",
520
+ 'description': translated_text,
521
+ 'language': target_language,
522
+ 'category': get_categories()[0],
523
+ 'location_name': '',
524
+ 'manual_lat': 0.0,
525
+ 'manual_lon': 0.0
526
+ }
527
+ st.success("Content saved to form data! Go to Submit page to complete the entry.")
528
+
529
+ # Show popular translations
530
+ st.markdown("---")
531
+ st.subheader("Popular Farming Terms Translation")
532
+
533
+ farming_terms = {
534
+ "Organic Fertilizer": "जैविक उर्वरक",
535
+ "Crop Rotation": "फसल चक्र",
536
+ "Irrigation": "सिंचाई",
537
+ "Pest Control": "कीट नियंत्रण",
538
+ "Soil Health": "मिट्टी की स्वास्थ्य",
539
+ "Harvest": "फसल कटाई",
540
+ "Seeds": "बीज",
541
+ "Monsoon": "मानसून"
542
+ }
543
+
544
+ cols = st.columns(4)
545
+ for i, (eng, hindi) in enumerate(farming_terms.items()):
546
+ with cols[i % 4]:
547
+ st.info(f"**{eng}**\n{hindi}")
548
+
549
+ # Export Data Page
550
+ elif page == "📊 Export Data":
551
+ st.header("Export Data")
552
+ st.markdown("Export collected farming wisdom for research and analysis")
553
+
554
+ col1, col2 = st.columns(2)
555
+
556
+ with col1:
557
+ st.subheader("Export Options")
558
+ export_format = st.selectbox("Format", ["JSONL", "CSV"])
559
+ include_media_paths = st.checkbox("Include Media File Paths", value=True)
560
+ include_coordinates = st.checkbox("Include Geo-coordinates", value=True)
561
+
562
+ # Filter options
563
+ export_language = st.selectbox("Language Filter", ["All"] + get_languages(), key="export_lang")
564
+ export_category = st.selectbox("Category Filter", ["All"] + get_categories(), key="export_cat")
565
+
566
+ with col2:
567
+ st.subheader("Export Statistics")
568
+ total_entries = len(st.session_state.entries)
569
+ entries_with_media = len([e for e in st.session_state.entries if e.get('image_path') or e.get('audio_path')])
570
+ entries_with_coords = len([e for e in st.session_state.entries if e.get('latitude') and e.get('longitude')])
571
+
572
+ st.metric("Total Entries", total_entries)
573
+ st.metric("Entries with Media", entries_with_media)
574
+ st.metric("Entries with Coordinates", entries_with_coords)
575
+
576
+ # Export button
577
+ if st.button("Generate Export", type="primary"):
578
+ if st.session_state.entries:
579
+ # Filter entries based on selection
580
+ filtered_entries = st.session_state.entries.copy()
581
+
582
+ if export_language != "All":
583
+ filtered_entries = [e for e in filtered_entries if e.get('language') == export_language]
584
+
585
+ if export_category != "All":
586
+ filtered_entries = [e for e in filtered_entries if e.get('category') == export_category]
587
+
588
+ if export_format == "JSONL":
589
+ export_data = export_to_jsonl(filtered_entries, include_media_paths, include_coordinates)
590
+ st.download_button(
591
+ label="Download JSONL",
592
+ data=export_data,
593
+ file_name=f"ancestral_archive_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.jsonl",
594
+ mime="application/json"
595
+ )
596
+ else:
597
+ export_data = export_to_csv(filtered_entries, include_media_paths, include_coordinates)
598
+ st.download_button(
599
+ label="Download CSV",
600
+ data=export_data,
601
+ file_name=f"ancestral_archive_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.csv",
602
+ mime="text/csv"
603
+ )
604
+
605
+ st.success(f"Export ready! {len(filtered_entries)} entries included.")
606
+ else:
607
+ st.warning("No entries to export. Please submit some entries first.")
608
+
609
+ # Profile Page
610
+ elif page == "👤 Profile":
611
+ st.header("User Profile")
612
+
613
+ col1, col2 = st.columns(2)
614
+
615
+ with col1:
616
+ st.subheader("Profile Information")
617
+ st.write(f"**Full Name:** {user_info.get('full_name', 'Not provided')}")
618
+ st.write(f"**Username:** {st.session_state.username}")
619
+ st.write(f"**Email:** {user_info.get('email', 'Not provided')}")
620
+ st.write(f"**Member since:** {user_info.get('registration_date', 'Unknown')[:10]}")
621
+ st.write(f"**Entries submitted:** {user_info.get('entries_submitted', 0)}")
622
+
623
+ with col2:
624
+ st.subheader("My Contributions")
625
+ my_entries = [e for e in st.session_state.entries if e.get('contributor') == st.session_state.username]
626
+
627
+ if my_entries:
628
+ st.write(f"You have contributed {len(my_entries)} farming knowledge entries:")
629
+ for entry in my_entries[-5:]: # Show last 5 entries
630
+ st.write(f"• {entry.get('title', 'Untitled')} ({entry.get('category', 'Unknown')})")
631
+
632
+ if len(my_entries) > 5:
633
+ st.write(f"... and {len(my_entries) - 5} more entries")
634
+ else:
635
+ st.info("You haven't submitted any entries yet. Share your farming wisdom!")
636
+
637
+ st.markdown("---")
638
+ st.subheader("Account Settings")
639
+
640
+ # Language preference
641
+ preferred_language = st.selectbox("Preferred Language", get_languages(),
642
+ index=0)
643
+
644
+ # Notification settings
645
+ st.subheader("Preferences")
646
+ email_notifications = st.checkbox("Email notifications for new entries in my area")
647
+ tts_enabled = st.checkbox("Enable text-to-speech by default", value=True)
648
+
649
+ if st.button("Update Profile", type="primary"):
650
+ st.success("Profile updated successfully!")
651
+
652
+ # Settings Page
653
+ elif page == "🔧 Settings":
654
+ st.header("Settings")
655
+
656
+ st.subheader("Data Management")
657
+ col1, col2 = st.columns(2)
658
+
659
+ with col1:
660
+ if st.button("Refresh Data", type="secondary"):
661
+ st.session_state.entries = load_entries()
662
+ st.success("Data refreshed!")
663
+ st.rerun()
664
+
665
+ with col2:
666
+ if st.button("Clear All Data", type="secondary"):
667
+ if st.checkbox("I understand this will delete all entries"):
668
+ if st.button("Confirm Delete", type="primary"):
669
+ try:
670
+ # Clear the entries file
671
+ with open("data_entries/entries.json", "w") as f:
672
+ json.dump([], f)
673
+ st.session_state.entries = []
674
+ st.success("All data cleared!")
675
+ st.rerun()
676
+ except Exception as e:
677
+ st.error(f"Error clearing data: {str(e)}")
678
+
679
+ st.subheader("About")
680
+ st.markdown("""
681
+ **Farming Wisdom Archive** - Version 1.0
682
+
683
+ A multilingual platform for collecting, preserving, and sharing traditional Indian farming knowledge.
684
+
685
+ - **Offline-first design** for low-bandwidth regions
686
+ - **Multilingual support** for Indian languages
687
+ - **Accessibility features** with TTS/STT
688
+ - **Geographic mapping** of farming wisdom
689
+ - **Translation hub** for cross-language knowledge sharing
690
+ - **Open-source corpus** for agricultural research
691
+ """)
692
+
693
+ # Footer
694
+ st.markdown("---")
695
+ st.markdown("🌾 **Farming Wisdom Archive** - Preserving traditional agricultural knowledge for future generations")