Discourse Retort

Ich habe eine neue Anfrage Support multiple-reactions per post (Retort style) zu multiple-reactions-per-post eröffnet, da der andere Link nur dazu dient, weitere Reaktionsmöglichkeiten für die einzige Reaktion anzubieten, die Discourse Reactions zulässt.

3 „Gefällt mir“

Das Retort-Plugin ist kein #offizielles Plugin, daher haben wir keinen Einfluss darauf, wann es von der Community nicht mehr aktiv entwickelt und gepflegt wird. :man_shrugging: Das Beste, was wir tun können, ist, die Leute nach Möglichkeit auf dem Laufenden zu halten, damit sie etwas Zeit haben, eine Alternative zu finden (oder zumindest ihre Mitglieder vorzuwarnen, um die Enttäuschung abzumildern).

Hoffentlich werden diese beiden #feature-Anfragen irgendwann in das #reactions-Plugin übernommen, aber bisher sind sie noch im Stadium der ‘nette Ideen’. Aber ich drücke die Daumen. :crossed_fingers:

3 „Gefällt mir“

Ich verstehe, was Sie meinen. Die Realität ist, dass weder ich noch James die Zeit hatten, Retort schon seit einiger Zeit richtig zu unterstützen. Sie werden feststellen, dass der letzte Commit im Repository über ein Jahr alt ist (von mir am 21. Juli 2021). Es ist großartig, dass das Plugin so lange funktioniert hat, und es ist ein Beweis für die Qualität der Arbeit, die James in seine Entwicklung gesteckt hat.

Wenn ich sage, dass ich keine Zeit habe, glauben Sie mir, ich wünschte, ich hätte sie! Ich bin jedes Mal traurig, wenn ich eine dieser Entscheidungen treffen muss (wie beim Landing Pages Plugin). Ich habe Retort nicht entwickelt, aber ich habe Zeit darin investiert. Wenn man sich entscheidet, etwas auszumustern, ist es, als würde man akzeptieren, dass etwas, das man geschaffen oder geliebt hat und mit dem man viele Stunden, Tage und Wochen seines Lebens verbracht hat, sterben muss. Ich weiß, dass es für James eine schwierige Entscheidung war, als er das Gefühl hatte, sich anderen Dingen zuwenden zu müssen.

Im Gegensatz dazu wird das Reactions Plugin von Discourse.org, einer Organisation mit über 60 Mitarbeitern, aktiv gepflegt. Es wird auf einer Reihe von Servern verwendet, die von den Kunden von Discourse.org genutzt werden. Ja, es hat noch nicht die gleichen Funktionen wie Retort, aber ich würde Sie dringend bitten, die Entwicklung dieser Funktion als einen Weg zu verfolgen. Vielleicht könnten Sie jemanden wie mich oder ein anderes Mitglied von Pavilion davon überzeugen, eine fehlende Funktion in das Plugin einzubringen. Das wäre ein kluger Weg, Ihre langfristigen Ziele hier zu erreichen.

7 „Gefällt mir“

Es gibt immer Marketplace, wenn Sie einen Entwickler bezahlen möchten, um es in der Zwischenzeit wiederzubeleben. Aber Sie müssen dies möglicherweise mehrmals tun oder eine Wartungsvereinbarung treffen.

2 „Gefällt mir“

Ich schätze, die Antwort ist Nein? Ich würde gerne zu Reaktionen migrieren und versuchen, die beliebten zu finden…

1 „Gefällt mir“

Ich stelle mir vor, das wäre möglich, da sie irgendwo in der Datenbank gespeichert werden. Leider habe ich dieses Plugin nicht auf meiner Testseite installiert, um die Einzelheiten zu überprüfen. Gibt es eine discourse-retort-retorts-Tabelle oder etwas Ähnliches?

2 „Gefällt mir“

Hier ist, wie Sie eine mit | getrennte Zeichenfolge für die von Ihnen derzeit verwendeten Retorten erhalten:

# ./launcher enter app
# rails c
retorts = {}
PostDetail.where(extra: 'retort').each do |p|
  retort = p.key.split('|').first
  (retorts[retort] ||= []) << p
