ترجمہ کا نظام: تین ٹیکنالوجیز کا ہائبرڈ طریقہ کار

یہ مضمون ہمارے ترجمہ کے نظام کی وضاحت کرتا ہے جو تین ٹیکنالوجیز کو یکجا کرتا ہے—ٹیمپلیٹس کے لیے Flask-Babel، فریز ٹیبلز کے لیے TranslationManager، اور مواد کے ترجمے کے لیے DeepSeek AI—تاکہ جامع کثیر اللسانی سپورٹ فراہم کی جا سکے۔

مسئلہ: ایک پیچیدہ ویب سائٹ کا ترجمہ کرنا

ہماری ویب سائٹ میں متعدد قسم کے مواد ہیں جن کا ترجمہ درکار ہے:

  • ساکن ٹیمپلیٹس: نیویگیشن، بٹنز، لیبلز (500+ اسٹرنگز)

  • متحرک مواد: مصنوعات کے نام، تفصیلات، خصوصیات (10,000+ اسٹرنگز)

  • صارف سے تخلیق شدہ مواد: جائزے، تبصرے، سپورٹ ٹکٹس

  • تکنیکی اصطلاحات: برانڈ کے نام، SKUs، URLs (ترجمہ نہیں ہونے چاہئیں)

ترجمہ کا ایک واحد طریقہ کار کام نہیں کرتا:

  • مشینی ترجمہ: تیز لیکن تکنیکی اصطلاحات کے لیے غیر درست

  • دستی ترجمہ: درست لیکن سست اور مہنگا

  • صرف ٹیمپلیٹ: متحرک مواد کو ہینڈل نہیں کرتا

ہمیں ایک ہائبرڈ طریقہ کار درکار ہے جو تینوں کے بہترین پہلوؤں کو یکجا کرے۔

ترجمہ کا فن تعمیر

graph TD
    Request[صارف کی درخواست
lang=hi] subgraph Templates Babel[Flask-Babel
.po فائلیں] Static[ساکن اسٹرنگز
بٹن، لیبلز] end subgraph Dynamic TM[TranslationManager
فریز ٹیبلز] Phrases[مصنوعات کے نام
خصوصیات، اصطلاحات] end subgraph AI DS[DeepSeek API
AI ترجمہ] Content[تفصیلات
مضامین، طویل متن] end Request --> Babel Request --> TM Request --> DS Babel --> Static TM --> Phrases DS --> Content Static --> Response[ترجمہ شدہ صفحہ] Phrases --> Response Content --> Response

تین ٹیکنالوجیز

1. Flask-Babel: ٹیمپلیٹ تراجم

Flask-Babel gettext .po فائلوں کا استعمال کرتے ہوئے ساکن ٹیمپلیٹ اسٹرنگز کو ہینڈل کرتا ہے۔

  • استعمال کیس: نیویگیشن، بٹنز، لیبلز، خرابی کے پیغامات

  • مثال:

# Template
{{ _('Add to Cart') }}

# .po file (Hindi)
msgid "Add to Cart"
msgstr "कार्ट में जोड़ें"

فوائد:

  • ✅ معیاری i18n طریقہ کار

  • ✅ ترجمہ کے ٹولز کی سپورٹ (Poedit, Weblate)

  • ✅ کمپائل ٹائم کی توثیق

  • ✅ تیز تلاش (کمپائل شدہ .mo فائلیں)

محدودیتاں:

  • ❌ صرف ساکن اسٹرنگز کے لیے کام کرتا ہے

  • ❌ نئی اسٹرنگز شامل کرنے کے لیے کوڈ میں تبدیلی درکار

  • ❌ متحرک مواد کی سپورٹ نہیں

2. TranslationManager: فریز ٹیبلز

ہمارا مخصوص TranslationManager کلاس JSON فریز ٹیبلز کا استعمال کرتے ہوئے متحرک مواد کو ہینڈل کرتا ہے۔

  • استعمال کیس: مصنوعات کے نام، خصوصیات، تفصیلات، وضاحتیں

  • مثال:

{
  "Mini PC": "मिनी पीसी",
  "Intel N100": "Intel N100",
  "8GB RAM": "8GB RAM",
  "256GB SSD": "256GB SSD"
}

فوائد:

  • ✅ متحرک مواد کی سپورٹ

  • ✅ رن ٹائم اپ ڈیٹس (دوبارہ شروع کرنے کی ضرورت نہیں)

  • ✅ تحفظ کے قواعد (برانڈ کے نام، SKUs)

  • ✅ علاقائی فارمیٹنگ (اعشاریہ علیحدہ کرنے والے)

  • ✅ ترجمہ کی قطار (غائب اسٹرنگز)

