# disqus.rb 导入脚本使用问题

**URL:** https://meta.discourse.org/t/issues-with-using-disqus-rb-import-script/169984
**Category:** Support
**Created:** [2020年十一月12日 21:10 UTC](https://meta.discourse.org/t/issues-with-using-disqus-rb-import-script/169984 "2020-11-12T21:10:33Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![astuffedtiger](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/astuffedtiger/32/258958_2.png) [@astuffedtiger](https://meta.discourse.org/u/astuffedtiger)
#### Post date: [2020年十一月12日 21:10 UTC](https://meta.discourse.org/t/issues-with-using-disqus-rb-import-script/169984/1 "2020-11-12T21:10:33Z")

</div>

您好，

我刚搭建好 Discourse，但想从 Disqus 导入我的评论。我注意到有一个很棒的导入脚本，但它似乎对我不起作用。

**更新 #2：** 好的，看来我有一些格式错误的 XML，所以我现在遇到了同样的问题 [如这里所述](https://meta.discourse.org/t/disqus-xml-import-it-discourse-issue/88435)。问题是 Disqus 不再在 XML 导出中包含电子邮件地址，实际上在其仪表板中“隐藏”了它们。因此，除非您添加一些额外的代码，在 `create_users` 函数中即时生成电子邮件地址，否则可能无法导入评论。

**更新：** 实际上，我想我应该先退一步。如果不调整脚本顶部的 `frozen_string_literal` 项，我会得到：

```plaintext
Traceback (most recent call last):
        6: from script/import_scripts/disqus.rb:228:in `<main>'
        5: from script/import_scripts/disqus.rb:228:in `new'
        4: from script/import_scripts/disqus.rb:21:in `initialize'
        3: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/nokogiri-1.10.10/lib/nokogiri/xml/sax/parser.rb:104:in `parse_file'
        2: from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/nokogiri-1.10.10/lib/nokogiri/xml/sax/parser.rb:104:in `parse_with'
        1: from script/import_scripts/disqus.rb:176:in `characters'
script/import_scripts/disqus.rb:195:in `record': can't modify frozen String (FrozenError)

```

所以，也许应该先解决这个问题（在深入探讨下面的问题之前）？

```plaintext
root@discourse:/var/www/discourse# su discourse -c "bundle exec ruby script/import_scripts/disqus.rb"
Loading existing groups...
Loading existing users...
Loading existing categories...
Loading existing posts...
Loading existing topics...

importing users...

importing topics...

Updating topic status

Updating bumped_at on topics

Updating last posted at on users

Updating last seen at on users

Updating first_post_created_at...

Updating user post_count...

Updating user topic_count...

Updating topic users

Updating post timings

Updating featured topic users

Updating featured topics in categories
        4 / 4 (100.0%) [3222 items/min] n]  
Resetting topic counters

Done (00h 00min 00sec)

```

我对 Ruby 了解不多——实际上我完全不懂，但我确实知道足够多的内容来尝试添加一些调试代码，比如 `puts "#{id}"`，看看是否有内容被获取等。例如，我在第 190 行上方添加了 `puts "#{target}"` 或 `puts "#{str}"`，这样我就能看到它确实在读取文件。

我知道脚本的一部分在工作，`IMPORT_FILE` 和 `IMPORT_CATEGORY` 已正确设置。

对于我还能做些什么来排查/调试，有什么建议吗？

谢谢！💙

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2020年十一月13日 00:12 UTC](https://meta.discourse.org/t/issues-with-using-disqus-rb-import-script/169984/2 "2020-11-13T00:12:50Z")

</div>

几个月前我处理过这个议题。我想通过将 `target[sym] << str` 替换为 `target[sym] += str` 解决了 `frozen_string_literal` 问题，不过只需将第一行中的 `true` 改为 `false` 应该就可以了。

我隐约记得它当时也没起什么作用，就像对你一样，但我记不清具体原因了，在我当时的修改中也看不出明显的线索。而且，由于这次导入需要集成到一个现有网站中，我不得不进行了一些其他调整，所以恐怕我的代码对你没什么帮助。

---

<div class="post-metadata">

### Author: ![astuffedtiger](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/astuffedtiger/32/258958_2.png) [@astuffedtiger](https://meta.discourse.org/u/astuffedtiger)
#### Post date: [2020年十一月13日 00:43 UTC](https://meta.discourse.org/t/issues-with-using-disqus-rb-import-script/169984/3 "2020-11-13T00:43:16Z")

</div>

嘿 @pfaffman！感谢你抽空回复！

我也尝试过使用 `target[sym] += str`，并将第一行改为 `false`。我认为我上面的第 2 条更新是正确的。代码试图将 `email` 中的值传递给另一个函数，但由于该值为 null 或空，导致另一个函数报错崩溃了 😝

需要引入一些新代码来处理 `email` 为空的情况：要么将其替换为默认值，要么生成一个新的唯一值，或者在 `email` 为空时跳过创建新用户。

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2020年十一月13日 00:46 UTC](https://meta.discourse.org/t/issues-with-using-disqus-rb-import-script/169984/4 "2020-11-13T00:46:48Z")

</div>

> [@astuffedtiger](#):
>
> 需要引入某种新代码来处理 `email` 为空的情况

```ruby
    @parser.posts.each do |id, p|
      p[:author_email] = "#{p[:author_username]}@nowhere.invalid" unless p[:author_usrname]
      next if p[:is_spam] == 'true' || p[:is_deleted] == 'true'
      puts "name: #{p[:author_name]}, username: #{p[:author_username]}, email: #{p[:author_email]} "
      by_email[p[:author_email]] = { name: p[:author_name], username: p[:author_username] }
    end

