Subayyal commited on
Commit
e05fb58
·
verified ·
1 Parent(s): 62ee211

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.py +159 -0
  2. requirements.txt +4 -0
  3. style.css +28 -53
app.py ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+ import json
4
+ import random
5
+ import os
6
+ from bs4 import BeautifulSoup
7
+ from urllib.parse import quote
8
+
9
+ # Set page config for wide layout and title
10
+ st.set_page_config(page_title="MoodVerse", layout="wide")
11
+
12
+ # Load custom CSS
13
+ def load_css():
14
+ with open("style.css") as f:
15
+ st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)
16
+
17
+ load_css()
18
+
19
+ # Load mood-to-verse mapping from JSON
20
+ @st.cache_data
21
+ def load_mood_verses():
22
+ with open("mood_verses.json", "r", encoding="utf-8") as f:
23
+ return json.load(f)
24
+
25
+ # Fetch verse data from APIs
26
+ @st.cache_data(ttl=3600) # Cache for 1 hour
27
+ def fetch_verse_data(reference):
28
+ try:
29
+ surah, ayat = reference.split(":")
30
+ # Fetch from Al-Quran API for Arabic, English, Urdu translations, and audio
31
+ url = f"http://api.alquran.cloud/v1/ayah/{quote(reference)}"
32
+ response = requests.get(url, timeout=5)
33
+ response.raise_for_status()
34
+ data = response.json()["data"]
35
+
36
+ english_url = f"http://api.alquran.cloud/v1/ayah/{quote(reference)}/en.sahih"
37
+ urdu_url = f"http://api.alquran.cloud/v1/ayah/{quote(reference)}/ur.jalandhry"
38
+ english_data = requests.get(english_url, timeout=5).json()["data"]
39
+ urdu_data = requests.get(urdu_url, timeout=5).json()["data"]
40
+
41
+ audio_url = f"http://api.alquran.cloud/v1/ayah/{quote(reference)}/ar.alafasy"
42
+ audio_data = requests.get(audio_url, timeout=5).json()["data"]
43
+
44
+ # Fetch English Tafseer from quran-api (Maududi)
45
+ eng_tafseer_url = f"https://cdn.jsdelivr.net/gh/fawazahmed0/quran-api@1/editions/eng-maududi/{surah}/{ayat}.json"
46
+ eng_tafseer_response = requests.get(eng_tafseer_url, timeout=5)
47
+ eng_tafseer_data = eng_tafseer_response.json()
48
+ tafseer_english = eng_tafseer_data["text"]
49
+
50
+ # Fetch Urdu Tafseer from quran-api (Maududi)
51
+ urd_tafseer_url = f"https://cdn.jsdelivr.net/gh/fawazahmed0/quran-api@1/editions/urd-maududi/{surah}/{ayat}.json"
52
+ urd_tafseer_response = requests.get(urd_tafseer_url, timeout=5)
53
+ urd_tafseer_data = urd_tafseer_response.json()
54
+ tafseer_urdu = urd_tafseer_data["text"]
55
+
56
+ return {
57
+ "reference": data["surah"]["englishName"] + " (" + data["surah"]["name"] + "), Ayat " + str(data["numberInSurah"]),
58
+ "arabic": data["text"],
59
+ "english_translation": english_data["text"],
60
+ "urdu_translation": urdu_data["text"],
61
+ "english_tafseer": tafseer_english,
62
+ "urdu_tafseer": tafseer_urdu,
63
+ "audio": audio_data["audio"]
64
+ }
65
+ except Exception as e:
66
+ st.error(f"Failed to fetch verse data: {str(e)}")
67
+ return None
68
+
69
+ # Main app
70
+ def main():
71
+ # Display logo and title
72
+ st.image("https://cdn.pixabay.com/photo/2017/03/27/13/59/quran-2178816_1280.png", width=200)
73
+ st.title("MoodVerse")
74
+ st.markdown("Discover peace and guidance from the Holy Quran. Select a mood to receive a random uplifting verse or dua, complete with Arabic text, translations in English and Urdu, and explanations (tafseer).")
75
+
76
+ # Sidebar for mood selection and language toggle
77
+ st.sidebar.header("Select a Mood")
78
+ moods = [
79
+ "Angry", "Happy", "Depressed", "Sick",
80
+ "Tired", "Frustrated", "Evil Eye",
81
+ "Indecisive", "Proud", "Aggressive",
82
+ "Lonely", "Guilty", "Hopeful"
83
+ ]
84
+ selected_mood = st.sidebar.radio("Choose a mood", moods)
85
+ language = st.sidebar.selectbox("Language", ["Bilingual", "English", "Urdu"])
86
+
87
+ # Random mood button
88
+ if st.sidebar.button("Random Mood"):
89
+ selected_mood = random.choice(moods)
90
+
91
+ # Load mood-to-verse mapping
92
+ mood_verses = load_mood_verses()
93
+ verses = mood_verses.get(selected_mood.lower(), [])
94
+
95
+ if not verses:
96
+ st.warning("No verses found for this mood.")
97
+ return
98
+
99
+ # Generate random verse on mood selection or button press
100
+ if "selected_mood" not in st.session_state:
101
+ st.session_state.selected_mood = selected_mood
102
+ if "current_verse" not in st.session_state or st.session_state.selected_mood != selected_mood or st.button("Generate Another"):
103
+ st.session_state.current_verse = random.choice(verses)
104
+ st.session_state.selected_mood = selected_mood
105
+
106
+ verse_ref = st.session_state.current_verse
107
+ with st.spinner("Fetching verse data..."):
108
+ verse_data = fetch_verse_data(verse_ref)
109
+
110
+ if verse_data:
111
+ # Display verse
112
+ st.markdown(f"### {verse_data['reference']}")
113
+ st.markdown(f"<div class='arabic-text'>{verse_data['arabic']}</div>", unsafe_allow_html=True)
114
+
115
+ col1, col2 = st.columns(2)
116
+ if language in ["Bilingual", "English"]:
117
+ with col1:
118
+ st.markdown("<div class='english-translation'>**English Translation**</div>", unsafe_allow_html=True)
119
+ st.markdown(f"<div class='english-translation'>{verse_data['english_translation']}</div>", unsafe_allow_html=True)
120
+ st.markdown("<div class='english-tafseer'>**English Tafseer**</div>", unsafe_allow_html=True)
121
+ st.markdown(f"<div class='english-tafseer'>{verse_data['english_tafseer']}</div>", unsafe_allow_html=True)
122
+ if language in ["Bilingual", "Urdu"]:
123
+ with col2:
124
+ st.markdown("<div class='urdu-translation'>**اردو ترجمہ**</div>", unsafe_allow_html=True)
125
+ st.markdown(f"<div class='urdu-translation'>{verse_data['urdu_translation']}</div>", unsafe_allow_html=True)
126
+ st.markdown("<div class='urdu-tafseer'>**اردو تفسیر**</div>", unsafe_allow_html=True)
127
+ st.markdown(f"<div class='urdu-tafseer'>{verse_data['urdu_tafseer']}</div>", unsafe_allow_html=True)
128
+
129
+ # Audio playback
130
+ if verse_data["audio"]:
131
+ st.audio(verse_data["audio"], format="audio/mp3")
132
+
133
+ # Save verse button
134
+ if "saved_verses" not in st.session_state:
135
+ st.session_state.saved_verses = []
136
+
137
+ if st.button("Save this Verse"):
138
+ if len(st.session_state.saved_verses) < 10 and verse_data not in st.session_state.saved_verses:
139
+ st.session_state.saved_verses.append(verse_data)
140
+ elif len(st.session_state.saved_verses) >= 10:
141
+ st.warning("You can save up to 10 verses only.")
142
+
143
+ # Display saved verses in expander
144
+ with st.expander("Saved Verses"):
145
+ for i, saved in enumerate(st.session_state.saved_verses):
146
+ st.markdown(f"**Saved {i+1}: {saved['reference']}**")
147
+ if st.button(f"View {saved['reference']}", key=f"view_{i}"):
148
+ st.markdown(f"<div class='arabic-text'>{saved['arabic']}</div>", unsafe_allow_html=True)
149
+ st.write(saved["english_translation"])
150
+ st.write(saved["urdu_translation"])
151
+ st.write(saved["english_tafseer"])
152
+ st.write(saved["urdu_tafseer"])
153
+
154
+ # Footer
155
+ st.markdown("---")
156
+ st.markdown("Data sourced from Al-Quran API and Quran-API on GitHub. Built with Streamlit.")
157
+
158
+ if __name__ == "__main__":
159
+ main()
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ streamlit==1.25.0
2
+ requests==2.31.0
3
+ beautifulsoup4==4.12.2
4
+ python-dotenv==1.0.0
style.css CHANGED
@@ -1,65 +1,40 @@
 
 
 
 
1
  .arabic-text {
2
- font-family: 'Traditional Arabic', 'Scheherazade New', serif;
3
  font-size: 24px;
4
- text-align: right;
5
  direction: rtl;
6
- line-height: 2;
7
- margin: 20px 0;
8
- padding: 15px;
9
- background-color: #f8f9fa;
10
- border-radius: 10px;
11
- border-right: 4px solid #2ca02c;
12
- }
13
-
14
- .urdu-text {
15
- font-family: 'Jameel Noori Nastaleeq', 'Urdu Typesetting', serif;
16
- font-size: 18px;
17
  text-align: right;
18
- direction: rtl;
19
- line-height: 1.8;
20
- margin: 15px 0;
21
- padding: 10px;
22
- background-color: #f0f2f6;
23
- border-radius: 8px;
 
 
 
24
  }