محدودیتاں:

  • ❌ دستی فریز مینجمنٹ

  • ❌ مترجمین کے لیے سیاق و سباق نہیں

  • ❌ ابتدائی ترجمہ درکار

3. DeepSeek AI: مواد کا ترجمہ

DeepSeek AI ماڈل طویل مواد کے ترجمے کو ہینڈل کرتا ہے۔

  • استعمال کیس: بلاگ مضامین، مصنوعات کی تفصیلات، مارکیٹنگ کاپی

  • مثال:

prompt = f"Translate to {lang}: {text}"
response = deepseek.generate(prompt)

فوائد:

  • ✅ طویل مواد کو ہینڈل کرتا ہے (1000+ الفاظ)

  • ✅ سیاق و سباق سے آگاہ ترجمہ

  • ✅ قدرتی زبان کا آؤٹ پٹ

  • ✅ بیچ پروسیسنگ

محدودیتاں:

  • ❌ فی ترجمہ API لاگت

  • ❌ انٹرنیٹ کنکشن درکار

  • ❌ تکنیکی اصطلاحات کو غلط ترجمہ کر سکتا ہے

TranslationManager کا فن تعمیر

فریز ٹیبل کی ساخت

فریز ٹیبلز ہر زبان کے لیے JSON فائلوں کے طور پر محفوظ ہیں:

app/shared/translation/phrase_tables/

ہر فائل انگریزی فریزز کو تراجم سے میپ کرتی ہے:

{
  "Mini PC": "मिनी पीसी",
  "Thin Client": "थिन क्लाइंट",
  "Industrial PC": "औद्योगिक पीसी",
  "All-in-One": "ऑल-इन-वन"
}

ترجمہ کی تلاش

get() طریقہ کار کثیر سطحی تلاش انجام دیتا ہے:

1. تحفظ کی چیک:

if self._should_skip_translation(text, lang):
    return text  # برانڈ کے نام، SKUs، URLs کا ترجمہ نہ کریں

2. کوما سپلٹنگ (طویل اسٹرنگز کے لیے):

if len(text) > 150 and "," in text:
    parts = text.split(",")
    return ", ".join(self.get(p, lang) for p in parts)

3. فریز ٹیبل تلاش:

if text in self.phrase_tables[lang]:
    return self.phrase_tables[lang][text]

4. لیگیسی کیشے کی ترقی:

if text_hash in self.legacy_caches[lang]:
    translation = self.legacy_caches[lang][text_hash]
    self.set(text, lang, translation)  # فریز ٹیبل میں ترقی دیں
    return translation

5. قطار میں شامل کریں اگر غائب ہے:

if queue_if_missing:
    self.add_to_queue(text, lang)
return None  # کوئی ترجمہ نہیں ملا

تحفظ کے قواعد

ہم مخصوص مواد کی اقسام کو محفوظ رکھتے ہیں:

برانڈ کے نام:

BRAND_NAMES_PRESERVE = [
    "Thinvent", "Intel", "AMD", "Microsoft", "Ubuntu",
    "Windows", "Linux", "WiFi", "Bluetooth"
]

تکنیکی اصطلاحات:

TECHNICAL_TERMS_PRESERVE = [
    "HDMI", "DisplayPort", "VGA", "USB", "Ethernet",
    "DDR4", "SSD", "NVMe", "PCIe", "SATA"
]

SKUs (پیٹرن پر مبنی):

if not " " in text and text.count("-") >= 2:
    return True  # "Treo-N100-8-256-2H-W6-11P" کو محفوظ رکھیں

URLs:

if text.startswith(("/", "http://", "https://")):
    return True

علاقائی فارمیٹنگ

یورپی لینگویجز (جرمن، فرانسیسی، ہسپانوی) کے لیے، ہم علاقائی فارمیٹنگ لاگو کرتے ہیں:

اعشاریہ علیحدہ کرنے والا:

# English: 34.00
# German:  34,00
text = text.replace(".", ",")

وولٹیج/امپیرج:

# English: 12.5V
# German:  12,5V
text = re.sub(r"(\d+)\.(\d+)V", r"\1,\2V", text)

یہ یقینی بناتا ہے کہ ہر لوکیل کے لیے نمبر صحیح طور پر ڈسپلے ہوں۔

ترجمہ کی قطار

غائب تراجم بیچ پروسیسنگ کے لیے قطار میں ڈالے جاتے ہیں:

[
  {
    "text": "Compact Desktop",
    "lang": "hi",
    "hash": "a1b2c3d4e5f6"
  },
  {
    "text": "Fanless Design",
    "lang": "hi",
    "hash": "f6e5d4c3b2a1"
  }
]

ایک بیک گراؤنڈ اسکرپٹ DeepSeek AI کا استعمال کرتے ہوئے قطار کو پروسیس کرتا ہے:

