Discourseサイトを2つ1つにマージする

{“content”: “\u003cdiv data-theme-toc="true"\u003e \u003c/div\u003e\n\n2つのDiscourseサイトを1つにまとめたい場合、このガイドはあなたのためです。\n\ndiscourse_mergerというツールがあり、1つのDiscourseサイトを別のサイトにマージできます。\n\n# 前提条件\n\nこれは簡単な作業ではなく、Discourseへの他の移行と同じように扱う必要があります。discourse_mergerを本番稼働中のサイトで実行することはありません。マージは、結果を本番環境に移行する前に確認できる別の環境で実行します。\n\n### コピー vs マージ\n\nほぼすべてが一方のサイトから他方のサイトへコピーされますが、カテゴリとユーザーはマージして重複を防ぐことができます。\n\n* 両方のサイトのユーザーが同じメールアドレスを持っている場合、ユーザーはマージされます。\n* 名前が同じ場合、カテゴリはマージされます。\n\nデータの再編成を行いたい場合は、マージ前にそれを実行してください。\n\n### 宛先サイトの選択\n\nデータの宛先となるサイトを選択します。このサイトがすべてのスタイルと設定を保持します。もう一方のサイトのユーザー、カテゴリ、トピック、投稿、アップロードなどが、宛先サイトにコピー/マージされます。\n\n# 手順\n\n両方のサイトのファイルを含むバックアップを取得し、マージを実行する環境にコピーします。これらは異なるバージョンのDiscourseからのものである可能性があるため、同じバージョンにする必要があります。マージを実行する際は、最新バージョンのDiscourseを使用することをお勧めします。\n\n宛先サイトをマージ環境にリストアします。コマンドラインから行う場合:\n\n\nbundle exec ruby script/discourse restore destination-2018-08-02-134227-v2018xxx.tar.gz\n\n\n次に、もう一方のサイトを展開します。\n\n\ncd /path/to/data\ntar xvzf other-2018-08-02-134227-v2018xxx.tar.gz\n\n\n出力には、データベースダンプとアップロードファイルが含まれます。\n\nデータでデータベースを作成します。\n\n\npsql\nCREATE DATABASE \"copyme\" ENCODING = 'utf8';\n\\q\ngunzip \u003c /path/to/data/other-2018-08-02-134227-v2018xxx.tar.gz | psql -d copyme\n\n\n公式Dockerコンテナ(推奨)でインポートを実行する場合、スクリプトがデータベースにアクセスできるようにpostgresユーザーのパスワードをリセットする必要があります。そうしないと、postgresユーザーがデータベースにアクセスできないというエラーが発生する可能性があります。\n\nパスワードを変更するには:\n\nsudo -u postgres psql\n\\password postgres\n(新しいパスワードを入力)\n\\q\n\n\nこれでスクリプトを実行する準備が整いました。設定する環境変数の一部:\n\nDB_NAME: マージされる宛先サイトのデータベース名。\nDB_HOST: (オプション) マージされるデータベースのホスト名。ローカルの場合は空白のままにします。\nDB_PASS: データベースにアクセスするためのpostgresユーザーのパスワード\nUPLOADS_PATH: 「original」ディレクトリと「optimized」ディレクトリを含むディレクトリの絶対パス(マージされるサイトのもの)。例: /path/to/data/uploads/default\nSOURCE_BASE_URL: マージされるサイトのベースURL。例: https://meta.discourse.org\nSOURCE_CDN: (オプション) マージされるサイトのCDNのベースURL。\n\nインポートスクリプトを実行する前に、エラーを避けるためにバンドルインストールが必要になる場合があります。これを行うには:\n\nsu discourse -c 'bundle config set --local with generic_import \u0026\u0026 bundle install'\n\n\n最初の実行時には、インポートスクリプトで必要なgemのために追加の依存関係をインストールする必要がある場合があります。\n\nバンドルが完了したら、インポートを実行します。\n\n\nsu discourse -c 'DB_NAME=copyme DB_PASS=password SOURCE_BASE_URL=http://copy.othersite.com UPLOADS_PATH=/shared/import/data/uploads/default bundle exec ruby script/bulk_import/discourse_merger.rb'\n\n\n\n完了したら、Webブラウザで結果を確認します。\n\n古いフォーラムからのリンクを更新するには、remapツールを使用できます。\n\n\nbundle exec ruby script/discourse remap 'copy.othersite.com' 'hot.newsite.com'\n\n\nまた、アップロードを含むすべての投稿を再ベイクします。\n\n\nrake posts:rebake_match[\"upload:\"]\n\n\nすべて問題ないように見えたら、結果のバックアップを取得し、本番サーバーにリストアします。\n\n\nbundle exec ruby script/discourse backup\n”}

「いいね!」 45

動作しているようですが、バックアップを実行すると以下のようなエラーが発生します。

pg_dump: error: query failed: ERROR:  permission denied for table migration_mappings

これは非常に奇妙です。

編集:以下で解決しました。

ALTER USER discourse WITH SUPERUSER;
「いいね!」 1

最近これを使った人はいますか?どうでしたか?

また、ユーザーをそれぞれのフォーラムごとに自動的にグループに入れることは可能ですか?(彼らが来たフォーラムのトピックを表示する権限を簡単に付与できるようにするため。)

少し大変でした。いくつかコメントアウトする必要があったと思います。マージ画像にも問題がありました。

新しいサイトのユーザーをすべて何らかのグループに追加しておけば、マージ時にそのグループに属するようにできると思います。マージ後やマージの一部として行うよりも、こちらの方が簡単でしょう。

「いいね!」 2

前回これを実行したとき、マージされたサイトからのアップロードがすべて欠落していました。tar tf backupfile.tar.gz からアップロードのリストを取得し、allfiles.txtx に入れてアップロードディレクトリにコピーしました。このスクリプト(おそらく変更なしでは動作しません)は、それらのファイルのそれぞれに対してアップロードを作成したため、投稿を再ベイクすることで、欠落した画像がすべて(またはほとんど)修正されました。

def process_uploads
  begin
    # ファイル名のリストを読み込む
    filenames = File.readlines('/shared/uploads/allfiles.txt').map(&:strip)
    count = 0

    filenames.each do |filename|
      # ファイル名に /shared を前置する
      filename.gsub!(/\.\//,"")
      full_path = File.join('/shared/uploads/default/original/', filename)

      begin
        # パスが存在し、通常のファイル(ディレクトリではない)であることを確認する
        count += 1
        
        if File.exist?(full_path) && File.file?(full_path)
          # ファイルを開く
          File.open(full_path, 'r') do |tempfile|
            # 指定されたパラメータを使用してアップロードを作成する
            u = UploadCreator.new(tempfile, 'imported', {}).create_for(-1)
            puts "#{count} -- #{u.id}: #{u.url}"
          end
        else
          puts "警告: パスが見つからないか、通常のファイルではありません: #{full_path}"
        end
      rescue => e
        puts "ファイル #{full_path} の処理中にエラーが発生しました: #{e.message}"
        # 現在のファイルが失敗しても、次のファイルに進む
        next
      end
    end
  rescue Errno::ENOENT
    puts "エラー: files.txt が見つかりませんでした"
  rescue => e
    puts "files.txt の読み取り中にエラーが発生しました: #{e.message}"
  end
end

# 処理を実行する
process_uploads;

次のように、悪い投稿を取得しました。

 bad=Post.where("cooked like '%/images/transparent.png%'")

そして、再ベイクが必要であることをマークするためにこれを使用しました。

bad.update_all(baked_version: nil)

私は性急だったので、これを使用しました。

rake posts:rebake_uncooked_posts

それらを再ベイクするために。

「いいね!」 2

マージしたいディスコースフォーラムを XenForo に変換する方が簡単な場合があります(インポーターは通常優れているため)。その後、マージしたい他のフォーラム(vBulletin から XenForo に変換される)とマージし、最後に新しいマージされた XenForo フォーラムをディスコースにインポートします。