import os import streamlit as st from dotenv import load_dotenv from pymongo import MongoClient import pandas as pd from bson import ObjectId import cloudinary import cloudinary.uploader # Load environment variables from .env file load_dotenv() # Get MongoDB URI from .env file mongodb_uri = os.getenv('MONGODB_URI') # Configure Cloudinary cloudinary.config( cloud_name = os.getenv('CLOUDINARY_CLOUD_NAME'), api_key = os.getenv('CLOUDINARY_API_KEY'), api_secret = os.getenv('CLOUDINARY_API_SECRET') ) # Connect to MongoDB @st.cache_resource def init_connection(): return MongoClient(mongodb_uri) client = init_connection() # Access the 'mitra' database db = client['mitra'] # Access the 'base-voices' collection collection = db['base-voices'] # Streamlit app st.title('Base Voices Data Management') # Sidebar for actions st.sidebar.header('Actions') action = st.sidebar.radio('Choose an action:', ['View Data', 'Add Category', 'Remove Category', 'Add Voice', 'Remove Voice']) if action == 'View Data': # Retrieve all documents from the collection @st.cache_data def get_base_voices(): base_voices = list(collection.find({}, {'_id': 0})) # Exclude the '_id' field return base_voices data = get_base_voices() # Display the data if data: # Normalize the data for better display normalized_data = [] for category in data: for voice in category['voices']: normalized_data.append({ 'Category': category['category'], 'Voice Name': voice['name'], 'Is Free': 'Yes' if voice['is_free'] else 'No', 'File URL': voice['file_url'] }) df = pd.DataFrame(normalized_data) # Display the table st.subheader("Voice Data Table") st.dataframe(df, use_container_width=True) # Display audio players for each voice st.subheader("Audio Samples") for category in data: st.write(f"**{category['category']}**") for voice in category['voices']: col1, col2 = st.columns([3, 1]) with col1: st.write(f"{voice['name']} ({'Free' if voice['is_free'] else 'Paid'})") st.audio(voice['file_url']) with col2: st.markdown(f"[Download]({voice['file_url']})") st.write("---") # Optional: Add a download button csv = df.to_csv(index=False) st.download_button( label="Download data as CSV", data=csv, file_name="base_voices.csv", mime="text/csv", ) else: st.write("No data found in the 'base-voices' collection.") elif action == 'Add Category': st.header('Add New Category') new_category = st.text_input('Enter new category name:') if st.button('Add Category'): if new_category: new_doc = {'category': new_category, 'voices': []} result = collection.insert_one(new_doc) st.success(f'Category "{new_category}" added successfully!') else: st.error('Please enter a category name.') elif action == 'Remove Category': st.header('Remove Category') categories = [doc['category'] for doc in collection.find({}, {'category': 1})] category_to_remove = st.selectbox('Select category to remove:', categories) if st.button('Remove Category'): result = collection.delete_one({'category': category_to_remove}) if result.deleted_count > 0: st.success(f'Category "{category_to_remove}" removed successfully!') else: st.error('Failed to remove category. Please try again.') elif action == 'Add Voice': st.header('Add Voice to Category') categories = [doc['category'] for doc in collection.find({}, {'category': 1})] selected_category = st.selectbox('Select category:', categories) voice_name = st.text_input('Enter voice name:') voice_file = st.file_uploader("Upload voice file", type=['mp3', 'wav']) is_free = st.checkbox('Is this voice free?') if st.button('Add Voice'): if voice_name and voice_file: # Upload file to Cloudinary upload_result = cloudinary.uploader.upload(voice_file, resource_type="auto") voice_url = upload_result['secure_url'] new_voice = { 'name': voice_name, 'file_url': voice_url, 'is_free': is_free } result = collection.update_one( {'category': selected_category}, {'$push': {'voices': new_voice}} ) if result.modified_count > 0: st.success(f'Voice "{voice_name}" added to category "{selected_category}" successfully!') else: st.error('Failed to add voice. Please try again.') else: st.error('Please enter a voice name and upload a file.') elif action == 'Remove Voice': st.header('Remove Voice from Category') categories = [doc['category'] for doc in collection.find({}, {'category': 1})] selected_category = st.selectbox('Select category:', categories) category_doc = collection.find_one({'category': selected_category}) if category_doc and 'voices' in category_doc: voice_names = [voice['name'] for voice in category_doc['voices']] voice_to_remove = st.selectbox('Select voice to remove:', voice_names) if st.button('Remove Voice'): result = collection.update_one( {'category': selected_category}, {'$pull': {'voices': {'name': voice_to_remove}}} ) if result.modified_count > 0: st.success(f'Voice "{voice_to_remove}" removed from category "{selected_category}" successfully!') else: st.error('Failed to remove voice. Please try again.') else: st.warning(f'No voices found in category "{selected_category}".') # Refresh data after actions if st.button('Refresh Data'): st.rerun()