for item in queue:
    translation = deepseek.translate(item["text"], item["lang"])
    translation_manager.set(item["text"], item["lang"], translation)

فائل لاکنگ

ہم fcntl فائل لاکنگ کا استعمال کرتے ہیں تاکہ ہم وقت سازی لکھائیوں کو روکا جا سکے:

with open(lock_path, "w") as lock_file:
    fcntl.flock(lock_file, fcntl.LOCK_EX)
    try:
        # فریز ٹیبل پڑھیں، ترمیم کریں، لکھیں
        with open(table_path, "r+") as f:
            data = json.load(f)
            data.update(new_translations)
            f.seek(0)
            json.dump(data, f)
            f.truncate()
    finally:
        fcntl.flock(lock_file, fcntl.LOCK_UN)

یہ یقینی بناتا ہے کہ متعدد پروسیسز فریز ٹیبلز کو خراب نہ کریں۔

زبان کی پہچان

ہم یونیکوڈ رینجز اور اسٹاپ ورڈز کا استعمال کرتے ہوئے سرچ کی زبان کی پہچان کرتے ہیں:

یونیکوڈ رینج پہچان

دیوناگری (ہندی، مراٹھی):

if 0x0900 <= ord(char) <= 0x097F:
    return "hi"

بنگالی:

if 0x0980 <= ord(char) <= 0x09FF:
    return "bn"

عربی:

if 0x0600 <= ord(char) <= 0x06FF:
    return "ar"

سیریلیک (روسی):

if 0x0400 <= ord(char) <= 0x04FF:
    return "ru"

CJK (چینی، جاپانی، کوریائی):

if 0x4E00 <= ord(char) <= 0x9FFF:  # Kanji/Hanzi
    has_cjk = True
if 0x3040 <= ord(char) <= 0x30FF:  # Hiragana/Katakana
    return "ja"
if 0xAC00 <= ord(char) <= 0xD7AF:  # Hangul
    return "ko"

اسٹاپ ورڈ پہچان

لاطینی بنیاد والی زبانوں کے لیے، ہم اسٹاپ ورڈز کا استعمال کرتے ہیں:

ہسپانوی:

SPANISH_STOPWORDS = {
    "el", "la", "los", "las", "un", "una", "para", "con",
    "en", "por", "que", "es", "su", "y", "del", "al"
}

فرانسیسی:

FRENCH_STOPWORDS = {
    "le", "la", "les", "des", "du", "un", "une", "pour",
    "avec", "en", "est", "sur", "et", "au", "dans"
}

جرمن:

GERMAN_STOPWORDS = {
    "der", "die", "das", "ein", "eine", "für", "mit",
    "ist", "und", "auf", "den", "dem", "bei", "von"
}

اگر کوئی اسٹاپ ورڈ مماثل ہو، تو ہم وہ زبان لوٹاتے ہیں۔

متحرک زبان کی پہچان

صارفین درج ذیل کے ذریعے زبان کی وضاحت کر سکتے ہیں:

1. URL پیرامیٹر

/p/Treo-N100-8-256-2H-W6-11P?lang=hi

2. کوکی

response.set_cookie("lang", "hi", max_age=31536000)

3. براؤزر Accept-Language ہیڈر

lang = request.accept_languages.best_match(["en", "hi", "es", "fr", "de"])

ترجیح: URL پیرامیٹر > کوکی > Accept-Language > ڈیفالٹ (en)

بازگشتی ترجمہ

ہم نیسٹڈ ڈیٹا ڈھانچے کا بازگشتی ترجمہ کرتے ہیں:

def translate_data(obj, lang):
    if isinstance(obj, dict):
        return {k: translate_data(v, lang) for k, v in obj.items()}
    elif isinstance(obj, list):
        return [translate_data(item, lang) for item in obj]
    elif isinstance(obj, str):
        return self.get(obj, lang) or obj
    return obj

مثال:

data = {
    "title": "Mini PC",
    "features": {
        "RAM": "8GB",
        "Storage": "256GB SSD"
    },
    "price": 25000
}

translated = translate_data(data, "hi")
# نتیجہ:
# {
#     "title": "मिनी पीसी",
#     "features": {
#         "RAM": "8GB",
#         "Storage": "256GB SSD"
#     },
#     "price": 25000
# }

خصوصیات کا ترجمہ

مصنوعات کی خصوصیات کو خصوصی ہینڈلنگ درکار ہے:

```python def translate_features(features, lang): translated = {} for heading, feature_dict in features.items(): # ہیڈنگ کا ترجمہ کریں translated_heading = self.get(heading, lang) or heading

    # خصوصیات کے نام اور قدر کا ترجمہ کریں
    translated_features = {}
    for name, value in feature_dict.items():
        translated_name = self.get