end
retorts.length
retorts.keys.join('|')

Das gibt Ihnen:

  • Zuerst die Anzahl der verwendeten eindeutigen Retorten-Emojis
  • Dann die Retorten in einem Format, das Sie in die Reaktionskonfiguration einfügen könnten, vielleicht nach dem Kürzen, wenn es für die Reaktions-UI zu lang ist.

Für mich erhalte ich diese Zeichenfolge:

tada|rage|money_with_wings|face_vomiting|crossed_fingers|grin|vulcan_salute|worried|slightly_smiling_face|dart|+1|relaxed|star_struck|upside_down_face|sweat_drops|astonished|frowning_face|champagne|heavy_plus_sign|bulb|joy|fireworks|zap|smile|fast_forward|grinning|clap|sandwich|heart_eyes|rofl|smiley|wave|ice_cream|sob|mortar_board|open_mouth|pray|grimacing|roll_eyes|arrow_right_hook|brain|wink|cry|nerd_face|slight_smile|confused|ok|thinking|it|heart|smirk|sleepy|eyes|disappointed|question|laughing|man_shrugging|drum|shushing_face|herb|man_facepalming|ear|scream|ok_hand|mantelpiece_clock|smiling_face_with_three_hearts|confetti_ball|sunglasses|nose|pirate_flag|neutral_face|sweat_smile|gift|pensive|dark_sunglasses|exclamation|call_me_hand|green_heart|face_with_monocle|blush|boom|hugs|stuck_out_tongue|zipper_mouth_face|slightly_frowning_face|face_with_raised_eyebrow|exploding_head|information_source|sailboat|fire|gun|carousel_horse|sparkles|hearts|pizza|frowning|drooling_face|-1|100|metal|partying_face|four_leaf_clover|grinning_face_with_smiling_eyes|scream_cat|person_shrugging|deciduous_tree|sunflower|see_no_evil|hear_no_evil|speak_no_evil|微笑|top|face_with_peeking_eye|face_with_hand_over_mouth|stethoscope|money_mouth_face

Wenn Sie eine Liste vorhandener Retorten in einen Beitrag in Discourse kopieren möchten, um zu besprechen, welche beim Migrieren zu Reaktionen beibehalten werden sollen, könnten Sie stattdessen Folgendes verwenden:

":" + retorts.keys.join(': :') + ':'

Für mich ist das derzeit diese Sammlung:

:tada: :rage: :money_with_wings: :face_vomiting: :crossed_fingers: :grin: :vulcan_salute: :worried: :slightly_smiling_face: :dart: :+1: :relaxed: :star_struck: :upside_down_face: :sweat_drops: :astonished: :frowning_face: :champagne: :heavy_plus_sign: :bulb: :joy: :fireworks: :zap: :smile: :fast_forward: :grinning: :clap: :sandwich: :heart_eyes: :rofl: :smiley: :wave: :ice_cream: :sob: :mortar_board: :open_mouth: :pray: :grimacing: :roll_eyes: :arrow_right_hook: :brain: :wink: :cry: :nerd_face: :slight_smile: :confused: :ok: :thinking: :it: :heart: :smirk: :sleepy: :eyes: :disappointed: :question: :laughing: :man_shrugging: :drum: :shushing_face: :herb: :man_facepalming: :ear: :scream: :ok_hand: :mantelpiece_clock: :smiling_face_with_three_hearts: :confetti_ball: :sunglasses: :nose: :pirate_flag: :neutral_face: :sweat_smile: :gift: :pensive: :dark_sunglasses: :exclamation: :call_me_hand: :green_heart: :face_with_monocle: :blush: :boom: :hugs: :stuck_out_tongue: :zipper_mouth_face: :slightly_frowning_face: :face_with_raised_eyebrow: :exploding_head: :information_source: :sailboat: :fire: :gun: :carousel_horse: :sparkles: :hearts: :pizza: :frowning: :drooling_face: :-1: :100: :metal: :partying_face: :four_leaf_clover: :grinning_face_with_smiling_eyes: :scream_cat: :person_shrugging: :deciduous_tree: :sunflower: :see_no_evil: :hear_no_evil: :speak_no_evil: :微笑: :top: :face_with_peeking_eye: :face_with_hand_over_mouth: :stethoscope: :money_mouth_face:

