所以,我目前的状况是这样的:
在尝试对所有包含字符串 [img] 的 40000 篇帖子执行 post.rebake!(invalidate_broken_images: true) 后,很多图片的上传都成功了……但远非全部,尽管它们托管在同一个外部图片托管服务上。
例如,我有数千个“有效”的 casimages 链接(链接到有效的图片,并在编辑时的编辑器预览中显示图片),在帖子的已发布版本中却显示为损坏,尽管它们已通过我的脚本成功上传到服务器,但还有很多其他的图片根本没有上传,我不知道为什么。
Post.where('raw LIKE ?', '%[img]%').find_each do |p|
p.rebake!(invalidate_broken_images: true)
end
我还有来自其他图片托管的图片链接,有些上传成功了,有些则没有。
我未能发现这些帖子和图片链接之间有任何区别。它们都包含有效的图片,而且它们使用相同的图片托管服务让我感到困惑。
我尝试了多次操作,结果却不一致,这与外部托管服务无关……有些图片被上传了,有些则没有。看起来像是随机的。
这让我想起了 @Amethi 遇到的问题:Some linked images not displaying/show as broken - #8 by Amethi
这里我只讨论 casimages,尽管我导入的论坛使用了各种其他图片托管服务。
所以,我曾想,也许 casimages 会暂时将我的 IP 列入黑名单,如果我尝试从他们的服务器检索过多图片。这可以解释为什么并非所有图片都上传成功,以及图片上传成功的随机性。
甚至出现过 Rebuild HTML 选项(起初 只在第一次时)工作正常,图片显示出来而不是显示损坏的图片图标,尽管它们仍然托管在外部服务上,但当 Sidekiq 的“拉取外部图片”任务触发时,图片却损坏了。
使用 rebake!(invalidate_broken_images: true) 的 rail 脚本也是同样的情况。
所以,我目前正在尝试一种更慢的方法,在每次执行 rail rebake! 命令之间等待 5 秒:
total = Post.where('lower(raw) LIKE ?', '%[img]https:%').count
i = 0
Post.where('raw LIKE ?', '%[img]https:%').find_each do |p|
p.rebake!(invalidate_broken_images: true)
print "#{i}/#{total}"
print "\r"
i += 1
sleep(5)
end
我将在大约 60 小时后看看情况是否有所改善……
我想了解这个问题的根本原因,以及为什么“正常”的 rebake 无法将图片上传到服务器(如果 我没有被 casimages 暂时列入黑名单)。
请注意,这次,casimages 服务器的证书似乎没问题 :
我也不太明白 invalidate_broken_images 到底做了什么。我对 Discourse 的代码不太熟悉。
我查看了代码中 invalidage_broken_images 的出现位置,看到了这些文件:
end
if RailsMultisite::ConnectionManagement.current_db != "default"
recover_uploads_from_index(path)
else
RailsMultisite::ConnectionManagement.each_connection do
recover_uploads_from_index(path)
end
end
end
desc 'invalidate broken images'
task 'posts:invalidate_broken_images' => :environment do
puts "Invalidating broken images.."
posts = Post.where("raw like '%<img%'")
rebaked = 0
total = posts.count
posts.find_each do |p|
rebake_post(p, invalidate_broken_images: true)
为什么它专门搜索 \u003cimg 字符串?我的帖子是从 phpBB 导入的,原始版本只包含 [img] bbCode,而不是 \u003cimg\u003e 标签;那么它怎么会对我的帖子产生影响(而且确实产生了影响,请看我之前的消息)?
我也不太明白这两个方法之间的区别(?):
else
post.custom_fields["rebake_attempts"] = attempts + 1
post.save_custom_fields
end
end
end
problems
end
def rebake!(invalidate_broken_images: false, invalidate_oneboxes: false, priority: nil)
new_cooked = cook(raw, topic_id: topic_id, invalidate_oneboxes: invalidate_oneboxes)
old_cooked = cooked
update_columns(
cooked: new_cooked,
baked_at: Time.zone.now,
baked_version: BAKED_VERSION
)
if is_first_post?
guardian.ensure_can_change_post_type!
post = find_post_from_params
params.require(:post_type)
raise Discourse::InvalidParameters.new(:post_type) if Post.types[params[:post_type].to_i].blank?
post.revise(current_user, post_type: params[:post_type].to_i)
render body: nil
end
def rebake
guardian.ensure_can_rebake!
post = find_post_from_params
post.rebake!(invalidate_oneboxes: true, invalidate_broken_images: true)
render body: nil
end
def unhide
post = find_post_from_params
它似乎表明 rebake 将默认参数设置为 false,而 rebake! 将默认参数设置为 true。
这两个方法是如何关联的(顺便说一句,我知道 ! 字符在 ruby 中的含义),为什么它们会出现在不同的文件中?
我的目标只是想了解为什么我的外部图片有时上传成功,有时不成功,以及我是否能找到一种可靠的方法来自动正确地上传它们 ,即使这意味着每小时上传一张图片。
我为此已经花了将近两周的时间,这让我(以及我为其迁移服务器的人)快疯了。
另外,Discourse 的日志中没有任何记录,只有多条 Sidekiq is consuming too much memory (using: 592.25M) 的提示。请注意,我是在 Windows 10 的 WSL 上通过 Ubuntu 进行操作的,但我打算在我们的 VPS 上使用一个有效的解决方案(如果我找到了的话……)。