445 lines
16 KiB
Python
445 lines
16 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Comprehensive script to translate all remaining batch files with Arabic translations
|
|
"""
|
|
|
|
import re
|
|
import os
|
|
|
|
# Comprehensive Arabic translation dictionary
|
|
TRANSLATIONS = {
|
|
# Email and Authentication
|
|
"The date and time this notification is scheduled to be sent.": "التاريخ والوقت المحدد لإرسال هذا الإشعار.",
|
|
"Send Attempts": "محاولات الإرسال",
|
|
"Failed to start the job posting process. Please try again.": "فشل في بدء عملية نشر الوظيفة. يرجى المحاولة مرة أخرى.",
|
|
"You don't have permission to view this page.": "ليس لديك إذن لعرض هذه الصفحة.",
|
|
"Account Inactive": "الحساب غير نشط",
|
|
"Princess Nourah bint Abdulrahman University": "جامعة الأميرة نورة بنت عبدالرحمن",
|
|
"Manage your personal details and security.": "إدارة تفاصيلك الشخصية والأمان.",
|
|
"Primary": "أساسي",
|
|
"Verified": "موثق",
|
|
"Unverified": "غير موثق",
|
|
"Make Primary": "جعل أساسي",
|
|
"Remove": "إزالة",
|
|
"Add Email Address": "إضافة عنوان بريد إلكتروني",
|
|
"Hello,": "مرحباً،",
|
|
"Confirm My KAAUH ATS Email": "تأكيد بريدي الإلكتروني في نظام توظيف جامعة نورة",
|
|
"Alternatively, copy and paste this link into your browser:": "بدلاً من ذلك، انسخ والصق هذا الرابط في متصفحك:",
|
|
"Password Reset Request": "طلب إعادة تعيين كلمة المرور",
|
|
"Click Here to Reset Your Password": "اضغط هنا لإعادة تعيين كلمة المرور",
|
|
"This link is only valid for a limited time.": "هذا الرابط صالح لفترة محدودة فقط.",
|
|
"Thank you,": "شكراً لك،",
|
|
"KAAUH ATS Team": "فريق نظام توظيف جامعة نورة",
|
|
"Confirm Email Address": "تأكيد عنوان البريد الإلكتروني",
|
|
"Account Verification": "التحقق من الحساب",
|
|
"Verify your email to secure your account and unlock full features.": "تحقق من بريدك الإلكتروني لتأمين حسابك وإلغاء قفل جميع الميزات.",
|
|
"Confirm Your Email Address": "تأكيد عنوان بريدك الإلكتروني",
|
|
"Verification Failed": "فشل التحقق",
|
|
"The email confirmation link is expired or invalid.": "رابط تأكيد البريد الإلكتروني منتهي الصلاحية أو غير صالح.",
|
|
"Keep me signed in": "ابق مسجلاً للدخول",
|
|
"Return to Profile": "العودة إلى الملف الشخصي",
|
|
"Enter your e-mail address to reset your password.": "أدخل عنوان بريدك الإلكتروني لإعادة تعيين كلمة المرور.",
|
|
"Remember your password?": "تتذكر كلمة المرور؟",
|
|
"Log In": "تسجيل الدخول",
|
|
"Password Reset Sent": "تم إرسال إعادة تعيين كلمة المرور",
|
|
"Return to Login": "العودة إلى تسجيل الدخول",
|
|
"Please enter your new password below.": "يرجى إدخال كلمة المرور الجديدة أدناه.",
|
|
|
|
# Common UI Elements
|
|
"Save": "حفظ",
|
|
"Cancel": "إلغاء",
|
|
"Delete": "حذف",
|
|
"Edit": "تحرير",
|
|
"View": "عرض",
|
|
"Create": "إنشاء",
|
|
"Update": "تحديث",
|
|
"Submit": "إرسال",
|
|
"Search": "بحث",
|
|
"Filter": "تصفية",
|
|
"Sort": "ترتيب",
|
|
"Export": "تصدير",
|
|
"Import": "استيراد",
|
|
"Download": "تنزيل",
|
|
"Upload": "رفع",
|
|
"Close": "إغلاق",
|
|
"Back": "رجوع",
|
|
"Next": "التالي",
|
|
"Previous": "السابق",
|
|
"First": "الأول",
|
|
"Last": "الأخير",
|
|
"Home": "الرئيسية",
|
|
"Dashboard": "لوحة التحكم",
|
|
"Profile": "الملف الشخصي",
|
|
"Settings": "الإعدادات",
|
|
"Help": "المساعدة",
|
|
"About": "حول",
|
|
"Contact": "اتصال",
|
|
"Logout": "تسجيل الخروج",
|
|
"Login": "تسجيل الدخول",
|
|
"Register": "التسجيل",
|
|
"Sign Up": "إنشاء حساب",
|
|
"Sign In": "تسجيل الدخول",
|
|
|
|
# Status Messages
|
|
"Active": "نشط",
|
|
"Inactive": "غير نشط",
|
|
"Pending": "في الانتظار",
|
|
"Completed": "مكتمل",
|
|
"Failed": "فشل",
|
|
"Success": "نجح",
|
|
"Error": "خطأ",
|
|
"Warning": "تحذير",
|
|
"Info": "معلومات",
|
|
"Loading": "جاري التحميل",
|
|
"Processing": "جاري المعالجة",
|
|
"Ready": "جاهز",
|
|
"Not Ready": "غير جاهز",
|
|
"Available": "متاح",
|
|
"Unavailable": "غير متاح",
|
|
"Online": "متصل",
|
|
"Offline": "غير متصل",
|
|
"Connected": "متصل",
|
|
"Disconnected": "منقطع",
|
|
"Enabled": "مفعل",
|
|
"Disabled": "معطل",
|
|
"Required": "مطلوب",
|
|
"Optional": "اختياري",
|
|
"Yes": "نعم",
|
|
"No": "لا",
|
|
"True": "صحيح",
|
|
"False": "خطأ",
|
|
"On": "مفعل",
|
|
"Off": "معطل",
|
|
"Open": "مفتوح",
|
|
"Closed": "مغلق",
|
|
"Locked": "مقفل",
|
|
"Unlocked": "غير مقفل",
|
|
|
|
# Form Fields
|
|
"Name": "الاسم",
|
|
"Email": "البريد الإلكتروني",
|
|
"Phone": "الهاتف",
|
|
"Address": "العنوان",
|
|
"City": "المدينة",
|
|
"Country": "البلد",
|
|
"State": "الولاية",
|
|
"Zip Code": "الرمز البريدي",
|
|
"Password": "كلمة المرور",
|
|
"Confirm Password": "تأكيد كلمة المرور",
|
|
"Username": "اسم المستخدم",
|
|
"First Name": "الاسم الأول",
|
|
"Last Name": "اسم العائلة",
|
|
"Full Name": "الاسم الكامل",
|
|
"Company": "الشركة",
|
|
"Position": "المنصب",
|
|
"Department": "القسم",
|
|
"Title": "العنوان",
|
|
"Description": "الوصف",
|
|
"Comments": "التعليقات",
|
|
"Notes": "ملاحظات",
|
|
"Date": "التاريخ",
|
|
"Time": "الوقت",
|
|
"Start Date": "تاريخ البدء",
|
|
"End Date": "تاريخ الانتهاء",
|
|
"Created": "تم الإنشاء",
|
|
"Modified": "تم التعديل",
|
|
"Updated": "تم التحديث",
|
|
|
|
# Messages
|
|
"Please select an option": "يرجى اختيار خيار",
|
|
"This field is required": "هذا الحقل مطلوب",
|
|
"Invalid email address": "عنوان بريد إلكتروني غير صالح",
|
|
"Password must be at least 8 characters": "يجب أن تكون كلمة المرور 8 أحرف على الأقل",
|
|
"Passwords do not match": "كلمات المرور غير متطابقة",
|
|
"Email already exists": "البريد الإلكتروني موجود بالفعل",
|
|
"User not found": "المستخدم غير موجود",
|
|
"Invalid credentials": "بيانات الاعتماد غير صالحة",
|
|
"Access denied": "الوصول مرفوض",
|
|
"Permission denied": "الإذن مرفوض",
|
|
"Operation successful": "تمت العملية بنجاح",
|
|
"Operation failed": "فشلت العملية",
|
|
"Data saved successfully": "تم حفظ البيانات بنجاح",
|
|
"Data deleted successfully": "تم حذف البيانات بنجاح",
|
|
"Are you sure you want to delete this item?": "هل أنت متأكد من أنك تريد حذف هذا العنصر؟",
|
|
"This action cannot be undone": "لا يمكن التراجع عن هذا الإجراء",
|
|
|
|
# Navigation
|
|
"Menu": "القائمة",
|
|
"Home": "الرئيسية",
|
|
"Dashboard": "لوحة التحكم",
|
|
"Profile": "الملف الشخصي",
|
|
"Settings": "الإعدادات",
|
|
"Admin": "المسؤول",
|
|
"Users": "المستخدمون",
|
|
"Reports": "التقارير",
|
|
"Analytics": "التحليلات",
|
|
"Messages": "الرسائل",
|
|
"Notifications": "الإشعارات",
|
|
"Tasks": "المهام",
|
|
"Calendar": "التقويم",
|
|
"Documents": "المستندات",
|
|
"Files": "الملفات",
|
|
"Media": "الوسائط",
|
|
"Help": "المساعدة",
|
|
"Support": "الدعم",
|
|
"FAQ": "الأسئلة الشائعة",
|
|
"Terms": "الشروط",
|
|
"Privacy": "الخصوصية",
|
|
"Legal": "قانوني",
|
|
|
|
# Common Actions
|
|
"Add": "إضافة",
|
|
"Remove": "إزالة",
|
|
"Edit": "تحرير",
|
|
"Update": "تحديث",
|
|
"Delete": "حذف",
|
|
"View": "عرض",
|
|
"Show": "إظهار",
|
|
"Hide": "إخفاء",
|
|
"Enable": "تفعيل",
|
|
"Disable": "تعطيل",
|
|
"Activate": "تنشيط",
|
|
"Deactivate": "إلغاء تنشيط",
|
|
"Approve": "موافقة",
|
|
"Reject": "رفض",
|
|
"Accept": "قبول",
|
|
"Decline": "رفض",
|
|
"Send": "إرسال",
|
|
"Receive": "استلام",
|
|
"Download": "تنزيل",
|
|
"Upload": "رفع",
|
|
"Import": "استيراد",
|
|
"Export": "تصدير",
|
|
"Print": "طباعة",
|
|
"Copy": "نسخ",
|
|
"Move": "نقل",
|
|
"Rename": "إعادة تسمية",
|
|
"Share": "مشاركة",
|
|
"Subscribe": "اشتراك",
|
|
"Unsubscribe": "إلغاء الاشتراك",
|
|
"Follow": "متابعة",
|
|
"Unfollow": "إلغاء المتابعة",
|
|
"Like": "إعجاب",
|
|
"Unlike": "إلغاء الإعجاب",
|
|
"Comment": "تعليق",
|
|
"Rate": "تقييم",
|
|
"Review": "مراجعة",
|
|
"Bookmark": "إشارة مرجعية",
|
|
"Favorite": "مفضل",
|
|
"Archive": "أرشفة",
|
|
"Restore": "استعادة",
|
|
"Backup": "نسخ احتياطي",
|
|
"Recover": "استرداد",
|
|
"Reset": "إعادة تعيين",
|
|
"Refresh": "تحديث",
|
|
"Reload": "إعادة تحميل",
|
|
"Sync": "مزامنة",
|
|
"Connect": "اتصال",
|
|
"Disconnect": "قطع الاتصال",
|
|
"Link": "ربط",
|
|
"Unlink": "فك الربط",
|
|
"Attach": "إرفاق",
|
|
"Detach": "فصل",
|
|
"Merge": "دمج",
|
|
"Split": "تقسيم",
|
|
"Combine": "دمج",
|
|
"Separate": "فصل",
|
|
"Group": "تجميع",
|
|
"Ungroup": "فك التجميع",
|
|
"Sort": "ترتيب",
|
|
"Filter": "تصفية",
|
|
"Search": "بحث",
|
|
"Find": "بحث",
|
|
"Replace": "استبدال",
|
|
"Clear": "مسح",
|
|
"Clean": "تنظيف",
|
|
"Empty": "فارغ",
|
|
"Full": "ممتلئ",
|
|
"All": "الكل",
|
|
"None": "لا شيء",
|
|
"Some": "بعض",
|
|
"Any": "أي",
|
|
"Other": "آخر",
|
|
"More": "المزيد",
|
|
"Less": "أقل",
|
|
"New": "جديد",
|
|
"Old": "قديم",
|
|
"Recent": "الحديث",
|
|
"Latest": "الأحدث",
|
|
"Previous": "السابق",
|
|
"Next": "التالي",
|
|
"First": "الأول",
|
|
"Last": "الأخير",
|
|
"Current": "الحالي",
|
|
"Today": "اليوم",
|
|
"Yesterday": "أمس",
|
|
"Tomorrow": "غداً",
|
|
"This week": "هذا الأسبوع",
|
|
"Last week": "الأسبوع الماضي",
|
|
"Next week": "الأسبوع القادم",
|
|
"This month": "هذا الشهر",
|
|
"Last month": "الشهر الماضي",
|
|
"Next month": "الشهر القادم",
|
|
"This year": "هذا العام",
|
|
"Last year": "العام الماضي",
|
|
"Next year": "العام القادم",
|
|
}
|
|
|
|
def translate_batch_file(batch_file_path):
|
|
"""
|
|
Translate a single batch file and return the translations
|
|
"""
|
|
translations = {}
|
|
|
|
with open(batch_file_path, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
|
|
lines = content.split('\n')
|
|
i = 0
|
|
while i < len(lines):
|
|
line = lines[i].strip()
|
|
if line.startswith('msgid: "'):
|
|
# Extract msgid content, removing the extra quote at the beginning
|
|
msgid = line[8:-1] # Extract msgid content (skip the extra quote)
|
|
|
|
# Skip empty msgid or already Arabic text
|
|
if not msgid or msgid.strip() == "" or is_arabic_text(msgid):
|
|
i += 1
|
|
continue
|
|
|
|
# Find translation
|
|
translation = TRANSLATIONS.get(msgid, "")
|
|
if translation:
|
|
translations[msgid] = translation
|
|
print(f"✓ Found translation: '{msgid}' -> '{translation}'")
|
|
else:
|
|
print(f"✗ No translation found: '{msgid}'")
|
|
i += 1
|
|
|
|
return translations
|
|
|
|
def is_arabic_text(text):
|
|
"""Check if text contains Arabic characters"""
|
|
arabic_chars = set('ابتثجحخدذرزسشصضطظعغفقكلمنهويءآأؤإئابةة')
|
|
return any(char in arabic_chars for char in text)
|
|
|
|
def process_all_batches():
|
|
"""
|
|
Process all batch files and create a comprehensive translation file
|
|
"""
|
|
all_translations = {}
|
|
|
|
# Process batches 02-35 (batch 01 already done)
|
|
for batch_num in range(2, 36):
|
|
batch_file = f"translation_batch_{batch_num:02d}.txt"
|
|
if os.path.exists(batch_file):
|
|
print(f"\n=== Processing {batch_file} ===")
|
|
batch_translations = translate_batch_file(batch_file)
|
|
all_translations.update(batch_translations)
|
|
print(f"Found {len(batch_translations)} translations in {batch_file}")
|
|
else:
|
|
print(f"⚠️ {batch_file} not found")
|
|
|
|
return all_translations
|
|
|
|
def create_translation_script(all_translations):
|
|
"""
|
|
Create a script to apply all translations to the main django.po file
|
|
"""
|
|
script_content = '''#!/usr/bin/env python3
|
|
"""
|
|
Script to apply all batch translations to the main django.po file
|
|
"""
|
|
|
|
import re
|
|
|
|
def apply_all_translations():
|
|
"""
|
|
Apply all translations to the main django.po file
|
|
"""
|
|
# All translations from batches 02-35
|
|
translations = {
|
|
'''
|
|
|
|
for english, arabic in all_translations.items():
|
|
script_content += f' "{english}": "{arabic}",\n'
|
|
|
|
script_content += ''' }
|
|
|
|
main_po_file = "locale/ar/LC_MESSAGES/django.po"
|
|
|
|
# Read the main django.po file
|
|
with open(main_po_file, 'r', encoding='utf-8') as f:
|
|
main_content = f.read()
|
|
|
|
# Apply translations to main file
|
|
updated_content = main_content
|
|
applied_count = 0
|
|
|
|
for english, arabic in translations.items():
|
|
# Pattern to find msgid followed by empty msgstr
|
|
pattern = rf'(msgid "{re.escape(english)}"\\s*\\nmsgstr) ""'
|
|
replacement = rf'\\1 "{arabic}"'
|
|
|
|
if re.search(pattern, updated_content):
|
|
updated_content = re.sub(pattern, replacement, updated_content)
|
|
applied_count += 1
|
|
print(f"✓ Applied: '{english}' -> '{arabic}'")
|
|
else:
|
|
print(f"✗ Not found: '{english}'")
|
|
|
|
# Write updated content back to main file
|
|
with open(main_po_file, 'w', encoding='utf-8') as f:
|
|
f.write(updated_content)
|
|
|
|
print(f"\\nApplied {applied_count} translations to {main_po_file}")
|
|
return applied_count
|
|
|
|
def main():
|
|
"""Main function to apply all translations"""
|
|
print("Applying all batch translations to main django.po file...")
|
|
applied_count = apply_all_translations()
|
|
|
|
if applied_count > 0:
|
|
print(f"\\n✅ Successfully applied {applied_count} translations!")
|
|
print("Next steps:")
|
|
print("1. Run: python manage.py compilemessages")
|
|
print("2. Test the translations in the application")
|
|
else:
|
|
print("\\n❌ No translations were applied.")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
'''
|
|
|
|
with open("apply_all_translations.py", 'w', encoding='utf-8') as f:
|
|
f.write(script_content)
|
|
|
|
print("Created apply_all_translations.py script")
|
|
|
|
def main():
|
|
"""Main function to process all batches"""
|
|
print("🚀 Starting comprehensive translation process...")
|
|
|
|
# Process all batch files
|
|
all_translations = process_all_batches()
|
|
|
|
print(f"\n📊 Summary:")
|
|
print(f"Total translations found: {len(all_translations)}")
|
|
|
|
if all_translations:
|
|
# Create the application script
|
|
create_translation_script(all_translations)
|
|
|
|
print(f"\n✅ Translation processing complete!")
|
|
print(f"📝 Created apply_all_translations.py with {len(all_translations)} translations")
|
|
print(f"\n🎯 Next steps:")
|
|
print(f"1. Run: python apply_all_translations.py")
|
|
print(f"2. Run: python manage.py compilemessages")
|
|
print(f"3. Test the translations in the application")
|
|
else:
|
|
print("\n❌ No translations found to process.")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|