Seltsames Kodierungsproblem auf der Kategorieseite

Ich versuche, ein seltsames Problem bei einer nicht-dockerisierten Installation zu finden (mir ist bewusst, dass die Unterstützung für diese Art von Installation begrenzt/nicht vorhanden ist, daher suche ich nur nach Hinweisen, was hier falsch sein könnte – unser internes Paketteam hat die Anweisungen für den ‘Entwickler-Build’ verwendet, um die notwendigen Pakete zu erstellen). Ich konnte bestätigen, dass das Problem spezifisch für unsere Installationsmethode ist – mein Infrastrukturteam ist nicht bereit, eine dockerisierte Installation zu verwenden (sie ziehen es vor, alles selbst zu bauen), daher betreibe ich Sandbox-Instanzen, die dockerisiert und nicht-dockerisiert sind und eine Kopie unserer Datenbank enthalten, um zu überprüfen, wo ein Problem liegt, und dies ist definitiv ein Artefakt der Art und Weise, wie wir unser Setup installiert haben.

Beim Upgrade von 3.3.2 auf 3.3.3 bemerkten einige unserer nicht-englischen Forenmitarbeiter, dass der “Über uns”-Text für Abschnitte, die Akzentzeichen verwenden, nicht korrekt kodiert ist:

Interessanterweise sehen wir, dass die Überschrift sowie alle anderen Texte korrekt kodiert sind. Tatsächlich ist die Nachricht selbst, die für die “Über uns”-Nachricht verwendet wird, korrekt kodiert:

Ich habe bestätigt, dass es sich um denselben Text handelt, indem ich ihn bearbeitet und die Änderung auf der Kategorienseite gesehen habe.

Es handelt sich also um etwas Spezifisches für die Darstellung dieses Textes auf der Kategorienseite.

Wenn ich document.characterSet in meinem Browser betrachte, wird es korrekt als UTF-8 identifiziert. Die Datenbank zeigt ebenfalls das Format als UTF-8 an.

Ich frage mich, ob mir jemand Hinweise geben kann, was bei der Darstellung dieses Textes auf der Kategorienseite anders ist. Ich vermute, dass es sich um ein Ruby-Paket handelt, das nicht richtig kompiliert wurde (möglicherweise fehlt die UTF-8-Unterstützung), das bei der Darstellung dieses Textes, aber nicht bei anderen Texten im System verwendet wird, oder um etwas, das den “Über uns”-Nachrichtentext verarbeitet und ihn kürzt (was hier der Fall ist; wir haben jedoch auch einen Link zu einem externen französischen Forum, der eine nicht gekürzte Nachricht ist, aber ich vermute, dass er immer noch vom selben Code verarbeitet wird).

Vielen Dank für jeden Hinweis. Ich bin hier etwas ratlos.

Ich sehe, dass es manchmal korrekt ist:

Wenn man eine rohe categories.json zieht, zeigt sich, dass sie nur im Auszug falsch ist:

        "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.).",

Wenn man die gleiche Kategorie auf try.discourse.org erstellt und categories.json überprüft, erhält man das richtige Ergebnis:

        "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.).",

Ich bin mir nicht sicher, was der nächste Schritt wäre, um dies auf Ihrer Installation zu verfolgen, aber vielleicht hilft es, sich auf den Codepfad zu konzentrieren, der den Auszug generiert, sowie zu wissen, dass dies durch etwas entstanden ist, das die UTF-8-Kodierung als iso-8859-1 interpretiert.

Ja, das ist meine Vermutung – was auch immer den Auszug generiert, ist wahrscheinlich der richtige Ort. Ich bin nur nicht sicher, wo das im Code selbst ist. Aber zu wissen, dass ich nach dem Begriff „excerpt“ suchen muss, ist definitiv hilfreich – danke!

Es sah für mich so aus, als ob es irgendwann als iso-8859-1 übertragen wurde, daher schätze ich diese Bestätigung auch (ich war mir nicht 100% sicher, dass dies die falsche Kodierung war, die ich sah, aber es schien richtig).

Was Sie auf try.discourse.org gesehen haben, ist dasselbe, was ich auch in meiner Docker-Installation gesehen habe (nun ja, das Endergebnis der korrekten Kodierung :)).

Danke!

Sie können dies leicht überprüfen mit:

