مشكلة تشفير غريبة في صفحة التصنيفات

أحاول تتبع مشكلة غريبة في تثبيت غير مُعتمد على Docker (أدرك أن الدعم لهذا النوع من التثبيت محدود/غير موجود، لذا أبحث فقط عن بعض الإرشادات حول ما قد يكون خاطئًا هنا - استخدم فريق التعبئة الداخلي لدينا تعليمات “بناء المطور” لمعرفة كيفية بناء الحزم اللازمة). لقد تمكنت من التأكد من أن المشكلة خاصة بالطريقة التي قمنا بها بالتثبيت - فريق البنية التحتية لدي غير مستعد لاستخدام تثبيت مُعتمد على Docker (يفضلون بناء كل شيء بأنفسهم)، لذا أقوم بتشغيل مثيلات معزولة مُعتمدة على Docker وغير مُعتمدة على Docker مع نسخة من قاعدة بياناتنا للتحقق من مكان وجود مشكلة، وهذا بالتأكيد نتيجة للطريقة التي قمنا بها بتثبيت إعداداتنا.

عند الترقية من 3.3.2 إلى 3.3.3، لاحظ بعض موظفي المنتدى غير الناطقين باللغة الإنجليزية أن نص “حول” الأقسام التي تستخدم أحرفًا مشددة لم يتم ترميزها بشكل صحيح:

ومن المثير للاهتمام، يمكننا أن نرى أن العنوان وجميع النصوص الأخرى مرمزة بشكل صحيح. في الواقع، الرسالة نفسها المستخدمة لرسالة “حول” مرمزة بشكل صحيح:

لقد تأكدت من أن هذا هو نفس النص عن طريق تحريره ورؤية التغيير في صفحة الفئات.

لذا، فهذا شيء خاص بعرض هذا النص في صفحة الفئات.

بالنظر إلى document.characterSet في متصفحي، فقد تم التعرف عليه بشكل صحيح على أنه UTF-8. تعرض قاعدة البيانات أيضًا التنسيق على أنه UTF-8.

أتساءل عما إذا كان بإمكان أي شخص أن يشير لي إلى ما هو مختلف حول كيفية عرض هذا النص في صفحة الفئات. تخميني هو أنه حزمة Ruby معينة لم يتم بناؤها بشكل صحيح (ربما تفتقر إلى دعم UTF-8) والتي تُستخدم في عرض هذا النص وليس النص الآخر في النظام، أو شيء يعالج نص رسالة “حول” ويقوم باقتطاعه (وهو ما لاحظت أنه يحدث هنا؛ ومع ذلك، لدينا أيضًا رابط إلى منتدى فرنسي خارجي وهو رسالة غير مقتطعة، لكنني أخمن أنه لا يزال يتم تقييمه بواسطة نفس الكود).

شكرًا لأي إرشادات. أنا في حيرة من أمري هنا.

أرى أنها صحيحة في بعض الأحيان:

سحب ملف categories.json الخام يظهر أنه خاطئ فقط في المقتطف:

        "description": "Esta sección del Foro se dedica a las personas usuarias de openSUSE que forman parte de la comunidad lingüística castellana, de tal forma que dichas personas puedan consultar y participar en el foro en dicha lengua (sea el dialecto español o cualquiera de las variedades latinoamericanas, etc.).",
        "description_text": "Esta sección del Foro se dedica a las personas usuarias de openSUSE que forman parte de la comunidad lingüística castellana, de tal forma que dichas personas puedan consultar y participar en el foro en dicha lengua (sea el dialecto español o cualquiera de las variedades latinoamericanas, etc.).",
        "description_excerpt": "Esta sección del Foro se dedica a las personas usuarias de openSUSE que forman parte de la comunidad lingüística castellana, de tal forma que dichas personas puedan consultar y participar en el foro en dicha lengua (sea el dialecto español o cualquiera de las variedades latinoamericanas, etc.).",