Um eine Aufzählungsliste von Emojis mit der Anzahl der Vorkommen jedes einzelnen zu erhalten:

retorts.keys.sort.each do |k|
  puts "* :#{k}: #{retorts[k].length}"
end

Ich werde nicht die gesamte Aufzählungsliste der Emojis einfügen, aber sie beginnt so:

  • :+1: 161
  • :-1: 1
  • :100: 1
  • :arrow_right_hook: 1
  • :astonished: 9
  • :blush: 2
  • :boom: 2
  • :brain: 23
  • :bulb: 3

Wenn Sie jeden Beitrag sehen möchten, der für jedes Emoji existiert:

retorts.keys.sort.each do |k|
  puts "* :#{k}: #{retorts[k].length}"
  retorts[k].each do |r|
    p = Post.find_by(id: r.post_id)
    next if p.nil?
    puts "   * #{p.full_url}"
  end
end

Das ist viel zu lang, um es hier einzufügen!

Was ich nicht weiß, ist, wie ich all – oder einige – dieser Retorten zu Reaktionen migrieren kann. Es gibt keine Erwähnung von Retorten im Reaktions-Plugin, daher tut es dies nicht automatisch. Ich habe 927 Reaktionen mit 116 eindeutigen Emojis, die ich zu Reaktionen migrieren möchte.

Ich gehe davon aus, dass ich mich irgendwann damit befassen muss, vorzugsweise bevor Retort einfach aufhört zu funktionieren; wenn ich die Migration implementiere, werde ich sie hier dokumentieren. Aber zumindest zu wissen, was Sie haben, könnte Ihnen helfen.

6 „Gefällt mir“

Beim Schreiben von experimentellem Code zur Migration von Retort zu Reactions habe ich festgestellt, dass Retorts nicht aktualisiert werden, wenn Benutzernamen geändert werden.

Ich glaube, dass dies bei Reactions nicht der Fall sein wird, da PostActions eine Verbindung zu tatsächlichen Benutzerdatensätzen herstellt, anstatt Benutzernamen in einem JSON-Blob in PostDetail zu speichern.

Generell gilt: Wenn jemand beschließt, Retort zu übernehmen und zu pflegen, sollte er in Erwägung ziehen, von PostDetail zu PostActions zu migrieren, so wie es bei Reactions gemacht wurde.

Ebenso werden gelöschte Beiträge nicht erkannt.

Mein Script framework to rearrange topics and categories hat eine neue Funktion erhalten, die etwas über das Neuanordnen von Themen und Kategorien hinausgeht!