25
-
26
- .english-text {
27
- font-size: 16px;
28
- line-height: 1.6;
29
- margin: 15px 0;
30
  padding: 10px;
31
- background-color: #f0f2f6;
32
- border-radius: 8px;
33
  }
34
-
35
- .tafseer-text {
36
- font-style: italic;
37
- color: #555;
38
- margin: 10px 0;
39
  padding: 10px;
40
- background-color: #f8f9fa;
41
- border-left: 3px solid #1f77b4;
42
  border-radius: 5px;
43
  }
44
-
45
- .footer {
46
- text-align: center;
47
- font-size: 14px;
48
- color: #666;
49
- margin-top: 30px;
50
  }
51
-
52
- /* Mobile responsiveness */
53
- @media (max-width: 768px) {
54
- .arabic-text {
55
- font-size: 20px;
56
- }
57
-
58
- .urdu-text {
59
- font-size: 16px;
60
- }
61
-
62
- .english-text {
63
- font-size: 14px;
64
- }
65
  }
 
1
+ body {
2
+ font-family: Arial, sans-serif;
3
+ background-color: #f0f8ff;
4
+ }
5
  .arabic-text {
 
6
  font-size: 24px;
 
7
  direction: rtl;
 
 
 
 
 
 
 
 
 
 
 
8
  text-align: right;
9
+ color: #2c3e50;
10
+ margin-bottom: 20px;
11
+ }
12
+ h3 {
13
+ color: #1a5f7a;
14
+ }
15
+ button {
16
+ background-color: #1a5f7a !important;
17
+ color: white !important;
18
  }
19
+ .english-translation {
20
+ color: #007bff;
 
 
 
21
  padding: 10px;
22
+ border-radius: 5px;
 
23
  }
24
+ .english-tafseer {
25
+ color: #28a745;
 
 
 
26
  padding: 10px;
 
 
27
  border-radius: 5px;
28
  }
29
+ .urdu-translation {
30
+ color: #dc3545;
31
+ padding: 10px;
32
+ border-radius: 5px;
33
+ direction: rtl;
 
34
  }
35
+ .urdu-tafseer {
36
+ color: #ffc107;
37
+ padding: 10px;
38
+ border-radius: 5px;
39
+ direction: rtl;
 
 
 
 
 
 
 
 
 
40
  }