إنشاء نفس الفئة على try.discourse.org والتحقق من categories.json يعطي النتيجة الصحيحة:

        "description": "Esta sección del Foro se dedica a las personas usuarias de openSUSE que forman parte de la comunidad lingüística castellana, de tal forma que dichas personas puedan consultar y participar en el foro en dicha lengua (sea el dialecto español o cualquiera de las variedades latinoamericanas, etc.).",
        "description_text": "Esta sección del Foro se dedica a las personas usuarias de openSUSE que forman parte de la comunidad lingüística castellana, de tal forma que dichas personas puedan consultar y participar en el foro en dicha lengua (sea el dialecto español o cualquiera de las variedades latinoamericanas, etc.).",
        "description_excerpt": "Esta sección del Foro se dedica a las personas usuarias de openSUSE que forman parte de la comunidad lingüística castellana, de tal forma que dichas personas puedan consultar y participar en el foro en dicha lengua (sea el dialecto español o cualquiera de las variedades latinoamericanas, etc.).",

لست متأكدًا من الخطوة التالية في تتبع هذا على تثبيتك، ولكن ربما التركيز على مسار الكود الذي ينشئ المقتطف سيساعد، بالإضافة إلى معرفة أن هذا نشأ عن شيء ما يفسر ترميز UTF-8 على أنه iso-8859-1.

نعم، هذا هو تخميني - أيًا كان ما يولد المقتطف هو على الأرجح المكان المناسب. فقط لست متأكدًا من أين يوجد هذا في الكود نفسه. لكن معرفة البحث عن المصطلح “excerpt” مفيد بالتأكيد - شكرًا لك!

لقد بدا لي أنه كان يتم عبر iso-8859-1 في مرحلة ما، لذا أقدر هذا التأكيد أيضًا (لم أكن متأكدًا بنسبة 100٪ من أن هذا هو الترميز الخاطئ الذي كنت أراه، ولكنه بدا صحيحًا).

ما رأيته على try.discourse.org هو ما رأيته في تثبيتي المعبأ في حاويات أيضًا (حسنًا، النتيجة النهائية لكون الترميز صحيحًا :slight_smile: )

شكرًا!

يمكنك التحقق بسهولة باستخدام:

○ → ipython3

In [1]: 'Esta sección del Foro se dedica a las personas usuarias de openSUSE que forman parte de la comunidad lingüística castellana
   ...: , de tal forma que dichas personas puedan consultar y participar en el foro en dicha lengua (sea el dialecto español o cualq
   ...: uiera de las variedades latinoamericanas, etc.).'.encode('utf-8').decode('iso-8859-1')
Out[1]: 'Esta sección del Foro se dedica a las personas usuarias de openSUSE que forman parte de la comunidad lingüÃ\xadstica castellana, de tal forma que dichas personas puedan consultar y participar en el foro en dicha lengua (sea el dialecto español o cualquiera de las variedades latinoamericanas, etc.).'

تخميني هو أن شيئًا ما يقوم بنوع من التخزين المؤقت. هذا ليس مفيدًا جدًا، ولكنه ما سأحاول البحث عنه.

ما لم يكونوا يكرهون Docker، يمكنهم بناء صورهم الخاصة باستخدام discourse_docker. عندها يمكنهم رؤية ما يحدث بالضبط وعدم الاضطرار إلى الوثوق بصور أي شخص آخر.

رائع، شكرًا على ذلك.

اعتقدت أن هذا قد يكون هو الحال، لكن تغيير الرسالة أدى إلى تحديث، لذلك لا أعتقد أنه تخزين مؤقت - إنه شيء يتم ترميزه بشكل غير صحيح.

اقترحت بعض الخيارات، ولكن في النهاية، اختار فريق البنية التحتية المضي قدمًا في استخدام الحزم المبنية باستخدام خدمة البناء. لا أعتقد أن الأمر يتعلق بـ “نحن نكره Docker” (على الرغم من أن podman سيكون على الأرجح أكثر احتمالًا مما يريدون استخدامه)، بل هو طريقة لاستخدام أدوات إدارة التكوين التي يستخدمونها لإدارة كل شيء بنفس الطريقة. إن وجود شيء لمرة واحدة يستخدم Docker/podman سيضيف تعقيدات أخرى لاستخدام إعداد CI/CD الذي يستخدمونه (أو هكذا أفهم).

لذلك في النهاية، قمت بإعداد صندوقي الرمل لتحديد مكان الجذور للمشكلات حتى أتمكن من الإبلاغ عنها في المكان المناسب؛ لسوء الحظ، هذا يعني أنه عندما يكون هناك شيء في كيفية بناء الأشياء، يجب عليّ تتبع ما نفعله بشكل مختلف عن تثبيت Docker القياسي حتى نتمكن من إصلاحه.

