カテゴリページでの奇妙なエンコードの問題

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 で見たものは、私の Docker 化されたインストールでも同様でした(まあ、エンコードが正しいという最終結果は同じでした :))。

ありがとうございます!

You can easily check with:

○ → 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セットアップの使用に他の複雑さを加えることになるでしょう(私の理解では)。

そのため、最終的には、問題を適切な場所に報告できるように、2つのサンドボックスを設定しました。残念ながら、それは、私たちが構築した方法に問題がある場合、標準のDockerベースのインストールと何が違うのかを突き止めなければならないことを意味します。

彼らが「Discourseの方法」はクレイジーだと考えており、すべてを1つの統合システムの下で管理したいと思っていることは理解しています。

しかし。最後に私が担当したクライアントは、お気に入りのツールを使用することに固執した結果、Discourse.orgホスティングに移行するための実用的なバックアップを取得するために、私に20時間近くの作業費用を支払うことになりました。その前のクライアントは、サイトが週に数回クラッシュするのを防ぐためにカスタムセットアップを調整するためにさらに多くの費用を支払い、1年後には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 gem(Rubyコードであると確信しています)が正しくビルドされているかを確認する必要があるかがわかります。

「いいね!」 2

抜粋機能に固有の問題のようです。検索結果ページでも同様の問題が発生していることに気づきました。

(例として)

テキストは次のとおりです。

「共有」ボタンが見つかりません。

これは、ユーザー(panorain)への返信で私が引用したものです。偶然見つけました。自分のアクティビティを見ようとすると、サーバーエラー500が発生し、「/logs」からの出力には、lib/excerpt_parser.rb で「入力文字列は空にできません」という実行時エラーが表示されます。

いくつかの問題が抜粋処理の何かに起因しているようですが、開発環境でのみ発生しています。

Dockerベースのインストールでは、エラーなしでアクティビティを表示できます。ただし、奇妙なことに、そのインストールのデータベースは、問題が存在する最近の本番サーバーバックアップから復元されています。

「いいね!」 2

nokogiri を 1.17.2 にアップグレードしたようですが、Docker 化されたバージョンは 1.16.7 です。これが問題の原因だと疑っています。そのアップデート(および同時に更新されたものすべて)を元に戻すことを検討します。

パッケージをダウングレードして Nokogiri 1.16 を再度使用するようにしました。理解できないのは、Gem を更新してパッケージの重複を減らすたびに、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!",

ご覧のとおり、正しいテキストが 2 回ありますが、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) からタイトルを抽出するために使用されます。このコードパスに精通しているわけではありませんが、これが問題の原因である可能性は低いと思われます。

もし別のこと (例: カスタムプラグインでこの関数を使用している) を行っている場合、そこでのエンコーディングパラメータは、取得されたリソースの 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)

したがって、応答している Web サーバーが誤った content-type を報告していると疑われるでしょう。

なぜなら、そのパッチ内の他のすべての呼び出しには encoding: parameters が指定されているからです。

retrieve title 内の呼び出しだけが指定されておらず、一貫性がなく、UTF-8エンコーディングを適切に処理していなかったことが、このスレッドにつながった議論全体でした。

ああ:

は、次の省略形です。

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

そこでUTF8を強制すると、Webサーバーからの非UTF8応答の解析が壊れます。

明確化ありがとうございます。3.4.0 のパッケージングに戻ります。