Ich erinnere mich normalerweise daran, Leute zu warnen, dass ich kein Ruby oder Ruby on Rails kann, daher ist mein Code eher eigenwillig als idiomatisch. Aber bisher scheint er in meinen Tests zu funktionieren!

  def migrateRetortToReactions(allowed:, likes: nil, emojimap: nil)
    # migriert, wo möglich, ohne bestehende Likes zu überschreiben
    # dies ist eine zwangsläufig verlustbehaftete Konvertierung und ist nur durch die Reihenfolge von PostDetail konsistent
    # es wird kein Versuch unternommen, einen PostDetail-Datensatz einem anderen vorzuziehen
    emojimap = {} if emojimap.nil?
    allowed.each do |a|
      emojimap[a] = a
    end
    retort = "retort".freeze
    emojiType = "emoji".freeze
    usermap = Hash.new { |hash, username| hash[username] = User.find_by_username(username) }
    postmap = Hash.new { |hash, post_id| hash[post_id] = Post.find(post_id) }
    likeType = PostActionType.where(name_key: "like").pluck(:id).first

    PostDetail.where(extra: retort).each do |pd|
      begin
        p = postmap[pd.post_id]
      rescue
        # PostDetail nicht konsistent WRT Löschung
        $stderr.puts sprintf("Konnte Beitrag nicht finden für %d: %s / %s", pd.post_id, pd.key, pd.value)
        next
      end
      emoji = pd.key.split('|').first
      users = JSON.parse(pd.value)
      users.each do |user|
        u = usermap[user]
        next if u.nil? # geänderter Benutzername oder gelöschter Benutzer hinterlässt verwaiste Retorts
        if likes.include?(emoji)
          pa = PostAction.where(post_id: p.id, user_id: u.id, post_action_type_id: likeType).first
          next unless pa.nil?
          $stderr.puts sprintf("Füge Like für Retort %s für Benutzer %s in %s hinzu", emoji, user, p.url)
          PostActionCreator.create(u, p, :like, created_at: pd.created_at, silent: true)
        elsif emojimap.has_key?(emoji)
          e = emojimap[emoji]
          r = DiscourseReactions::Reaction.where(post_id: p.id, reaction_type: emojiType, reaction_value: e).first_or_create
          ru = DiscourseReactions::ReactionUser.where(user_id: u.id, post_id: p.id).first
          next unless ru.nil?
          $stderr.puts sprintf("Konvertiere Retort %s zu Reaktion %s für Benutzer %s in %s", emoji, e, user, p.url)
          DiscourseReactions::ReactionUser.create(reaction_id: r.id, user_id: u.id, post_id: p.id, created_at: pd.created_at)
        else
          $stderr.puts sprintf("Ignoriere nicht zugeordnete Retort %s für Benutzer %s in %s", emoji, user, p.url)
        end
      end
    end
  end

Ich benutze das von mir erstellte Framework, um eine YAML-Konfiguration bereitzustellen, die so aussieht:

- migrateRetortToReactions:
    allowed:
      - rofl
      - astonished
      - crossed_fingers
      - sob
      - thinking
      - grimacing
      - frowning_face
      - drum
    likes:
      - dart
      - +1
      - joy
      - "100"
      - brain
      - heart
      - heart_eyes
      - hearts
    emojimap:
      rage: sob
      four_leaf_clover: crossed_fingers
      cry: sob
      open_mouth: astonished
      scream: frowning_face

Sie könnten das aber auch einfach in ein Ruby-Skript packen, einschließlich der Umwandlung dieser Argumente in literalen Ruby-Code, es in das Verzeichnis script/ legen und ausführen.

2 „Gefällt mir“

Hallo Leute, wie oben im Thema besprochen, habe ich bereits eine Migrationsfunktion von Retort zu Reactions geschrieben, einschließlich einer Admin-Oberfläche.

Damit es produktionsreif ist, müssen die Maintainer von Reactions eine kleine Änderung vornehmen, um die Abstraktion des Codes im Reactions-Plugin zu verbessern.

Die Unterstützung einer produktionsreifen Migration zwischen zwei Plugins wie diesem erfordert eine erhebliche Qualitätssicherung, da sonst Probleme wie dieses leicht auftreten können.

4 „Gefällt mir“

Es tut mir leid! Ich habe diese Beiträge übersehen und nur im Hauptzweig nachgesehen. Es ist ein langer Thread…

Ich stimme zu. Ich bin komplett daran vorbeigegangen. Es ist mehr als nur ReactionManager.toggle! – es muss wirklich created_at übergeben, nicht wahr?

Die Umstellung auf Reactions ändert die Semantik von „Gefällt mir“ wirklich, da man sie nicht zurücknehmen kann, wenn jemand seinen Beitrag bearbeitet. Ich hätte nicht die gleiche Implementierungsentscheidung getroffen. :frowning:

Auf jeden Fall möchte ich dies von einem Skript aus steuern, und ich habe keinerlei Interesse daran, es von einer Benutzeroberfläche aus zu steuern. Ich bin nicht die Zielgruppe für die Benutzeroberfläche, also schadet mein Hack vielleicht nicht.

1 „Gefällt mir“

Ich wollte Sie keineswegs davon abhalten, es für Ihre eigenen Zwecke zu schreiben, aber ich würde anderen Websites nicht raten, es zu verwenden, es sei denn, sie sind mit dem Code und der Datenstruktur vertraut.

