# Discourse Retort

**URL:** https://meta.discourse.org/t/discourse-retort/35903
**Category:** Plugin
**Tags:** end-of-life
**Created:** [11월 22, 2015, 11:53오전 UTC](https://meta.discourse.org/t/discourse-retort/35903 "2015-11-22T11:53:58Z")
**Posts on this page:** 1
**Showing post:** 468

<div class="post-metadata">

### Author: ![mcdanlj](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mcdanlj/32/131829_2.png) [@mcdanlj](https://meta.discourse.org/u/mcdanlj)
#### Post date: [10월 27, 2022, 4:07오전 UTC](https://meta.discourse.org/t/discourse-retort/35903/468 "2022-10-27T04:07:41Z")

</div>

제가 만든 [Script framework to rearrange topics and categories](https://meta.discourse.org/t/script-framework-to-rearrange-topics-and-categories/241964?u=mcdanlj) 프레임워크에 토픽과 카테고리 재배열을 약간 벗어나는 새로운 기능이 추가되었습니다!

보통 저는 Ruby나 Ruby on Rails를 잘 알지 못한다고 경고하곤 하는데, 그래서 제 코드는 관용적(idiomatic)이라기보다는 특이(idiosyncratic)한 편입니다. 하지만 지금까지 테스트해 본 결과 잘 작동하고 있습니다!

```ruby
  def migrateRetortToReactions(allowed:, likes: nil, emojimap: nil)
    # 기존 좋아요를 덮어쓰지 않고 가능한 한 마이그레이션 수행
    # 이는 필연적으로 손실이 있는 변환이며, PostDetail의 순서에 의해만 일관성이 유지됨
    # 한 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 설정을 제공합니다:

```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/ 디렉터리에 배치하여 실행하는 것도 가능합니다.

---

_[View the full topic](https://meta.discourse.org/t/discourse-retort/35903)._