أتفهم كيف يعتقدون أن “طريقة Discourse” مجنونة ويريدون حقًا إدارة كل شيء تحت نظام موحد واحد.

لكن. العميل الأخير الذي أصر على استخدام أدواته المفضلة جعلني أدفع ما يقرب من 20 ساعة عمل للحصول على نسخة احتياطية قابلة للاستخدام للانتقال إلى استضافة discourse.org. العميل الذي سبقه دفع أكثر لتعديل إعداده المخصص لمنع تعطل موقعه عدة مرات في الأسبوع، وبعد عام دفع لي المزيد لنقله إلى استضافة discourse.org. :slight_smile:

حظا سعيدا!

3 إعجابات

أقدر النصيحة. الخبر السار هو أن النسخ الاحتياطية من نظام الإنتاج لدينا تعمل بشكل جيد في تثبيت Docker (لقد اختبرت ذلك)، لذلك إذا/عندما يقررون أن استخدام تثبيت يعتمد على Docker هو الطريقة الصحيحة للمضي قدمًا، فسنكون في وضع جيد. لدينا الكثير من البيانات (تم ترحيلها من vBulletin قبل بضع سنوات إلى Discourse)، وبشكل عام، سارت الأمور بشكل جيد، مع بعض المشاكل الغريبة هنا وهناك.

ونتيجة لذلك، فقد تعلمنا الكثير عن كيفية عمل Discourse، لذا فهي ليست فكرة سيئة على الإطلاق. :slight_smile:

يبدو أن /categories.json هو نقطة نهاية لواجهة برمجة التطبيقات (API) بدلاً من ملف ثابت يتم إنشاؤه ثم قراءته، لذلك أعتقد أن هذا يساعد في حصر المشكلة إما في Ruby أو JavaScript. لقد وجدت مكان مخطط هذه النقطة، ولكن نظرًا لأنني لست على دراية كبيرة بـ Ruby (لقد اكتسبت الكثير من الخبرة في لغات البرمجة على مر السنين، لذا فإن قراءة معظم اللغات ليست مشكلة بالنسبة لي حتى لو لم أتمكن من البرمجة بها - يمكنني فهم الفكرة بسهولة)، ولكن يبدو أن JavaScript يتم تنفيذه في الغالب في المتصفح، ويتم تنفيذ Ruby على الخادم (على الرغم من أنني لاحظت أنه تم تثبيت nodejs أيضًا، لذلك قد لا يكون هذا التعميم صحيحًا حقًا).

إذا تمكنت من العثور على الدالة التي تعالج /categories (حيث يبدو أن .json في النهاية يخبر الكود فقط بكيفية تنسيق الإخراج؛ أرى سلوكًا مشابهًا في /top مقابل /top.rss، على سبيل المثال)، فسوف يضيق ذلك نطاق المكان الذي أحتاج إلى البحث فيه في الكود، وسوف يخبرني أي من حزم Ruby (أنا متأكد تمامًا من أنها ستكون كود Ruby) تحتاج إلى التحقق من أنها مبنية بشكل صحيح.

إعجابَين (2)

يبدو أن هناك شيئًا خاصًا بوظائف الاستخراج - لقد لاحظت للتو أن هذا يحدث أيضًا في صفحات نتائج البحث الخاصة بنا:

(على سبيل المثال)

النص هو:

لا أرى زر “مشاركة”.

وهو شيء اقتبسته في رد على مستخدم (panorain) بنفسي. صادفت هذا عن طريق الخطأ، حيث أن محاولة النظر إلى نشاطي الخاص، أحصل على خطأ خادم 500، ويظهر المخرج من /logs خطأ في وقت التشغيل “لا يمكن أن تكون سلسلة الإدخال فارغة” في lib/excerpt_parser.rb.

يبدو أن هناك بعض الأشياء التي تعود إلى شيء ما في معالجة المقتطفات، ولكن فقط في التثبيتات بأسلوب التطوير.

في تثبيتي المستند إلى Docker، يمكنني فعليًا عرض نشاطي دون خطأ؛ الغريب، مع ذلك، قاعدة البيانات في هذا التثبيت مستعادة من نسخة احتياطية حديثة لخادم الإنتاج - حيث توجد المشكلة.

إعجابَين (2)

يبدو أننا قمنا بترقية nokogiri إلى الإصدار 1.17.2، وأرى أن الإصدار المعبأ في حاويات هو 1.16.7 - أشك في أن هذا هو سبب هذه المشكلة. سأقوم بالرجوع عن هذا التحديث (وأي شيء آخر تم تحديثه في نفس الوقت).