○ → 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.).'

Meine Vermutung ist, dass etwas eine Art Caching durchführt. Das ist nicht sehr hilfreich, aber danach würde ich suchen.

Es sei denn, sie hassen Docker einfach, sie können ihre eigenen Images mit discourse_docker erstellen. Dann können sie genau sehen, was passiert, und müssen den Images anderer nicht vertrauen.

Cool, danke dafür.

Ich dachte, das könnte der Fall sein, aber die Änderung der Nachricht führte zu einem Update, daher glaube ich nicht, dass es sich um Caching handelt – es ist etwas, das falsch kodiert wird.

Ich habe ein paar Optionen vorgeschlagen, aber am Ende hat das Infrastrukturteam beschlossen, einfach Pakete zu verwenden, die mit dem Build-Service erstellt wurden. Ich glaube nicht, dass es sich um eine Sache handelt, bei der „wir hassen Docker“ (obwohl Podman wahrscheinlich eher das wäre, was sie verwenden wollen), sondern eher um eine Möglichkeit, die Konfigurationsmanagement-Tools zu verwenden, mit denen sie alles auf die gleiche Weise verwalten. Ein Unikat, das Docker/Podman verwendet, würde zusätzliche Komplexität für die Verwendung des CI/CD-Setups mit sich bringen (zumindest verstehe ich das so).

Daher habe ich letztendlich meine beiden Sandboxes so eingerichtet, dass ich feststellen kann, wo Probleme liegen, damit ich sie an die richtige Stelle melden kann. Leider bedeutet das, dass ich, wenn es sich um etwas handelt, das wir erstellt haben, nachvollziehen muss, was wir anders machen als bei einer Standard-Docker-Installation, damit wir es beheben können.

Ich verstehe, wie sie denken, dass der Discourse-Weg verrückt ist und sie wirklich alles unter einem einheitlichen System verwalten wollen.

Aber. Der letzte Kunde, der darauf bestand, seine bevorzugten Werkzeuge zu verwenden, zahlte mir fast 20 Stunden Arbeit, um ein brauchbares Backup zu erstellen, um zum Hosting von discourse.org zu wechseln. Der davor zahlte noch mehr, um ihr benutzerdefiniertes Setup anzupassen, damit ihre Website nicht mehrmals pro Woche abstürzte, und ein Jahr später zahlte er mir noch mehr, um sie zum Hosting von discourse.org zu wechseln. :slight_smile:

Viel Glück!

3 „Gefällt mir“

Ich weiß den Rat zu schätzen. Die gute Nachricht ist, dass die Backups unseres Prod-Systems in einer Docker-Installation einwandfrei funktionieren (ich habe das getestet), sodass wir gut aufgestellt sind, falls sie sich entscheiden, eine Docker-basierte Installation als den richtigen Weg zu wählen. Wir haben viele Daten (vor ein paar Jahren von vBulletin zu Discourse migriert), und im Allgemeinen hat alles ziemlich gut funktioniert, mit ein paar seltsamen Aussetzern hier und da.

Folglich haben wir viel über die Funktionsweise von Discourse gelernt, also keine schlechte Sache rundum. :slight_smile:

Es sieht so aus, als ob /categories.json ein API-Endpunkt ist und keine statische Datei, die erstellt und dann gelesen wird. Ich denke, das hilft, das Problem auf Ruby oder Javascript zu beschränken. Ich habe gefunden, wo das Schema für diesen Endpunkt ist, aber da ich mit Ruby nicht besonders vertraut bin (ich habe im Laufe der Jahre viel Programmiererfahrung gesammelt, sodass das Lesen der meisten Sprachen für mich kein Problem ist, auch wenn ich sie nicht programmieren kann - ich kann die Essenz ziemlich leicht erfassen), sieht es so aus, als ob das Javascript hauptsächlich im Browser ausgeführt wird und das Ruby auf dem Server ausgeführt wird (obwohl ich bemerke, dass auch nodejs installiert ist, sodass diese Verallgemeinerung möglicherweise nicht wirklich zutrifft).

