将 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 的代码。以前:

    # [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 世界中,spoiler 不是模糊的内容,而是折叠的内容。所以我认为对于 vbulletin 导入脚本来说,将 spoiler 转换为 details 比模糊的 spoiler 更合适。

我还注意到 mention 标签。在我的情况下,在 vbulletin 中,mention 的外观如下:
[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 个赞

当我开始迁移我运行 vB 3 的 24 年历史的 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_URL 设置为 forum.hostname/path(无协议)。

与其尝试将 vBulletin 私信转换为 Discourse 私信,用户将收到一个系统私信,其中包含他们之前私信的存档。vBulletin 的 PM 结构与 Discourse 并不真正兼容。尝试转换它也会暴露一些隐私问题,具体取决于人们在 vBulletin 中使用 PM 的方式。

与其他导入器一样,转换可能需要相当长的时间。在我的工作站上,转换 7k 用户、16k 帖子、415k 回复的转换脚本花费了 5.5 小时。我不知道帖子处理花了多长时间,我让它在夜间运行。从开始到结束,论坛停机了 30 小时。最终,我对结果感到满意。

2 个赞

这可真是怀旧 :slight_smile:

你的论坛看起来很不错。我喜欢主题行交替的颜色。

似乎这个线程和导入器现在都已经过时了。我在这个线程的帮助下修复了一些问题,但现在在用户导入步骤上遇到了困难,有人知道怎么修复吗?

internal:timev:286:in at’:无法将 NilClass 转换为精确数字(TypeError)`

要么查询有误,要么表中缺少某个值

多年后回复这个有点奇怪,但我现在正在使用批量导入器进行 VB 导入,并且丢失了很多图片,原因是它们将附件文件名移到了不同的字段。

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

NUMBER.attach 文件现在是 filedataid 字段,而不是 attachment_id 字段。因此,脚本中的该查询需要更新。

我被要求将 vbulletin 4.25 论坛迁移到 discourse……阅读此帖让我心情复杂……看起来是可行的,但可能是一个巨大的痛苦和时间消耗(我现在两者都想避免)……

是否有适用于 vbulletin 4.25 的更新脚本?我只能在官方页面上看到 3 和 5?

嗯,在 script/bulk_import 目录中有 vbulletinvbulletin5 脚本,它们只有几个月的使用时间。运行这些批量导入非常棘手,而且文档记录不完善。

我已经进行了 100 多次导入,并且我非常确定我从未进行过一次不需要因各种原因调整脚本的导入。

在我真正学会 Ruby 之前,我写了几个导入脚本(但一位 20 世纪 80 年代中期的教授向我保证,在他的编程语言课程之后,如果我有一个周末和一本书,我就可以说我懂任何语言;他基本上是对的。)

但是的,这很可能和你想象的一样麻烦和耗时。

我怀疑 vbulletin 脚本会做得很好;我可能不会推荐批量导入脚本,除非你有超过一百万的帖子+用户。

1 个赞

谢谢 :slight_smile:
看来我需要决定这个周末要做什么了 :smiley:

1 个赞

我真的很希望能得到一些帮助 :face_with_spiral_eyes:

我通读了帖子,并按照这里看到的一些步骤进行操作,但遇到了困难。

  1. 我通过 SSH 连接到我的 VPS
  2. 进入 Docker 镜像
  3. 安装 mariadb-server
  4. 尝试运行 mysql 命令来创建一个数据库,但收到“无法通过套接字连接到本地服务器”的错误

这里的说明是几年前的了——我看到有几个人遇到了同样的错误,但我没有看到任何解决方案。

有人最近进行过这个过程吗?能给我指明正确的方向吗?我不认为我错过了任何一步一步的指南,对吧?

编辑:补充一下,我尝试了各种方法,最终在本地主机(非 Docker)上安装了一个 mariadb Docker 镜像,然后暴露了端口——我现在可以从 Docker 镜像连接到数据库……但运行脚本时出现:Gemfile:未定义局部变量或方法 ‘mysql2’。我尝试安装 gemfile,但失败了……在我进一步排查之前,我总觉得我使用的是过时的信息和可能过时的软件包……我非常困惑,需要一些指导!

任何帮助都将不胜感激!

…我坚持了下来,终于运行了脚本!但是,在开始执行后,它会因以下错误而失败:

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

…我想我已经快到故障排除能力的极限了。

我不知道从 /var/www/discourse 启动是否会有区别,但我一直都是这么做的。以下是 OP 中推荐的方法。

我不认识那个错误。

1 个赞

到我昨晚放弃的时候,经过数小时的“研究”,我已经尝试了许多超出我能力范围的事情,我担心我正在造成更多损害而不是好处。我也很想知道是否有人最近做过这件事,并且我遗漏了什么神奇的步骤,而不是陷入反复出现的兔子洞 :winking_face_with_tongue:

可能存在一些新问题。我前几天运行了一个 mbox 导入,我想它调用了导致你出错的相同代码。

哦。我在容器中做的,而这些说明是针对开发环境的。你设置了开发环境吗?你成功了吗?在 VPN 上这很棘手。

我明天会清除并重试,今晚偏头痛。\n\n我会告诉你进展如何 :slightly_smiling_face:

1 个赞

你是否设置了开发环境?那是你的第一步吗?

我尝试通过宿主 vps 来进行操作,并且通过容器来处理。等我完成时,我不确定我具体做了什么。这很可能是技术问题……我明天会重新开始。

如果在虚拟机上进行操作,那么在容器中进行操作可能更容易。可以参考一些其他的导入操作指南示例(它们会包含 mysql 模板)。

您将进入容器,可能需要编辑 Gemfile 并运行 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)西欧时间,伦敦,里斯本,卡萨布兰卡),而我正在导入的 discourse 实例有两个条目:America/Los Angeles 和 Europe/Paris。

你知道我应该选择哪个吗?

没关系,你选哪个都行。

我想可能是日期存储的方式不符合脚本的预期。

1 个赞