Discourse Retort

複数のリアクションを投稿ごとに許可することについて、新しいリクエスト Support multiple-reactions per post (Retort style) を作成しました。なぜなら、他のリンクはDiscourse Reactionsが許可する唯一のリアクションに対する、より多くのリアクション選択肢を提供するものだからです。

「いいね!」 3

Retortプラグインは#公式なものではないため、コミュニティによって積極的に開発・保守されなくなる時期について、私たちは何も言うことができません。:man_shrugging: 私たちにできる最善のことは、可能な限り人々を情報に通じさせ、代替手段を見つける時間を与える(または少なくともメンバーに失望を和らげるよう知らせる)ことです。

うまくいけば、その2つの#featureリクエストは、いつか#reactionsプラグインに採用されるでしょうが、現時点ではまだ「良いアイデア」の段階です。しかし、私は指をクロスさせています。:crossed_fingers:

「いいね!」 3

おっしゃることは理解できます。現実には、私にもジェームズにも、しばらくの間Retortを適切にサポートする時間がありませんでした。リポジトリの最後のコミットは、1年以上前(2021年7月21日の私によるもの)であることに気づくでしょう。このプラグインがこれほど長く機能し続けているのは素晴らしいことであり、ジェームズが構築した作業の品質の証です。

時間がないと言うとき、信じてください、そう願っています!(Landing Pages Pluginの時のような)これらの決定のいずれかを下さなければならないときは、悲しくなります。Retortは私が構築したものではありませんが、それに時間を投資しました。何かを廃止すると決めることは、あなたが人生の多くの時間、日、週を費やして作成または愛したものが死ななければならないことを受け入れるようなものです。ジェームズが他のことに移らなければならないと感じたときに、それが彼にとってつらい決断であったことはわかっています。

対照的に、Reactions Pluginは、60人以上の組織であるDiscourse.orgによって積極的に維持されています。Discourse.orgのクライアントが使用する多くのサーバーで使用されています。はい、まだRetortと同じ機能はありませんが、その機能開発を手段として追求することを強くお勧めします。おそらく、私のような人物、またはPavilionの他のメンバーに、プラグインに不足している機能をPRするように説得できるかもしれません。それは、ここで長期的な目標を達成するための賢明な道となるでしょう。

「いいね!」 7

それまでの間、開発者に復活させるために支払いたい場合は、常に#marketplaceがあります。ただし、これを複数回行うか、保守契約に同意する必要がある場合があります。

「いいね!」 2

答えは「いいえ」だと思いますか? 反応に移行して、人気のあるものをいくつか見つけたいのですが…

「いいね!」 1

データベースのどこかに保存されているため、可能だと思います。残念ながら、テストサイトにこのプラグインがインストールされていないため、詳細を確認できません。discourse-retort-retorts テーブルのようなものはありますか?

「いいね!」 2

現在使用中のリアクションの「|」区切り文字列を取得する方法は次のとおりです。

# ./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('|')

これにより、次のものが得られます。

  • まず、使用されているユニークなリアクション絵文字の数
  • 次に、リアクションの設定に貼り付けられる形式のリアクション。リアクションUIで機能するには長すぎる場合は、トリミングが必要になる場合があります。

私の場合、この文字列が得られます。

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

Discourseの投稿に既存のリアクションのリストをコピーして、リアクションへの移行時に何を残すかを議論したい場合は、代わりにこれを使用できます。

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

私の場合、それは現在このセットです。

: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:

各絵文字のインスタンス数とともに絵文字の箇条書きリストを取得するには:

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

絵文字の箇条書きリスト全体は貼り付けませんが、次のように始まります。

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

各絵文字のすべての投稿を確認したい場合:

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

それはここに貼り付けるには長すぎます!

私が知らないのは、それらのリアクションのすべてまたは一部をリアクションに移行する方法です。リアクションプラグインにはリアクションの言及がないため、自動的には行われません。116個のユニークな絵文字を持つ927個のリアクションがあり、それらをリアクションに移行したいと考えています。

いつかこれに対処することになるでしょう。できれば、リアクションが動作しなくなる前に。移行を実装する場合は、ここに文書化する予定です。しかし、少なくとも何を持っているかを知ることは、あなたを助けるかもしれません。

