迁移后清理所有帖子中的html标签?

如我在 临时但可用的 Flarum 导入脚本 中所述,我已从 Flarum 迁移到 Discourse。这是我的第一个站点,我完全被你们的工作所吸引,向你们所有人致敬。

乍一看在开发环境中似乎一切正常的,是帖子迁移的方式。在浏览器中,大多数帖子看起来没问题,但深入查看会发现存在大量遗留的 HTML 标签,这些标签会导致图片加载失败、无法导入到本地存储等问题。

有没有一种聪明的方法可以在迁移后批量移除所有帖子中的 HTML 标记?

另一个问题是,我还需要将大量 URL 从 http 更正为 https。

感谢你们的帮助。顺便提一下,我提供的这个临时脚本确实应该进行改进,以便更好地处理帖子到 Discourse 帖子格式的转换(这不在我的技能范围内)。

2 个赞

在导入器中修复这些问题最为容易。如果您已经上线且无法使用导入器,那么难度会更大。您只需编写代码来修改原始文本,然后重新生成帖子。很遗憾,这并没有什么魔法。

3 个赞

听起来您遇到了这里描述的问题:https://meta.discourse.org/t/fix-broken-images-for-posts-created-by-the-wp-discourse-and-rss-plugins/160773。我在该主题下的第一条回复中详细说明了问题的成因。该问题会影响通过 HTML 创建的帖子中的图片。我会更新该主题的标题,以明确其影响范围不仅限于通过 WP Discourse 插件或 RSS 源创建的帖子。

理想情况下,Discourse 的 Markdown 解析器应能处理被其他 HTML 标签包裹的 HTML 图片标签。不过,我认为修复这个问题相当困难。

2 个赞

是的,这正是我遇到图片损坏且位于其他 HTML 标签内时的现象。

我已经开始手动修复,但这非常耗时,而且每次修改都会导致帖子被重新置顶到最新列表,这又需要手动重置置顶等操作,问题变得更加复杂。

我打算先查看几个问题严重的帖子,尝试找出移除 HTML 标签的逻辑。之后,我可能需要协助将整个数据库中的此类问题自动化处理,我打算尝试使用 Data Explorer 来解决这部分问题。Data Explorer 能否作为 IDE 来执行这些帖子转换操作?

期待学习这一过程。

Koen

1 个赞

不行,Data Explorer 插件仅允许你从站点数据库读取数据,不允许向站点数据库写入数据。

2 个赞

大家好,我已经摸索出如何手动清理数据并修复损坏的图片。不过,我希望能够自动化完成这些操作。

我想要找到一种方法,移除所有类似 [P][/P][BR/] 的 HTML 标签。

我已经在论坛中搜索过,但没找到接近的解决方案。我也查看了导入脚本,但其中并没有从 Discourse 到 Discourse 的导入器作为起点。我认为我需要编写一个脚本来:

  • 访问 posts 表
  • 遍历所有帖子
  • 对每个帖子进行处理:
    • 完全移除 P 标签
    • BR/ 替换为换行符
    • 对 URL 进行智能处理
    • 对图片进行智能处理
  • 最后重新生成(rebake)所有帖子

有人能指引我参考 Discourse 上的相关讨论吗?或者是否有人拥有可以让我上手的脚本或代码片段?我并非资深开发者,但我可以修改现有的可用代码……

一旦我达成目标,我会将成果回馈给社区。

Koen

1 个赞

这是执行类似操作的代码:

posts=Post.where("raw like '%Sent from%using Tapatalk'")

posts.each do |post|
   post.raw.gsub!(/^Sent from my.+?using Tapatalk$/,"")
   post.save
   post.rebake!
end

除非图片或 URL 已损坏,否则我认为你不需要对它们做“智能”处理。

你可以尝试类似以下的代码:

   post.raw.gsub!(/\/?\[p\]/ig,"\n")

用换行符替换 [p][/p](多一个换行符通常无妨,但如果你认为不需要换行,可以移除 \n)。不过我尚未测试,所以这段代码可能不正确。你可以在 https://rubular.com/ 等工具中进行测试。

2 个赞

太棒了,这完全帮我理清了思路。

我想对于我的简单情况,直接使用 rake posts:remap["find","replace"] 应该就足够了,对吧?

我这就去试试,非常感谢!

1 个赞

