Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import random | |
| import json | |
| from pathlib import Path | |
| import requests | |
| from bs4 import BeautifulSoup | |
| import time | |
| from fake_useragent import UserAgent | |
| import hashlib | |
| from datetime import datetime | |
| import pytz | |
| class SimpleAuth: | |
| def __init__(self): | |
| self.users_file = Path('users.json') | |
| self.init_users_db() | |
| def init_users_db(self): | |
| if not self.users_file.exists(): | |
| with open(self.users_file, 'w') as f: | |
| json.dump({'users': {}}, f) | |
| def get_users(self): | |
| with open(self.users_file, 'r') as f: | |
| return json.load(f) | |
| def save_users(self, users_data): | |
| with open(self.users_file, 'w') as f: | |
| json.dump(users_data, f) | |
| def hash_password(self, password): | |
| return hashlib.sha256(password.encode()).hexdigest() | |
| def signup(self, email, password): | |
| users_data = self.get_users() | |
| if email in users_data['users']: | |
| return False, "Email already exists" | |
| users_data['users'][email] = { | |
| 'password': self.hash_password(password), | |
| 'favorites': [] | |
| } | |
| self.save_users(users_data) | |
| return True, "Signup successful" | |
| def login(self, email, password): | |
| users_data = self.get_users() | |
| if email not in users_data['users']: | |
| return False, "Email not found" | |
| if users_data['users'][email]['password'] != self.hash_password(password): | |
| return False, "Invalid password" | |
| return True, "Login successful" | |
| class QuoteScraper: | |
| def __init__(self): | |
| self.ua = UserAgent() | |
| self.headers = {'User-Agent': self.ua.random} | |
| def scrape_goodreads(self, category): | |
| quotes = [] | |
| try: | |
| url = f"https://www.goodreads.com/quotes/tag/{category}" | |
| response = requests.get(url, headers=self.headers) | |
| soup = BeautifulSoup(response.text, 'html.parser') | |
| quote_divs = soup.find_all('div', class_='quoteText') | |
| for div in quote_divs: | |
| quote = div.get_text().split('―')[0].strip().strip('"').strip('"') | |
| quotes.append(quote) | |
| time.sleep(2) # Respectful delay between requests | |
| except Exception as e: | |
| print(f"Error scraping Goodreads: {e}") | |
| return quotes | |
| def scrape_brainyquote(self, category): | |
| quotes = [] | |
| try: | |
| url = f"https://www.brainyquote.com/topics/{category}" | |
| response = requests.get(url, headers=self.headers) | |
| soup = BeautifulSoup(response.text, 'html.parser') | |
| quote_divs = soup.find_all('div', class_='grid-item') | |
| for div in quote_divs: | |
| quote_text = div.find('a', class_='b-qt') | |
| if quote_text: | |
| quotes.append(quote_text.get_text().strip()) | |
| time.sleep(2) | |
| except Exception as e: | |
| print(f"Error scraping BrainyQuote: {e}") | |
| return quotes | |
| class QuoteManager: | |
| def __init__(self): | |
| self.scraper = QuoteScraper() | |
| self.quotes_file = Path('enhanced_quotes.json') | |
| self.favorites_file = Path('favorites.json') | |
| self.categories = [ | |
| 'motivation', 'wisdom', 'spiritual', 'philosophy', 'success', | |
| 'love', 'life', 'happiness', 'science', 'education', 'leadership', | |
| 'buddhist', 'christian', 'islamic', 'hindu', 'jewish', | |
| 'native-american', 'african', 'asian', 'european' | |
| ] | |
| self.init_favorites_db() | |
| def init_favorites_db(self): | |
| if not self.favorites_file.exists(): | |
| with open(self.favorites_file, 'w') as f: | |
| json.dump({}, f) | |
| def update_quotes_database(self): | |
| quotes_data = {} | |
| for category in self.categories: | |
| quotes = [] | |
| # Scrape from multiple sources | |
| quotes.extend(self.scraper.scrape_goodreads(category)) | |
| quotes.extend(self.scraper.scrape_brainyquote(category)) | |
| quotes_data[category] = list(set(quotes)) # Remove duplicates | |
| with open(self.quotes_file, 'w', encoding='utf-8') as f: | |
| json.dump(quotes_data, f, ensure_ascii=False, indent=4) | |
| return quotes_data | |
| def load_quotes(self): | |
| if not self.quotes_file.exists(): | |
| return self.update_quotes_database() | |
| with open(self.quotes_file, 'r', encoding='utf-8') as f: | |
| return json.load(f) | |
| def add_to_favorites(self, email, quote, category): | |
| with open(self.favorites_file, 'r') as f: | |
| favorites = json.load(f) | |
| if email not in favorites: | |
| favorites[email] = [] | |
| favorites[email].append({ | |
| 'quote': quote, | |
| 'category': category, | |
| 'timestamp': datetime.now(pytz.UTC).isoformat() | |
| }) | |
| with open(self.favorites_file, 'w') as f: | |
| json.dump(favorites, f) | |
| def get_favorites(self, email): | |
| with open(self.favorites_file, 'r') as f: | |
| favorites = json.load(f) | |
| return favorites.get(email, []) | |
| def remove_favorite(self, email, quote): | |
| with open(self.favorites_file, 'r') as f: | |
| favorites = json.load(f) | |
| if email in favorites: | |
| favorites[email] = [f for f in favorites[email] if f['quote'] != quote] | |
| with open(self.favorites_file, 'w') as f: | |
| json.dump(favorites, f) | |
| def main(): | |
| st.set_page_config( | |
| page_title="Global QuoteVerse - Wisdom From All Cultures", | |
| page_icon="🌎", | |
| layout="wide" | |
| ) | |
| # Initialize managers | |
| auth_manager = SimpleAuth() | |
| quote_manager = QuoteManager() | |
| # Initialize session state | |
| if 'user' not in st.session_state: | |
| st.session_state.user = None | |
| # Custom CSS (same as before) | |
| st.markdown(""" | |
| <style> | |
| .main { padding: 2rem; } | |
| .stButton button { | |
| width: 100%; | |
| border-radius: 20px; | |
| background-color: #4CAF50; | |
| color: white; | |
| } | |
| .quote-box { | |
| padding: 20px; | |
| border-radius: 10px; | |
| background-color: #f0f2f6; | |
| margin: 10px 0; | |
| box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
| } | |
| .search-box { | |
| padding: 10px; | |
| border-radius: 5px; | |
| border: 1px solid #ddd; | |
| width: 100%; | |
| } | |
| .category-tag { | |
| display: inline-block; | |
| padding: 5px 10px; | |
| border-radius: 15px; | |
| background-color: #e0e0e0; | |
| margin: 2px; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # Sidebar with authentication | |
| with st.sidebar: | |
| st.title("🌎 Global QuoteVerse") | |
| if not st.session_state.user: | |
| auth_option = st.radio("Choose Option", ["Login", "Sign Up"]) | |
| if auth_option == "Login": | |
| email = st.text_input("Email") | |
| password = st.text_input("Password", type="password") | |
| if st.button("Login"): | |
| success, message = auth_manager.login(email, password) | |
| if success: | |
| st.session_state.user = email | |
| st.success(message) | |
| st.rerun() | |
| else: | |
| st.error(message) | |
| else: | |
| email = st.text_input("Email") | |
| password = st.text_input("Password", type="password") | |
| if st.button("Sign Up"): | |
| success, message = auth_manager.signup(email, password) | |
| if success: | |
| st.success(message) | |
| else: | |
| st.error(message) | |
| else: | |
| st.write(f"Welcome, {st.session_state.user}") | |
| if st.button("Logout"): | |
| st.session_state.user = None | |
| st.rerun() | |
| menu = st.selectbox( | |
| "Navigation", | |
| ["Home", "Quote Generator", "Browse Categories", "Search Quotes", "My Favorites"] | |
| ) | |
| # Load quotes | |
| quotes_data = quote_manager.load_quotes() | |
| if menu == "Home": | |
| st.title("Welcome to Global QuoteVerse") | |
| st.markdown("### Discover Wisdom From All Cultures") | |
| # Featured categories | |
| st.markdown("### Featured Categories") | |
| cols = st.columns(4) | |
| featured_categories = ['motivation', 'spiritual', 'wisdom', 'philosophy'] | |
| for idx, category in enumerate(featured_categories): | |
| with cols[idx]: | |
| if st.button(category.title()): | |
| quote = random.choice(quotes_data[category]) | |
| st.markdown(f""" | |
| <div class='quote-box'> | |
| <p>{quote}</p> | |
| <div class='category-tag'>{category}</div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| elif menu == "Quote Generator": | |
| st.title("Generate Custom Quotes") | |
| category = st.selectbox("Select Category", quote_manager.categories) | |
| if st.button("Generate Quote"): | |
| quote = random.choice(quotes_data[category]) | |
| st.markdown(f""" | |
| <div class='quote-box'> | |
| <p>{quote}</p> | |
| <div class='category-tag'>{category}</div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| if st.session_state.user: | |
| if st.button("Add to Favorites"): | |
| quote_manager.add_to_favorites(st.session_state.user, quote, category) | |
| st.success("Added to favorites!") | |
| elif menu == "Search Quotes": | |
| st.title("Search Quotes") | |
| search_query = st.text_input("Enter search terms") | |
| selected_categories = st.multiselect("Filter by Categories", quote_manager.categories) | |
| if search_query: | |
| results = [] | |
| categories_to_search = selected_categories if selected_categories else quote_manager.categories | |
| for category in categories_to_search: | |
| for quote in quotes_data[category]: | |
| if search_query.lower() in quote.lower(): | |
| results.append((quote, category)) | |
| st.write(f"Found {len(results)} matches") | |
| for quote, category in results: | |
| st.markdown(f""" | |
| <div class='quote-box'> | |
| <p>{quote}</p> | |
| <div class='category-tag'>{category}</div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| elif menu == "My Favorites": | |
| if not st.session_state.user: | |
| st.warning("Please login to view your favorites") | |
| else: | |
| st.title("My Favorite Quotes") | |
| favorites = quote_manager.get_favorites(st.session_state.user) | |
| for idx, fav in enumerate(favorites): | |
| st.markdown(f""" | |
| <div class='quote-box'> | |
| <p>{fav['quote']}</p> | |
| <div class='category-tag'>{fav['category']}</div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| if st.button(f"Share", key=f"share_{idx}"): | |
| # Generate shareable text using regular quotes | |
| share_text = f'"{fav["quote"]}" - via Global QuoteVerse' | |
| st.code(share_text) | |
| with col2: | |
| if st.button(f"Remove", key=f"remove_{idx}"): | |
| quote_manager.remove_favorite(st.session_state.user, fav['quote']) | |
| st.success("Removed from favorites!") | |
| st.rerun() | |
| if __name__ == "__main__": | |
| main() |