Letztendlich ist das Reactions Plugin derzeit nicht so geschrieben, dass es eine stabile Migration ermöglicht, die in verschiedenen Umgebungen zuverlässig funktioniert.

Wenn jemand von Retort zu Reactions migrieren möchte, übernimmt Pavilion dies manuell auf Vertragsbasis (E-Mail an contact@pavilion.tech oder PM an mich). Wenn das Reactions Plugin aktualisiert wird, um verallgemeinerte Migrationen zu ermöglichen, werden wir die Migrationsarbeit abschließen, um diese kostenlos zur Verfügung zu stellen.

2 „Gefällt mir“

Aha. Das beantwortet einige Fragen, die ich hatte. Es ist schwer, 450 Beiträge über 7 Jahre hinweg zu verstehen.

Verstehe ich also richtig, dass das, was „getan werden muss“ (jeder kann seine eigene Definition von „muss“ liefern), darin besteht, Reactions irgendwie zu erweitern, damit es die Migration von Daten besser handhaben kann und auch fehlende Funktionen bereitstellt?

Wie groß ist das in einer groben Schätzung in Stunden oder Dollar?

Dies ist im Großen und Ganzen immer noch korrekt.


Wenn die Möglichkeit für einen PR realistisch besteht, würde ich es wahrscheinlich für eine gute Flasche Rotwein machen. Es ist schließlich Freitagabend.

Aber, um etwas ernster zu werden, worüber wir hier sprechen, ist ein kleiner Refaktor des Reactions-Plugins ReactionManager. Diese Art von Arbeit wird normalerweise nicht über PRs akzeptiert. Es müsste eine Zustimmung der Maintainer von Reactions geben.

Ich glaube, Sie möchten auch sicherstellen, dass die Likes silent sind und created_at für Likes und Reaktionen behandelt wird; andernfalls werden die Benutzer mit Benachrichtigungen von der Migration überflutet. (Ich habe dies auf meiner Testseite für meine eigene Anmeldung gesehen.)

Aus irgendeinem Grund löse ich immer noch das out of love-Maximum an Likes aus, selbst wenn created_by behandelt wird, und ich habe nicht weiter untersucht, da ich alle anderen Benachrichtigungen entfernt habe.

@joffreyjaffeux Gibt es einen Grund, die notwendige Funktionalität für eine saubere Migration nicht bereitzustellen?

Ich bin gerade zu Reactions umgezogen (weil es wohl offiziell ist und so…), möchte aber nicht alle bisherigen Retort-Daten verlieren.

Es tut mir leid, aber aus den oben genannten Gründen ist derzeit keine stabile Migration möglich.

Nun, es ist passiert, ich konnte Discourse wegen des Retort-Plugins nicht aktualisieren.

Dies ist der Datenbankmigrationsfehler, den ich erhalten habe:

could not create unique index "index_post_details_on_post_id_and_key_ccnew_ccnew"                                                 DETAIL:  Key (post_id, key)=(30297, +1|retort) is duplicated.

Ich habe dieses Skript als Basis für meinen eigenen Migrationscode verwendet. Hier ist, was ich getan habe.

  • Um Discourse wieder zum Laufen zu bringen, musste ich die “version” in der Template-.yml-Datei auf einen Commit aus dem Discourse-Repository vor etwa zwei Wochen überschreiben.
  • Erneut erstellen mit dem hinzugefügten Reactions-Plugin, um die Seite wieder hochzufahren.
  • Ich habe das Reactions-Plugin mit denselben Reaktionen wie Retort konfiguriert. Ich verwende keine Reaktion, die als “Like” interpretiert werden könnte.
  • Ich habe das Skript von @mcdanlj etwas modifiziert mit den folgenden Schritten (da ich alle Retorts migrieren wollte und bereits eine 1:1-Zuordnung zwischen Retorts und Reaktionen hatte):
  • Führen Sie ./launcher enter app aus.
  • Führen Sie rails c aus.
  • Fügen Sie Folgendes ein (es scheint, dass die Rails-Konsole den Code mit falschen Zeilenänderungen zurückgibt. Ich habe doppelte Zeilenumbrüche hinzugefügt, aber das hat die Ausgabe nicht wirklich geändert. Wenn jemand jedoch einen Syntaxfehler mit dem folgenden Code erhält, fügen Sie nach jeder Zeile einen zusätzlichen Zeilenumbruch hinzu):
