afaaaak commited on
Commit
28db5c0
·
verified ·
1 Parent(s): 2ac2788

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +375 -0
app.py ADDED
@@ -0,0 +1,375 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from transformers import MarianMTModel, MarianTokenizer
3
+ import torch
4
+ from deep_translator import GoogleTranslator
5
+ import re
6
+
7
+ # ================================
8
+ # PAGE CONFIGURATION
9
+ # ================================
10
+ st.set_page_config(
11
+ page_title="Urdu to Pashto Translator",
12
+ page_icon="🌐",
13
+ layout="wide",
14
+ initial_sidebar_state="collapsed"
15
+ )
16
+
17
+ # ================================
18
+ # CUSTOM CSS - GLASSMORPHISM THEME
19
+ # ================================
20
+ def load_css():
21
+ st.markdown("""
22
+ <style>
23
+ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600;700&family=Righteous&display=swap');
24
+
25
+ * {
26
+ margin: 0;
27
+ padding: 0;
28
+ box-sizing: border-box;
29
+ }
30
+
31
+ /* Main Background */
32
+ .stApp {
33
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 25%, #f093fb 50%, #4facfe 75%, #00f2fe 100%);
34
+ background-size: 400% 400%;
35
+ animation: gradientShift 15s ease infinite;
36
+ font-family: 'Poppins', sans-serif;
37
+ }
38
+
39
+ @keyframes gradientShift {
40
+ 0% { background-position: 0% 50%; }
41
+ 50% { background-position: 100% 50%; }
42
+ 100% { background-position: 0% 50%; }
43
+ }
44
+
45
+ /* Hide Streamlit Branding */
46
+ #MainMenu {visibility: hidden;}
47
+ footer {visibility: hidden;}
48
+ header {visibility: hidden;}
49
+
50
+ /* Glass Container */
51
+ .glass-container {
52
+ background: rgba(255, 255, 255, 0.15);
53
+ backdrop-filter: blur(20px);
54
+ -webkit-backdrop-filter: blur(20px);
55
+ border-radius: 25px;
56
+ border: 2px solid rgba(255, 255, 255, 0.3);
57
+ box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
58
+ padding: 40px;
59
+ margin: 20px auto;
60
+ max-width: 1200px;
61
+ }
62
+
63
+ /* Title Styling */
64
+ .main-title {
65
+ font-family: 'Righteous', cursive;
66
+ font-size: 3.5rem;
67
+ text-align: center;
68
+ background: linear-gradient(135deg, #ffffff 0%, #e0e7ff 100%);
69
+ -webkit-background-clip: text;
70
+ -webkit-text-fill-color: transparent;
71
+ background-clip: text;
72
+ margin-bottom: 10px;
73
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.2);
74
+ animation: titleGlow 3s ease-in-out infinite;
75
+ }
76
+
77
+ @keyframes titleGlow {
78
+ 0%, 100% { filter: drop-shadow(0 0 10px rgba(255,255,255,0.5)); }
79
+ 50% { filter: drop-shadow(0 0 20px rgba(255,255,255,0.8)); }
80
+ }
81
+
82
+ .subtitle {
83
+ text-align: center;
84
+ color: rgba(255, 255, 255, 0.9);
85
+ font-size: 1.2rem;
86
+ margin-bottom: 40px;
87
+ font-weight: 300;
88
+ }
89
+
90
+ /* Text Areas */
91
+ .stTextArea textarea {
92
+ background: rgba(255, 255, 255, 0.2) !important;
93
+ backdrop-filter: blur(10px);
94
+ border: 2px solid rgba(255, 255, 255, 0.4) !important;
95
+ border-radius: 15px !important;
96
+ color: #ffffff !important;
97
+ font-size: 1.1rem !important;
98
+ padding: 15px !important;
99
+ font-family: 'Poppins', sans-serif !important;
100
+ transition: all 0.3s ease;
101
+ }
102
+
103
+ .stTextArea textarea:focus {
104
+ border-color: rgba(255, 255, 255, 0.8) !important;
105
+ box-shadow: 0 0 20px rgba(255, 255, 255, 0.4) !important;
106
+ transform: scale(1.02);
107
+ }
108
+
109
+ .stTextArea textarea::placeholder {
110
+ color: rgba(255, 255, 255, 0.6) !important;
111
+ }
112
+
113
+ /* Labels */
114
+ .stTextArea label {
115
+ color: #ffffff !important;
116
+ font-weight: 600 !important;
117
+ font-size: 1.1rem !important;
118
+ margin-bottom: 10px !important;
119
+ }
120
+
121
+ /* 3D Button Styling */
122
+ .stButton button {
123
+ background: linear-gradient(145deg, #667eea, #764ba2);
124
+ color: white;
125
+ border: none;
126
+ border-radius: 15px;
127
+ padding: 15px 40px;
128
+ font-size: 1.2rem;
129
+ font-weight: 600;
130
+ font-family: 'Poppins', sans-serif;
131
+ cursor: pointer;
132
+ transition: all 0.3s ease;
133
+ box-shadow: 0 10px 25px rgba(102, 126, 234, 0.4),
134
+ inset 0 -3px 10px rgba(0, 0, 0, 0.2),
135
+ inset 0 3px 10px rgba(255, 255, 255, 0.2);
136
+ position: relative;
137
+ overflow: hidden;
138
+ width: 100%;
139
+ }
140
+
141
+ .stButton button:before {
142
+ content: '';
143
+ position: absolute;
144
+ top: 0;
145
+ left: -100%;
146
+ width: 100%;
147
+ height: 100%;
148
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
149
+ transition: left 0.5s;
150
+ }
151
+
152
+ .stButton button:hover:before {
153
+ left: 100%;
154
+ }
155
+
156
+ .stButton button:hover {
157
+ transform: translateY(-3px) scale(1.05);
158
+ box-shadow: 0 15px 35px rgba(102, 126, 234, 0.6),
159
+ inset 0 -3px 10px rgba(0, 0, 0, 0.2),
160
+ inset 0 3px 10px rgba(255, 255, 255, 0.3);
161
+ }
162
+
163
+ .stButton button:active {
164
+ transform: translateY(0px) scale(1);
165
+ box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
166
+ }
167
+
168
+ /* Clear Button */
169
+ .clear-button button {
170
+ background: linear-gradient(145deg, #f093fb, #f5576c);
171
+ box-shadow: 0 10px 25px rgba(245, 87, 108, 0.4);
172
+ }
173
+
174
+ .clear-button button:hover {
175
+ box-shadow: 0 15px 35px rgba(245, 87, 108, 0.6);
176
+ }
177
+
178
+ /* Info Box */
179
+ .info-box {
180
+ background: rgba(255, 255, 255, 0.1);
181
+ backdrop-filter: blur(10px);
182
+ border-radius: 15px;
183
+ border: 1px solid rgba(255, 255, 255, 0.3);
184
+ padding: 20px;
185
+ margin: 20px 0;
186
+ color: white;
187
+ }
188
+
189
+ .info-box h3 {
190
+ color: #ffffff;
191
+ font-weight: 600;
192
+ margin-bottom: 10px;
193
+ }
194
+
195
+ .info-box p {
196
+ color: rgba(255, 255, 255, 0.8);
197
+ line-height: 1.6;
198
+ }
199
+
200
+ /* Loading Animation */
201
+ .stSpinner > div {
202
+ border-top-color: #ffffff !important;
203
+ }
204
+
205
+ /* Columns */
206
+ .element-container {
207
+ margin-bottom: 20px;
208
+ }
209
+
210
+ /* Success Message */
211
+ .stSuccess {
212
+ background: rgba(72, 187, 120, 0.2);
213
+ backdrop-filter: blur(10px);
214
+ border-radius: 10px;
215
+ border: 1px solid rgba(72, 187, 120, 0.4);
216
+ color: white;
217
+ }
218
+
219
+ /* Footer */
220
+ .footer {
221
+ text-align: center;
222
+ color: rgba(255, 255, 255, 0.7);
223
+ margin-top: 50px;
224
+ padding: 20px;
225
+ font-size: 0.9rem;
226
+ }
227
+
228
+ /* Responsive Design */
229
+ @media (max-width: 768px) {
230
+ .main-title {
231
+ font-size: 2rem;
232
+ }
233
+
234
+ .subtitle {
235
+ font-size: 1rem;
236
+ }
237
+
238
+ .glass-container {
239
+ padding: 20px;
240
+ }
241
+ }
242
+ </style>
243
+ """, unsafe_allow_html=True)
244
+
245
+ # ================================
246
+ # TRANSLATION FUNCTIONS
247
+ # ================================
248
+
249
+ @st.cache_resource
250
+ def load_translation_model():
251
+ """Load the translation model (cached for performance)"""
252
+ try:
253
+ # Using a multilingual model that supports Urdu and Pashto
254
+ model_name = "Helsinki-NLP/opus-mt-mul-en"
255
+ tokenizer = MarianTokenizer.from_pretrained(model_name)
256
+ model = MarianMTModel.from_pretrained(model_name)
257
+ return tokenizer, model
258
+ except Exception as e:
259
+ st.error(f"Error loading model: {e}")
260
+ return None, None
261
+
262
+ def urdu_to_pashto_roman(urdu_text):
263
+ """
264
+ Translate Urdu to Pashto and romanize it
265
+ """
266
+ if not urdu_text.strip():
267
+ return ""
268
+
269
+ try:
270
+ # Step 1: Translate Urdu to Pashto using Google Translator
271
+ translator_to_pashto = GoogleTranslator(source='ur', target='ps')
272
+ pashto_text = translator_to_pashto.translate(urdu_text)
273
+
274
+ # Step 2: Transliterate Pashto to Roman script
275
+ # Using English as intermediate for romanization
276
+ translator_to_roman = GoogleTranslator(source='ps', target='en')
277
+ temp_english = translator_to_roman.translate(pashto_text)
278
+
279
+ # Step 3: Create phonetic Roman Urdu representation
280
+ # This gives us a romanized version
281
+ romanized = create_roman_representation(pashto_text, temp_english)
282
+
283
+ return romanized
284
+
285
+ except Exception as e:
286
+ st.error(f"Translation error: {e}")
287
+ return "Translation failed. Please try again."
288
+
289
+ def create_roman_representation(pashto_text, english_reference):
290
+ """
291
+ Create a Roman Urdu representation of Pashto text
292
+ """
293
+ # Pashto to Roman Urdu character mapping (phonetic)
294
+ pashto_to_roman = {
295
+ 'ا': 'a', 'ب': 'b', 'پ': 'p', 'ت': 't', 'ټ': 't', 'ث': 's',
296
+ 'ج': 'j', 'چ': 'ch', 'ح': 'h', 'خ': 'kh', 'د': 'd', 'ډ': 'd',
297
+ 'ذ': 'z', 'ر': 'r', 'ړ': 'r', 'ز': 'z', 'ژ': 'zh', 'ږ': 'g',
298
+ 'س': 's', 'ش': 'sh', 'ښ': 'kh', 'ص': 's', 'ض': 'z', 'ط': 't',
299
+ 'ظ': 'z', 'ع': 'a', 'غ': 'gh', 'ف': 'f', 'ق': 'q', 'ک': 'k',
300
+ 'ګ': 'g', 'ل': 'l', 'م': 'm', 'ن': 'n', 'ڼ': 'n', 'و': 'o',
301
+ 'ه': 'h', 'ۀ': 'a', 'ي': 'i', 'ې': 'e', 'ی': 'i', 'ئ': 'y',
302
+ ' ': ' ', '،': ',', '؟': '?', '۔': '.'
303
+ }
304
+
305
+ # Transliterate Pashto to Roman
306
+ roman_text = ''
307
+ for char in pashto_text:
308
+ roman_text += pashto_to_roman.get(char, char)
309
+
310
+ # If transliteration is too rough, use English reference with Urdu touch
311
+ if len(roman_text.strip()) < 3:
312
+ return english_reference
313
+
314
+ return roman_text
315
+
316
+ # ================================
317
+ # MAIN APPLICATION
318
+ # ================================
319
+
320
+ def main():
321
+ # Load custom CSS
322
+ load_css()
323
+
324
+ # Header
325
+ st.markdown('<h1 class="main-title">🌐 Urdu to Pashto Translator</h1>', unsafe_allow_html=True)
326
+ st.markdown('<p class="subtitle">Convert Urdu sentences to Pashto in Roman script</p>', unsafe_allow_html=True)
327
+
328
+ # Main container
329
+ st.markdown('<div class="glass-container">', unsafe_allow_html=True)
330
+
331
+ # Create two columns for input and output
332
+ col1, col2 = st.columns(2)
333
+
334
+ with col1:
335
+ st.markdown("### 📝 Input (Urdu)")
336
+ urdu_input = st.text_area(
337
+ "Enter Urdu text",
338
+ height=250,
339
+ placeholder="یہاں اردو متن درج کریں...",
340
+ label_visibility="collapsed",
341
+ key="urdu_input"
342
+ )
343
+
344
+ with col2:
345
+ st.markdown("### 🔤 Output (Pashto in Roman)")
346
+ if 'translation_output' not in st.session_state:
347
+ st.session_state.translation_output = ""
348
+
349
+ translation_output = st.text_area(
350
+ "Pashto translation in Roman script",
351
+ value=st.session_state.translation_output,
352
+ height=250,
353
+ placeholder="Translation will appear here...",
354
+ label_visibility="collapsed",
355
+ key="output_display",
356
+ disabled=True
357
+ )
358
+
359
+ # Buttons
360
+ col_btn1, col_btn2, col_btn3 = st.columns([1, 1, 1])
361
+
362
+ with col_btn2:
363
+ if st.button("🔄 Translate", use_container_width=True):
364
+ if urdu_input.strip():
365
+ with st.spinner("✨ Translating..."):
366
+ result = urdu_to_pashto_roman(urdu_input)
367
+ st.session_state.translation_output = result
368
+ st.rerun()
369
+ else:
370
+ st.warning("⚠️ Please enter some Urdu text first!")
371
+
372
+ with col_btn3:
373
+ st.markdown('<div class="clear-button">', unsafe_allow_html=True)
374
+ if st.button("🗑️ Clear", use_container_width=True):
375
+ st.session_state.translation_output = ""