vBulletin 4フォーラムをDiscourseに移行する

こんにちは。私のソリューションを共有したいと思います。
引用符の問題については、前述したように、問題に直面していました。引用符がキャプチャされない正規表現です。

  • ユーザー名と投稿IDは二重引用符で囲むことができます
  • ネストされた引用符

別のロジックを使用して検索と置換を行うことにしました。タグとそのコンテンツを検索するのではなく、タグのみを検索する正規表現を使用しました。

変更前:
raw.gsub!(%r{\\[quote=\"?([^;]+);(\\d+)\"?\\](.+?)\\[\\/quote\\]}im) do

変更後:
raw.gsub!(%r{(\\[QUOTE(=\"?([^;]+);(\\d+)\"?)?\\])|(\\[\\/QUOTE\\])}im) do

そして、引用元の決定を少し変更しました。

      if $3 && $4
        if topic_lookup = topic_lookup_from_imported_post_id(post_id)
          post_number = topic_lookup[:post_number]
          topic_id = topic_lookup[:topic_id]
          "\n[quote=\"#{new_username},post:#{post_number},topic:#{topic_id}\"]\n"
        else
          "\n[quote=\"#{new_username}\"]\n"
        end
      elsif $5
        "\n[/quote]\n"
      end

また、スポイラーのコードも変更しました。代わりに:

    # [spoiler=Some hidden stuff]SPOILER HERE!![/spoiler]
    raw.gsub!(%r{\\[spoiler=\"?(.+?)\"?\\](.+?)\\[/spoiler\\]}im) do
      "\n#{$1}\n[spoiler]#{$2}[/spoiler]\n"
    end

ぼかされたテキストは、detailsタグに変換します。

    raw.gsub!(%r{(\\[spoiler(=\"?(.*?)\"?\\])|(\\[\\/spoiler\\])}im) do
      if $3
        "\n[details=#{$3}]\n"
      elsif $1
        "\n[details]\n"
      elsif $4
        "\n[/details]\n"
      end
    end

vBulletinの世界では、スポイラーはぼかされたコンテンツではなく、折りたたまれたコンテンツであるため、vBulletinインポートスクリプトがスポイラーを詳細に変換する方が適切だと考えられます。

メンションタグにも気づきました。私の場合は、vBulletinではメンションは次のように表示されていました。
[mention=XXX]username[/mention]

スクリプトで使用されている正規表現では、タグにユーザーIDが含まれる可能性があることを考慮していません。

    # [MENTION]<username>[/MENTION]
    raw.gsub!(%r{\\[mention\\](.+?)\\[/mention\\]}i) do
      new_username = get_username_for_old_username($1)
      "@#{new_username}"
    end

これも独自の方法で修正しました。

    # [MENTION]<username>[/MENTION]
    raw.gsub!(%r{\\[mention(=\\d+)?\\](.+?)\\[/mention\\]}i) do
      new_username = get_username_for_old_username($2)
      "@#{new_username}"
    end
「いいね!」 1

これは、24年間運用していたvB 3のvBulletinフォーラムの移行を開始したときには、真実ではありませんでした。スクリプトには複数の非互換性やその他の問題がありました。しかし、vB4のスクリプトに基づいて、vBulletin 3のインポータを作成するために多大な労力を費やしました。

改善されたスクリプトはDiscourseに含まれていますvbulletin3.rbと呼ばれます。vB3インポートスクリプトの使用方法は、このハウツーで説明されているのと同じです。bundle exec ruby script/import_scripts/vbulletin3.rbを実行するだけです。

vBulletin3には、いくつかの重要な変更/改善点があります。

  1. フォーラムの権限がコピーされます
  2. フォーラムモデレーターグループが作成されます
  3. 参加可能なユーザーグループが適切に構成されて作成されます
  4. フォーラムのネストは最大3レベルまでインポートされます(Discourseの最大値)
  5. すべてのスレッドと投稿のパーマリンクが登録され、リンク切れを防ぎます
  6. いくつかの基本的なフォーラム設定がコピーされます(例:タイトル、通知メール、会社名)
  7. 投票がインポートされます
  8. bbcodeからmarkdownへの変換が大幅に改善されました
  9. スレッド、投稿、添付ファイルへのURLディープリンクはDiscourseの参照に変換されます。これには、環境変数FORUM_URLforum.hostname/path(プロトコルなし)に設定する必要があります。

vBulletinのプライベートメッセージをDiscourseのプライベートメッセージに変換しようとする代わりに、ユーザーはプライベートメッセージのアーカイブを含むシステムプライベートメッセージを受け取ります。vBulletinのPM構造は、Discourseと実際には互換性がありません。それを変換しようとすると、人々がvBulletinでPMをどのように使用したかによっては、プライバシーが露呈する可能性もあります。

他のインポータでもおそらくそうであるように、変換にはかなりの時間がかかる場合があります。私のワークステーションでは、7,000人のユーザー、16,000のスレッド、415,000の投稿の変換スクリプトに5.5時間かかりました。投稿処理にどれくらい時間がかかったかはわかりません。一晩実行しました。開始から終了まで、フォーラムは30時間ダウンしていました。最終的には、結果に満足しています。

「いいね!」 2

それは懐かしいですね :slight_smile:

あなたのフォーラムはとても素敵に見えます。トピック行の交互の色が良いですね。

このスレッドとインポーターはどちらも、現時点ではかなり古くなっているようです。このスレッドの助けを借りていくつかの問題を修正しましたが、ユーザーインポートステップで現在行き詰まっています。誰か修正方法を知っていますか?

\u003cinternal:timev\u003e:286:in at’: can’t convert NilClass into an exact number (TypeError)`

クエリが間違っているか、何らかの理由でテーブルに値がない可能性があります

何年も経ってからの返信で奇妙ですが、現在VBインポートをバルクインポーターで行っており、多くの画像が欠落しています。その理由は、添付ファイルのファイル名が別のフィールドに移動されたためです。

 SELECT a.filedataid attachment_id, a.userid user_id, a.filename filename
             FROM attachment a
            WHERE a.attachmentid = 383075;

NUMBER.attach ファイルは、attachment_id フィールドではなく、filedataid フィールドになりました。したがって、そのクエリはスクリプトで更新する必要があります。

vBulletin 4.25 フォーラムを Discourse に移行するように依頼されました…このスレッドを読むと複雑な気持ちになります…可能のようですが、非常に面倒で時間がかかる可能性もあります(どちらも現時点では避けたいことです)…。

vBulletin 4.25 用の更新されたスクリプトはどこかにありますか? 公式ページには 3 と 5 しか見当たらないのですが?

vbulletin および vbulletin5 スクリプトが bulk imports ディレクトリにあり、これらはわずか数ヶ月前のものであることを示しています。これらのバルクインポートの実行は非常に難しく、あまり文書化されていません。

100回以上のインポートを行いましたが、何らかの理由でスクリプトの調整が必要なかったインポートは一度もなかったと確信しています。

Ruby を本格的に学ぶ前にいくつかのインポート スクリプトを作成しました(しかし、1980 年代半ばの教授は、彼のプログラミング言語クラスの後なら、週末と本があればどんな言語でも知っていると言えるだろうと保証してくれました。彼はほとんど正しかったのです)。

しかし、それはあなたが想像しているのと同じくらい、あるいはそれ以上に面倒で時間のかかるものになる可能性が高いです。

vbulletin スクリプトはまともな仕事をしてくれると思いますが、100 万件以上の投稿やユーザーがいない限り、バルクインポート スクリプトはお勧めしないでしょう。

「いいね!」 1

ありがとうございます :slight_smile:
週末に何をしようか決めないといけないですね :smiley:

「いいね!」 1

:face_with_spiral_eyes: これについて、いくつか助けていただけると大変助かります。

スレッドを読み、いくつかステップを踏みましたが、行き詰まっています。

  1. VPSにSSHで接続します。
  2. Dockerイメージに入ります。
  3. mariadb-serverをインストールします。
  4. DBを作成するためにmysqlコマンドを実行しようとしますが、「ローカルサーバーにソケット経由で接続できません」というエラーが出ます。

ここにある指示は数年前のものなので、同じエラーが出た人が数人いるのを見かけましたが、解決策が見つかりません。

最近このプロセスを実行した人がいて、正しい方向を教えていただけますか?何か見落としているステップバイステップのガイドはないでしょうか?

編集:追加情報ですが、いろいろ試した結果、ローカルホスト(Dockerではない)にmariadbのDockerイメージをインストールし、ポートを公開しました。これでDockerイメージからDBに接続できるようになりました…しかし、スクリプトを実行すると、「Gemfile」で「‘mysql2’」という未定義のローカル変数またはメソッドが表示されます。gemfileをインストールしようとしましたが、失敗しました…さらにトラブルシューティングする前に、古い情報や古いパッケージを使っているような気がします…非常に混乱しており、ガイダンスが必要です!

どんな助けでも感謝します!

…なんとか実行までこぎつけました!しかし、実行を開始したところ、以下のエラーで失敗しました。

"root@vps-xxxxxxxx-app:/var/www/discourse/script/import_scripts# bundle exec ruby vbulletin.rb\n/var/www/discourse/config/initializers/013-excon_defaults.rb:4:in `\u003cmain\u003e': can't modify frozen Hash: {:chunk_size=\u003e1048576,                                                             :ciphers=\u003e\"ECDHE-ECDSA- [................]\"\n```

…もう私のトラブルシューティング能力の限界に達したと思います。

/var/www/discourse から開始しても違いがあるか分かりませんが、私はいつもそうしています。OP で推奨されているのは次のとおりです。

そのエラーは認識できません。

「いいね!」 1

昨夜、何時間も「調査」した末に諦めた時点では、自分のコンフォートゾーンをはるかに超えた多くのことをいじくり回しており、良いことよりも悪いことをしているのではないかと心配していました。また、最近誰かがそれをやっていて、私が何か魔法のような手順を見逃しているのではないか、それとも繰り返し現れるラビットホールに陥り続けるのではないか、ということを聞きたかったのです :winking_face_with_tongue:

何か新しい問題が発生している可能性があります。先日mboxインポートを実行しましたが、それがあなたにエラーを引き起こしたのと同じコードを呼び出すのだと思います。

ああ。コンテナ内で実行しましたが、これらの指示は開発環境用です。開発環境をセットアップしましたか?うまくいきましたか?VPNではそれは難しいです。

明日、すべて消去して再試行します。今夜は偏頭痛があります。
どうなったかお知らせします :slightly_smiling_face:

「いいね!」 1

開発環境をセットアップしましたか?それが最初の手順でしたか?

ホストVPS経由で試したり、コンテナ経由で強引にやろうとしたりしました。終わる頃には、何をしたのか、どこでやったのかさえ分からなくなっていました。おそらくスキル不足でしょう…明日、最初からやり直します。

VM上で実行しているのであれば、コンテナで実行する方がおそらく簡単でしょう。他のインポート方法の例(MySQLテンプレートが含まれています)を参照することをお勧めします。

コンテナに入り、Gemファイルを編集してbundle installを実行するかもしれません。

MySQLまたはMariaDBにコンテナを使用するのは理にかなっているでしょう。(ただし、コンテナ同士が互いに通信できることを確認する必要があります)

「いいね!」 1

エキサイティングなニュースがあります…

スクリプトが実行されるようになりました(完了したらガイドを作成します)。ユーザーグループはインポートされましたが、ユーザーのインポートで停止しています。タイムゾーンの変数に関連していると思われます。

importing users
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/tzinfo-2.0.6/lib/tzinfo/timestamp.rb:138:in `for': Integer values are not supported (ArgumentError)

            raise ArgumentError, "#{value.class} values are not supported" unless is_time_like?(value)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/tzinfo-2.0.6/lib/tzinfo/timezone.rb:575:in `utc_to_local'
        from script/import_scripts/vbulletin.rb:1019:in `parse_timestamp'
        from script/import_scripts/vbulletin.rb:166:in `block (2 levels) in import_users'
        from /var/www/discourse/script/import_scripts/base.rb:267:in `block in create_users'
        from /var/www/discourse/script/import_scripts/base.rb:266:in `each'
        from /var/www/discourse/script/import_scripts/base.rb:266:in `create_users'
        from script/import_scripts/vbulletin.rb:148:in `block in import_users'
        from /var/www/discourse/script/import_scripts/base.rb:951:in `block in batches'
        from <internal:kernel>:187:in `loop'
        from /var/www/discourse/script/import_scripts/base.rb:950:in `batches'
        from script/import_scripts/vbulletin.rb:126:in `import_users'
        from script/import_scripts/vbulletin.rb:82:in `execute'
        from /var/www/discourse/script/import_scripts/base.rb:47:in `perform'
        from script/import_scripts/vbulletin.rb:1027:in `<main>'

スクリプトのデフォルトは「America/Los Angeles」です。vBulletinフォーラムは(GMT)Western Europe Time、London、Lisbon、Casablancaに設定されており、インポート先のDiscourseインスタンスにはAmerica/Los AngelesとEurope/Parisの2つのエントリがあります。

どちらを選ぶべきか分かりますか?

どちらを選んでも、それほど大きな違いはありません。

スクリプトが予期している形式で日付が保存されていないことが原因かもしれません。

「いいね!」 1