```

---

<div class="post-metadata">

### Author: ![justin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/justin/32/157614_2.png) [@justin](https://meta.discourse.org/u/justin)
#### Post date: [2020年十一月13日 01:55 UTC](https://meta.discourse.org/t/issues-with-using-disqus-rb-import-script/169984/5 "2020-11-13T01:55:36Z")

</div>

如果您修复了问题，且确认 Disqus 导入功能确实存在缺陷，欢迎提交 Pull Request 以改进它！

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2020年十一月13日 04:27 UTC](https://meta.discourse.org/t/issues-with-using-disqus-rb-import-script/169984/6 "2020-11-13T04:27:25Z")

</div>

我总是 **打算** ……

---

<div class="post-metadata">

### Author: ![astuffedtiger](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/astuffedtiger/32/258958_2.png) [@astuffedtiger](https://meta.discourse.org/u/astuffedtiger)
#### Post date: [2020年十一月13日 17:10 UTC](https://meta.discourse.org/t/issues-with-using-disqus-rb-import-script/169984/7 "2020-11-13T17:10:19Z")

</div>

好的！我通过以下方式解决了这个问题：

```ruby
    @parser.posts.each do |id, p|
      p[:author_username] = "#{p[:author_name]}" unless p[:author_username]
      p[:author_email] = "#{p[:author_username]}@disqus.sucks" unless p[:author_email]
      next if p[:is_spam] == 'true' || p[:is_deleted] == 'true'
      puts "name: #{p[:author_name]}, username: #{p[:author_username]}, email: #{p[:author_email]}"
      by_email[p[:author_email]] = { name: p[:author_name], username: p[:author_username] }
    end

    @parser.threads.each do |id, t|
      t[:author_username] = "#{t[:author_name]}" unless t[:author_username]
      t[:author_email] = "#{t[:author_username]}@disqus.sucks" unless t[:author_email]
      by_email[t[:author_email]] = { name: t[:author_name], username: t[:author_username] }
    end

```

我还设置了 `frozen_string_literal: false`。

---

<div class="post-metadata">

### Author: ![jbrains](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jbrains/32/208183_2.png) [@jbrains](https://meta.discourse.org/u/jbrains)
#### Post date: [2021年二月3日 01:14 UTC](https://meta.discourse.org/t/issues-with-using-disqus-rb-import-script/169984/10 "2021-02-03T01:14:22Z")

</div>

我进展得更远了，但现在某个 _新_ 的东西是 `nil`。我会继续排查和尝试，但非常需要帮助，我承诺会将我的发现回馈回去。

我应用了本线程中的补丁，但在导入话题时卡在了这里：

```bash
Traceback (most recent call last):
        5: from script/import_scripts/disqus.rb:236:in `\u003cmain\u003e'
        4: from /var/www/discourse/script/import_scripts/base.rb:47:in `perform'
        3: from script/import_scripts/disqus.rb:29:in `execute'
        2: from script/import_scripts/disqus.rb:70:in `import_topics_and_posts'
        1: from script/import_scripts/disqus.rb:70:in `each'
script/import_scripts/disqus.rb:84:in `block in import_topics_and_posts': undefined method `topic' for nil:NilClass (NoMethodError)

```

好吧。我觉得今晚我搞不定这个了。

我已经弄明白 `find_remote()` 对某条评论返回了 `nil`，但我完全不知道这意味着什么，也不明白这为何重要。我怀疑这与 HTTP/HTTPS 有关，所以出于绝望，我打算把我 Disqus 导出文件中的所有 URL 从 HTTP 改为 HTTPS，然后听天由命。

非常欢迎任何建议。

[更新！]

我目前的猜想：如果 Disqus 评论所在的帖子链接对应的 Disqus 线程已不存在（例如来自 1853 年的 Tumblr 博客），那么这个导入脚本就会彻底崩溃。

万一我猜对了，有没有更熟悉代码的人能建议如何修改导入器，让它能够愉快地跳过这类线程和评论？

如果我没猜对，嗯，那我大概会再回复这条消息，分享更多发现。😛

[更新！]

我手动删除了所有来自链接已失效线程的评论。这似乎足以成功导入我所有的 Disqus 评论。因此，我认为，如果有人能读懂这个脚本的代码并据此进行修复，那就太好了。我觉得我自己做不到。

至少我希望这些文字能帮助到接下来追随我的那位可怜人。祝好运。

再见。