要弄清楚如何在该 rake 任务中转义 [ 可能很棘手(甚至可能无法实现)。

1 个赞

抱歉,那个"]“字符只是因为我当时不知道如何输入”<"才加上的。

我只需要移除几个这样的标准 HTML 标签。

这样用 remap 应该就没问题了吧?

2 个赞

大概是这样。你可以用反引号引用内容,就像这样:

`<`p`>`

或者

`<p>`
2 个赞

顺便提一下 @koen360

在我们迁移论坛时,来自近二十年论坛帖子的无数 bbcode 和标签问题层出不穷。

我们没有使用 rake remap 函数来处理这些问题,在所有情况下,我们都采用了 @pfaffman 在他的代码片段中概述的技术:

上面这段使用 gsub() 的代码片段总结了在迁移后(甚至更好的是在迁移期间)清理原始帖子的最佳方法之一。

在真正将其应用于数据库之前,请务必测试您的正则表达式,并在直接对数据库执行此类操作之前进行完整备份。

1 个赞

你好,下面是我的 script/cleanup.rb 脚本内容,我是这样运行的:RAILS_ENV=development bundle exec ruby script/cleanup.rb

文件内容:

require_relative '../config/environment'
pm = 0
Post.find_each do |test|
	test.raw.gsub!(/<(.|\/.)>/i,"")
	test.save
	test.rebake!
	pm = pm + 1
end
puts "cycled through #{pm} posts"

我尝试过 rake posts:rebake,它重新烘焙了 1757 篇帖子。而我的脚本只遍历了 1712 篇帖子,这些是导入的带有 HTML 标签的内容,其余的是在 Discourse 中新创建的。

我觉得我快成功了,但当我在 UI 中检查原始内容时,仍然看到所有的 HTML 标签。

我尝试重启环境并重新启动 Unicorn,但毫无效果。差一点了……差一点了 ;o)

2 个赞

你是在哪里测试你的正则表达式的?请一次只发布一条帖子,以确保原始内容已被正确修改。

1 个赞

采用了您推荐的 rubular 方案,现在 regexr.com 的效果如下截图所示。目前先处理 p 和 r 标签,等这些搞定后再添加更复杂的规则。

2 个赞

当我在我的 cleanup.rb 中添加了一个 put 语句,以便将原始帖子内容打印到命令行界面时,我注意到根本没有打印出任何 HTML 标签。

然而,当我编辑任何帖子时,我确实看到了以下内容,右侧显示了 HTML 标签。这似乎不是正常情况,因为当我返回编辑正在编辑的帖子时,我看不到 HTML 标签……

有人知道是怎么回事吗?

1 个赞

那个 gsub 需要在 /i 后面加一个 g 才能匹配多个标签。但如果你看到的 puts 输出与脚本运行后的结果不同,那我无法解释原因。

1 个赞

真奇怪,我遇到了这个错误:

script/cleanup.rb:9: unknown regexp option - g

当我像这样给 i 加上 g 时:

require_relative ‘../config/environment’

pm = 0
Post.find_each do |test|
puts test.raw
test.raw.gsub!(/<(.|/.)>/ig,“”)
test.save
test.rebake!
pm = pm + 1
end
puts “cycled through #{pm} posts”

1 个赞

据我所知(这也是我们通常使用 gsub 匹配多行内容的方式……),Ruby 的多行正则表达式需要 m 修饰符:

/./m - 匹配任意字符(m 修饰符启用多行模式)

参考:

希望这能帮到你。

1 个赞

谢谢,正则表达式那边已经解决了。

不过这个脚本似乎还有两个我无法解释的问题:

# 调用方式如下:
# RAILS_ENV=development bundle exec ruby script/cleanup.rb -> cleanup.log

require_relative '../config/environment'
pm = 0
Post.find_each do |test|
	puts test.raw
	test.raw.gsub!(/<(.|\/.)>/im,"")
	test.save
	test.rebake!
	pm = pm + 1
end
puts "cycled through #{pm} posts"
  1. 运行几次后,cleanup.log 中仍然在大约 21000 行原始帖子内容里保留了 10 个 <p> 实例。奇怪的是,这些从未被移除。
  2. 更奇怪的是(至少对我来说),当我启动 Unicorn 并在本地机器上访问网站时,在编辑器原始视图中检查的所有帖子仍然包含 HTML 标签。

看来我可能没有查看同一个环境?难道 d/unicorn 指向的是本地生产环境,而我的脚本只是对开发环境进行了修改?

我打算先在本地使用 Docker 指南在开发环境中解决这个问题,然后再处理线上站点。

这肯定是我这个新手忽略的某个基本问题。:sweat_smile:

1 个赞