لذلك قمت بترقية حزمتنا لاستخدام nokogiri 1.16 مرة أخرى. ما لا أفهمه. كلما قمت بترقية جوهرة لتقليل التعبئة المكررة، أتحقق مما إذا كانت هناك تغييرات ذات صلة في main لم تكن هناك أي تغييرات. إلا إذا فاتني شيء ما

        "description": "Witaj w polskiej sekcji społeczności openSUSE!",
        "description_text": "Witaj w polskiej sekcji społeczności openSUSE!",
        "description_excerpt": "Witaj w polskiej sekcji społeczności openSUSE!",

كما ترى، لدينا النص الصحيح مرتين، فقط عندما يمر عبر PrettyText.excerpt يكون معطلاً. كيف يتم التعامل مع ذلك في main؟

@hendersj أنا بالفعل أجهز حزمة main حتى نتمكن من اختبار ذلك بنسخة من قاعدة البيانات.

أعتقد أنه تم التعامل معها في DEV: Update nokogiri to 1.18.1 (#30554) · discourse/discourse@affe26f · GitHub

لكنني أتساءل … في lib/retrieve_title.rb

doc = Nokogiri.HTML5(html, encoding:)

ألا ينبغي أن يكون هذا:

doc = Nokogiri.HTML5(html, encoding: Encoding::UTF_8)
إعجاب واحد (1)

@pfaffman هذا الرمز الغريب موجود أيضًا في الإصدار 3.4.0. :slight_smile:
هل يمكنك التحقق مما إذا كان يجب استدعاؤه بالفعل مع تعيين ترميز فارغ؟

هل هناك سبب تعتقد ذلك؟ UTF-8 هو الافتراضي.

[1] pry(main)> Nokogiri::VERSION
=> "1.18.2"

[2] pry(main)> t = '<div>Witaj w polskiej sekcji społeczności openSUSE!</div>'
=> "<div>Witaj w polskiej sekcji społeczności openSUSE!</div>"

[3] pry(main)> Nokogiri.HTML5(t).to_s
=> "<html><head></head><body><div>Witaj w polskiej sekcji społeczności openSUSE!</div></body></html>"

[4] pry(main)> Nokogiri.HTML5(t, encoding: Encoding::UTF_8).to_s
=> "<html><head></head><body><div>Witaj w polskiej sekcji społeczności openSUSE!</div></body></html>"

[5] pry(main)> Nokogiri.HTML5(t).to_s == Nokogiri.HTML5(t, encoding: Encoding::UTF_8).to_s
=> true

تُستخدم الدالة retrieve_title لاستخراج العناوين من عناوين URL الخارجية (مثل Youtube) وعلى الرغم من أنني لست على دراية تامة بمسار التعليمات البرمجية هذا، إلا أنني سأندهش إذا وجدت أن هذا هو مصدر مشكلتك.

إذا كنت تفعل شيئًا آخر (على سبيل المثال، استخدام هذه الدالة في مكون إضافي مخصص) فإن المعلمة encoding هناك تأتي من رأس content-type للمورد الذي تم جلبه:

        if !encoding && content_type = _response["content-type"]&.strip&.downcase
          if content_type =~ /charset="?([a-z0-9_-]+)"?/
            encoding = Regexp.last_match(1)
            encoding = nil if !Encoding.list.map(&:name).map(&:downcase).include?(encoding)
          end
        end

        max_size = max_chunk_size(uri) * 1024
        title = extract_title(current, encoding)

لذلك يمكن للمرء أن يشك في أن خادم الويب المستجيب يبلغ عن نوع محتوى غير صحيح.

لأن جميع الاستدعاءات الأخرى في تلك الرقعة تحتوي على encoding: parameters محددة.

فقط الاستدعاء الموجود في retrieve title لا يحتوي عليها. وهذا يبدو غير متسق. وكان عدم التعامل مع ترميز UTF-8 بشكل صحيح هو محور المناقشة التي أدت إلى هذا الموضوع.

آه:

هو اختصار لـ:

doc = Nokogiri.HTML5(html, encoding: encoding)

فرض UTF8 هناك سيكسر تحليل الاستجابات غير UTF8 من خوادم الويب

شكراً للتوضيح. بالعودة إلى حزمة 3.4.0.