def migrateRetortToReactions()
  retort = "retort".freeze
  emojiType = "emoji".freeze
  usermap = Hash.new { |hash, username| hash[username] = User.find_by_username(username) }
  postmap = Hash.new { |hash, post_id| hash[post_id] = Post.find(post_id) }
  likeType = PostActionType.where(name_key: "like").pluck(:id).first
  PostDetail.where(extra: retort).each do |pd|
    begin
      p = postmap[pd.post_id]
    rescue
      # PostDetail ist nicht konsistent bezüglich Löschung
      $stderr.puts sprintf("Konnte Post für %d nicht finden: %s / %s", pd.post_id, pd.key, pd.value)
      next
    end

    emoji = pd.key.split('|').first
    users = JSON.parse(pd.value)
    users.each do |user|
      u = usermap[user]
      next if u.nil? # Geänderter Benutzername oder gelöschter Benutzer hinterlässt verwaiste Retorts
      e = emoji
      r = DiscourseReactions::Reaction.where(post_id: p.id, reaction_type: emojiType, reaction_value: e).first_or_create
      ru = DiscourseReactions::ReactionUser.where(user_id: u.id, post_id: p.id).first
      next unless ru.nil?
      $stderr.puts sprintf("Konvertiere Retort %s zu Reaction %s für Benutzer %s in %s", emoji, e, user, p.url)
      DiscourseReactions::ReactionUser.create(reaction_id: r.id, user_id: u.id, post_id: p.id, created_at: pd.created_at)
    end
  end
end
  • An diesem Punkt habe ich vorsichtshalber ein Website-Backup erstellt.
  • Führen Sie dann migrateRetortToReactions aus, was eine Weile dauern sollte. Bei mir habe ich keine Probleme gesehen oder erlebt. Nach der Ausführung scheint die Konsole alle geänderten Objekte anzuzeigen. Drücken Sie also q, um zu beenden.
  • Jetzt sollte es auf der Website so sein, dass die Daten korrekt migriert wurden.
  • Als letzten Schritt müssen Sie Folgendes ausführen: PostDetail.where(extra: "retort").destroy_all, wodurch die Retort-Daten gelöscht werden.
  • Jetzt konnte ich meine Seite mit der neuesten Discourse-Version und ohne das Retort-Plugin neu erstellen.

Alles in allem nicht so schwierig zu migrieren, aber es war ziemlich beängstigend, und wie bereits besprochen, überschreibt dies Likes mit Reaktionen auf Posts, die sowohl Likes als auch Retorts vom selben Benutzer hatten.

6 „Gefällt mir“

Einverstanden! Mehrere Reaktionen und die Möglichkeit, aus allen Reaktionen auszuwählen, sind ein Muss für meine Community. Die Leute haben es von der Discord-Chatserver-Welt erwartet, daher ist es für meine Community keine Option, diese Funktion rückgängig zu machen. Glücklicherweise ist dieses Plugin für mich noch nicht kaputtgegangen, aber ich habe mich mit der Realität abgefunden, dass ich langsam die Tage zähle. Ich hoffe, dass die gewünschte Lösung entweder von der Drittanbieter-Community oder von Discourse offiziell in den nächsten sechs Monaten kommt. Andernfalls wäre ich gezwungen, mein Forum auf einer älteren Build-Version auf unbestimmte Zeit zu halten, falls sich herausstellt, dass dieses Plugin Updates in Zukunft bricht.

1 „Gefällt mir“

Mit den neuen Ember 5-Änderungen ist Retort nun tot. Erkundung von Optionen zur Erhaltung seiner Funktionalität.

1 „Gefällt mir“