こんにちは、
Discourse をセットアップしたばかりですが、Disqus からコメントをインポートしたいと考えています。素晴らしいインポートスクリプトがあることに気づいたのですが、私の環境ではうまく動作していないようです。
UPDATE #2: どうやら XML に不正な部分があったようです。そのため、今では こちらで指摘されている のと同じ問題に直面しています。問題は、Disqus が XML エクスポートにメールアドレスを含まなくなり、実際にはダッシュボード内でそれらを「隠している」ことです。したがって、create_users 関数に対して動的にメールアドレスを生成する追加コードを実装しない限り、コメントのインポートは不可能かもしれません。
UPDATE: 実際、少し立ち止まって考えてみるべきかもしれません。スクリプトの先頭にある frozen_string_literal 項目を調整しない場合、以下のエラーが発生します。
Traceback (most recent call last):
6: from script/import_scripts/disqus.rb:228:in `\u003cmain\u003e'
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)
したがって、まずこの問題を解決するべきかもしれません(以下の内容を探る前に)?
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 が正しく設定されていることから、スクリプトの少なくとも一部は機能していることがわかります。
他にトラブルシューティングやデバッグのために何ができるか、アイデアはありますか?
ありがとうございます!
pfaffman
(Jay Pfaffman)
2020 年 11 月 13 日午前 12:12
2
数ヶ月前に Discus についていくつか作業を行いました。target[sym] << str を target[sym] += str に置き換えることで frozen_string_literal の問題を修正したと記憶していますが、最初の行の true を false に変更するだけでも問題ないはずです。
あなたの環境と同様に、何の変化も起きなかったという曖昧な記憶はありますが、それが何だったのかは覚えておらず、私の変更内容にも明らかな原因は見当たりません。また、このインポートは既存のサイトに統合する必要があるため、いくつか他の変更も加えました。そのため、私のコードがあなたのお役に立てるかどうかはわかりません。
「いいね!」 1
@pfaffman さん、ご返信いただきありがとうございます!
target[sym] += str を試したり、最初の行を false に変更してみたりしました。上記の更新 #2 が正しいと思います。email の値を別の関数に渡そうとしていますが、null または空のため、その関数がエラーを発生させてしまいます
email が空の場合に対応し、デフォルト値に置き換える、新しい一意の値を生成する、あるいは空の場合は新しいユーザーの作成をスキップするといった、何らかの新しいコードの導入が必要になるでしょう。
pfaffman
(Jay Pfaffman)
2020 年 11 月 13 日午前 12:46
4
@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
justin
(Justin DiRose)
2020 年 11 月 13 日午前 1:55
5
修正して、Disqus のインポートが実際に機能していないことが確認できた場合は、改善のためのプルリクエストを自由に投稿してください!
「いいね!」 1
よし、以下のコードで動作するようになりました:
@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 も設定しています。
「いいね!」 2
jbrains
(J. B. Rainsberger)
2021 年 2 月 3 日午前 1:14
10
さらに進めましたが、今度は何か 新しい ものが nil になっています。原因を突き止め、修正を試みますが、お手伝いいただければ幸いです。発見したことは必ず共有します。
このスレッドのパッチを適用した後、トピックのインポート中にここで停止してしまいました。
Traceback (most recent call last):
5: from script/import_scripts/disqus.rb:236:in `<main>'
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 コメントのインポートが成功したようです。したがって、このスクリプトのコードを読める方が、それに合わせてパッチを適用してくださると幸いです。私にはそれができる自信がありません。
少なくとも、この文章が私に続いてくる次の不運な方のお役に立てば幸いです。幸運を祈ります。
平和を。