「いいね!」 6

Retort を Reactions に移行するための実験的なコードを記述している際に、ユーザー名が変更されたときに Retort が更新されないことを発見しました。

これは、PostActions が実際のユーザーレコードに結合されるのに対し、PostDetail の JSON ブロブにユーザー名を記録するのとは対照的に、Reactions では当てはまらないと思います。

一般的に、誰かが Retort を採用して保守することを決定した場合、Reactions の方法に従って PostDetail から PostActions への移行を検討する必要があります。

同様に、投稿が削除されたことも認識しません。

私の Script framework to rearrange topics and categories は、トピックやカテゴリの並べ替えを少し超えた新しい機能を追加しました!

私は通常、RubyやRuby on Railsを知らないことを皆さんに警告するのを忘れないようにしていますが、私のコードは慣用的というよりは独特です。しかし、これまでのテストでは機能しているようです!

  def migrateRetortToReactions(allowed:, likes: nil, emojimap: nil)
    # 既存のいいねを上書きせずに可能な限り移行する
    # これは必然的に情報が失われる変換であり、PostDetailの順序によってのみ一貫性が保たれる
    # 1つのPostDetailレコードを別のレコードよりも優先する試みは行われない
    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が削除と一貫性がない
        $stderr.puts sprintf("Could not find post for %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? # ユーザー名が変更されたか、削除されたユーザーが孤立したRetortを残す
        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("Adding like for Retort %s for user %s in %s", 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("Converting Retort %s to Reaction %s for user %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("Ignoring unmapped Retort %s for user %s in %s", emoji, user, p.url)
        end
      end
    end
  end

私が構築したフレームワークを使用して、次のようなYAML設定を提供しています。

- 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

しかし、それをRubyスクリプトにラップし、それらの引数をリテラルのRubyコードとして含め、script/ディレクトリにドロップして実行することもできます。

「いいね!」 2

皆さん、上記のトピックで話し合ったように、Retort を Reactions に移行する機能と、管理 UI をすでに作成しました。

本番環境で利用可能にするには、Reactions プラグインのコードの抽象化を改善するために、Reactions のメンテナーがわずかな変更を加える必要があります。

このように 2 つのプラグイン間で本番レベルの移行をサポートするには、かなりの品質保証が必要となります。そうしないと、このような問題が容易に発生する可能性があります。

「いいね!」 4

申し訳ありません!それらの投稿を見逃しており、メインブランチのみを見ていました。長いスレッドですね…

同意します。完全に回避していました。ReactionsManager.toggle! だけでなく、created_at を渡す必要もありますよね?

Reactions への移行は、「いいね」の意味を大きく変えます。なぜなら、誰かが投稿を編集したときに元に戻すことができないからです。私は同じ実装の選択をしなかったでしょう。:frowning:

いずれにせよ、私がやりたいのはスクリプトからこれを実行することであり、UI から実行することには全く興味がありません。私は UI のターゲットオーディエンスではないので、私のハックが利用可能であっても害はないかもしれません。

「いいね!」 1

もちろん、あなた自身の目的のためにそれを書くことを思いとどまらせるつもりはありませんでしたが、コードとデータ構造に慣れていない限り、他のサイトがそれを使用することはお勧めしません。

要するに、Reactions Pluginは現在、環境間で確実に機能する安定した移行に適した方法で記述されていません。

誰かがRetortからReactionsに移行したい場合は、Pavilionが契約ベースで手動で処理しています(contact@pavilion.techにメールするか、PMしてください)。Reactions Pluginが一般的な移行を可能にするように更新されれば、これを無料で利用できるように移行作業を完了します。

「いいね!」 2

なるほど。これで疑問がいくつか解消されました。7年間にわたる450件の投稿を理解するのは難しいです。

つまり、「必要」なこと(「必要」の定義は誰でも提供できます)は、Reactions を拡張して、データの移行をよりクリーンに処理できるようにし、また、Reactions が不足している機能を提供できるようにすることだと理解すればよいのでしょうか?

それは、おおよその時間や費用でどれくらいの仕事量になりますか?

これは概ねまだ正確です。


もし PR の機会が現実的にあれば、良い赤ワイン1本くらいでやってもらえるかもしれません。金曜の夜ですしね。

しかし、もう少し真面目に言うと、ここで話しているのは Reactions プラグインの ReactionManager のマイナーリファクタリングです。そのような作業は通常 PR では受け付けられません。Reactions のメンテナーからの承認が必要になります。

いいねがsilentであり、いいねやリアクションのcreated_atが処理されていることを確認したいとも思います。そうしないと、ユーザーは移行からの通知でスパム状態になります。(自分のログインのテストサイトでこれを見ました。)

なぜか、created_byが処理されていても、私はまだout of loveの最大いいねをトリガーします。他のすべての通知を削除したので、それ以上調査しませんでした。

@joffreyjaffeux クリーンな移行に必要な機能を提供しない理由がありますか?

Reactionsに移行したばかりですが(公式になったようですので…)、以前のRetortのデータをすべて失いたくありません。

申し訳ありませんが、上記に述べた理由により、現時点では安定した移行を提供することはできません。

リタートプラグインが原因で Discourse を更新できませんでした。

表示されたデータベース移行エラーは次のとおりです。

一意インデックス "index_post_details_on_post_id_and_key_ccnew_ccnew" を作成できませんでした。 DETAIL: Key (post_id, key)=(30297, +1|retort) は重複しています。

このスクリプトを独自の移行コードのベースとして使用しました。以下に私が実行した手順を示します。

  • Discourse を再び機能させるために、テンプレートの .yml ファイルの「version」を、Discourse リポジトリの約 2 週間前のコミットにオーバーライドする必要がありました。
  • 反応プラグインを追加して再構築し、サイトを復旧させました。
  • リタートと同じ反応セットで反応プラグインを構成しました。いいねと解釈される可能性のある反応は使用していません。
  • @mcdanlj のスクリプトを少し変更して、次の手順で使用しました(すべてのリタートを移行したかったため、リタートと反応の間に 1 対 1 のマッピングがすでにありました)。
  • ./launcher enter app を実行します。
  • rails c を実行します。
  • 次のコードを貼り付けます(Rails コンソールはコードを不正確な行変更でエコーバックするようです。二重の行変更を追加しましたが、出力は実際には変更されませんでした。ただし、次のコードで構文エラーが発生した場合は、各行の後に 1 行追加してください)。
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 が削除と一致しない
      $stderr.puts sprintf("投稿が見つかりませんでした %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? # ユーザー名が変更されたか、削除されたユーザーが孤立したリタートを残す
      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("リタート %s をユーザー %s の投稿 %s のリアクション %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
  • この時点で、念のためサイトのバックアップを作成しました。
  • 次に migrateRetortToReactions を実行します。これには時間がかかるはずです。私の場合、問題は見られず、遭遇しませんでした。コンソールを実行すると、変更されたすべてのオブジェクトが表示されるため、q を押して終了します。
  • これで、サイトのデータが正しく移行されているはずです。
  • 最後のステップとして、PostDetail.where(extra: "retort").destroy_all を実行して、リタートデータを削除する必要があります。
  • これで、最新の Discourse バージョンで、リタートプラグインなしでサイトを再構築できるようになりました。

全体として、移行はそれほど難しくはありませんでしたが、かなり恐ろしいものでした。前述のように、同じユーザーが投稿に「いいね」と「リタート」の両方を行っていた場合、これは「いいね」をリアクションで上書きします。

「いいね!」 6

同意します!複数のリアクションと、すべてのリアクションから選択できることは、私のコミュニティにとって必須です。人々はDiscordチャットサーバーの世界からそれを期待するようになっているため、私のコミュニティでその機能を元に戻すことはできません。幸いなことに、このプラグインはまだ私にとって壊れていませんが、日数を数えているという現実に甘んじています。サードパーティのコミュニティまたはDiscourse公式のどちらからでも、今後6か月以内に望ましい解決策が登場することを願っています。そうでなければ、このプラグインが将来のアップデートを壊すことになった場合、フォーラムを古いビルドバージョンで無期限に保持することを余儀なくされるでしょう。

「いいね!」 1

新しいEmber 5の変更により、Retortはもう使えなくなりました。その機能性を維持するための選択肢を検討中です。

「いいね!」 1