Wenn ich die Funktion finden kann, die /categories verarbeitet (da es so aussieht, als ob .json am Ende dem Code nur sagt, wie die Ausgabe formatiert werden soll; ich sehe ein ähnliches Verhalten in /top vs /top.rss, zum Beispiel), dann sollte das eingrenzen, wo ich im Code suchen muss, und das wird mir sagen, welche Ruby-Gems (ich bin ziemlich sicher, dass es Ruby-Code sein wird) überprüft werden müssen, ob sie richtig kompiliert wurden.

2 „Gefällt mir“

Es scheint etwas Spezifisches für die Auszugsfunktionen zu sein – ich habe gerade bemerkt, dass dies auch auf unseren Suchergebnisseiten passiert:

(zum Beispiel)

Der Text lautet:

Ich sehe keinen „Teilen“-Button.

Was ich selbst in einer Antwort an einen Benutzer (panorain) zitiert habe. Ich bin zufällig darauf gestoßen, da ich beim Versuch, meine eigene Aktivität anzusehen, einen Serverfehler 500 erhalte und die Ausgabe von /logs einen Laufzeitfehler „input string cannot be empty“ in lib/excerpt_parser.rb anzeigt.

Es scheint, dass ein paar Dinge auf etwas in der Auszugsverarbeitung zurückzuführen sind, aber nur in den Installationen im Entwicklungsstil.

In meiner Docker-basierten Installation kann ich meine Aktivität ohne Fehler anzeigen; seltsamerweise ist die Datenbank in dieser Installation jedoch aus einem aktuellen Produktionsserver-Backup wiederhergestellt – wo das Problem besteht.

2 „Gefällt mir“

Es sieht so aus, als hätten wir Nokogiri auf 1.17.2 aktualisiert, und ich sehe, dass die Docker-Version 1.16.7 ist – ich vermute, das ist die Ursache dieses Problems. Ich werde versuchen, dieses Update (und alles andere, was zur gleichen Zeit aktualisiert wurde) rückgängig zu machen.

Ich habe unser Paket also wieder auf Nokogiri 1.16 herabgestuft. Was ich nicht verstehe. Immer wenn ich einen Gem aktualisiere, um doppelte Verpackungen zu reduzieren, prüfe ich, ob es verwandte Änderungen in main gab, es gab keine. Es sei denn, ich habe etwas übersehen

        "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!",

wie Sie sehen können, haben wir den richtigen Text zweimal, nur wenn er durch PrettyText.excerpt läuft, ist er kaputt. Wie wird das in main gehandhabt?

@hendersj Ich bereite bereits ein main-Paket vor, damit wir das mit einer Kopie der DB testen können.

Ich vermute, es wurde in DEV: Update nokogiri to 1.18.1 (#30554) · discourse/discourse@affe26f · GitHub behandelt.

aber ich frage mich … in lib/retrieve_title.rb

doc = Nokogiri.HTML5(html, encoding:)

sollte das nicht sein:

doc = Nokogiri.HTML5(html, encoding: Encoding::UTF_8)
1 „Gefällt mir“

@pfaffman dieser seltsame Code ist auch in der 3.4.0-Version enthalten. :slight_smile:
Könnten Sie prüfen, ob dies wirklich mit einer leeren Codierungseinstellung aufgerufen werden sollte?

Gibt es einen Grund, warum Sie das denken? UTF-8 ist der Standard.

[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

Die Funktion retrieve_title wird verwendet, um Titel von externen URLs (z. B. Youtube) zu extrahieren, und obwohl ich mit diesem Codepfad nicht genau vertraut bin, wäre ich überrascht, wenn dies die Ursache Ihres Problems wäre.

Wenn Sie etwas anderes tun (z. B. diese Funktion in einem benutzerdefinierten Plugin verwenden), stammt der dortige encoding-Parameter vom Content-Type-Header der abgerufenen Ressource:

        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)

da man vermuten könnte, dass der antwortende Webserver einen falschen Content-Type meldet.

da alle anderen Aufrufe in diesem Patch encoding: parameters angegeben haben.

nur der in retrieve title nicht. was inkonsistent erscheint. und die UTF-8-Kodierung nicht richtig zu handhaben, war die gesamte Diskussion, die zu diesem Thread führte.

Ah:

ist eine Kurzform für:

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

UTF8 dort zu erzwingen würde das Parsen von Nicht-UTF8-Antworten von Webservern brechen.

Vielen Dank für die Klarstellung. Zurück zum Verpacken von 3.4.0.