نقل قائمة بريدية إلى Discourse (mbox، Listserv، Google Groups، إلخ)

أحاول استيراد ملف mbox قياسي من قائمة بريدية، لكنني أواجه مشكلات تتعلق بـ “إيقاف العملية”، وعادة ما تحدث بعد قضاء وقت طويل في خطوة “فهرسة […]mbox”. هذا الملف هو نسخة كبيرة من قائمة بريدية لمشروع مفتوح المصدر تحتوي على عشر سنوات من المنشورات.

الأشياء التي جربتها:

  • تقسيم ملف mbox إلى أجزاء. نجح هذا جزئيًا، حيث تم استيراد العديد من المنشورات بنجاح، لكنني عالق الآن في فهرسة أحد هذه الأجزاء. حاولت تقسيم هذا الملف أيضًا إلى أجزاء، وقد تم استيراد الجزء الأول في النهاية، بينما يبدو أن الجزء الثاني متوقف حاليًا.

  • زيادة الذاكرة المتاحة على خادمنا. تزداد استهلاك الذاكرة ببطء أثناء الفهرسة، وتصل حاليًا إلى حوالي 16 جيجابايت (من أصل 32 جيجابايت) لمحاولة استيراد أحد هذه الأجزاء، وهو ملف mbox بحجم 80 ميجابايت:

خلال هذا الوقت، تستمر وحدة المعالجة المركزية (CPU) الواحدة في العمل بأقصى طاقتها.

أي نصيحة ستكون محل تقدير كبير، خاصة زيادة تفاصيل مخرجات التصحيح إذا كان النظام عالقًا في منشور معين. يبلغ حجم ملف index.db في مجلد import حوالي 800 ميجابايت.

أنا جديد في لغة Ruby ولا أستخدم SQL بانتظام، لذا أجد صعوبة في فهم ما يحدث. كما أن هذا الخادم ذو 32 جيجابايت مكلف، وأود تقليل حجمه إلى 4 جيجابايت قريبًا :slight_smile:

شكرًا على أي مساعدة!

إعجاب واحد (1)

أعتقد أن المحلل يتعطل عند بريد إلكتروني محدد في ملف mbox. قاعدة بيانات index.db هي قاعدة بيانات SQLite. انظر إلى جدول email، وقم بالفلترة حسب اسم ملف mbox في عمود filename، ثم ابحث عن أعلى قيمة في عمود last_line_number. من المرجح جدًا أن المحلل يتعطل عند البريد الإلكتروني التالي بعد رقم السطر ذلك داخل ملف mbox.

3 إعجابات

شكرًا جزيلاً @gerhard، لقد تمكنت من تحديد آخر بريد إلكتروني تم فهرسته بنجاح والبريد الإلكتروني الذي يليه مباشرة والذي (أفترض) أنه يسبب التعليق. ومع ذلك، لا يبدو لي أن هناك أي شيء استثنائي في هذين البريدين الإلكترونيين. هل يمكنني إرسال هذين المثالين من البريد الإلكتروني إليك في رسالة خاصة لأرى إذا كان هناك أي شيء يلفت الانتباه؟

بالتأكيد، يمكنك إرسال رسالة خاصة لي. كما يمكنك تجربة إزالة تلك عناوين البريد الإلكتروني من ملف mbox والتحقق مما إذا كان الفهرس يعمل.

3 إعجابات

شكرًا لك، تم الإرسال. لم أتمكن من مراسلتك مباشرةً عبر الرسائل الخاصة، لذا أرسلتها عبر مجموعة الفريق، آمل أن يكون ذلك مقبولاً. سأحاول إزالة البريد الإلكتروني أيضًا ونرى إلى أين سنصل قبل حدوث تعليق آخر.

إعجاب واحد (1)

شكرًا على رسائل البريد الإلكتروني. لم ألاحظ أي شيء غير عادي، وقد عملت بنجاح في اختباراتي دون مشاكل.

هذا الإجراء غير مُختبر، لكن يمكنك تجربة تطبيق رقعة git التالية قبل تشغيل سكريبت الاستيراد. تضيف هذه الرقعة مهلة زمنية مدتها 60 ثانية لتحليل رسالة البريد الإلكتروني. قد يساعدك ذلك في تحديد السبب المتسبب في المشكلة والمضي قدمًا، خاصة إذا كان الأمر يؤثر فقط على عدد قليل من الرسائل.

From 92efb4fc68724cfa20d5de48ba33b99c126a3a08 Mon Sep 17 00:00:00 2001
From: Gerhard Schlager
Date: Fri, 2 Oct 2020 17:27:39 +0200
Subject: [PATCH] Add timeout for parsing email in mbox importer

---
 script/import_scripts/mbox/support/indexer.rb | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/script/import_scripts/mbox/support/indexer.rb b/script/import_scripts/mbox/support/indexer.rb
index dc6e092c29..01523dad13 100644
--- a/script/import_scripts/mbox/support/indexer.rb
+++ b/script/import_scripts/mbox/support/indexer.rb
@@ -65,11 +65,15 @@ module ImportScripts::Mbox
     def index_emails(directory, category_name)
       all_messages(directory, category_name) do |receiver, filename, opts|
         begin
-          msg_id = receiver.message_id
-          parsed_email = receiver.mail
-          from_email, from_display_name = receiver.parse_from_field(parsed_email)
-          body, elided, format = receiver.select_body
-          reply_message_ids = extract_reply_message_ids(parsed_email)
+          msg_id = parsed_email = from_email = from_display_name = body = elided = format = reply_message_ids = nil
+
+          Timeout.timeout(60) do
+            msg_id = receiver.message_id
+            parsed_email = receiver.mail
+            from_email, from_display_name = receiver.parse_from_field(parsed_email)
+            body, elided, format = receiver.select_body
+            reply_message_ids = extract_reply_message_ids(parsed_email)
+          end
 
           email = {
             msg_id: msg_id,
-- 
2.28.0
3 إعجابات

شكرًا جزيلاً لك يا @gerhard، فالتصحيح الخاص بك يعمل بشكل رائع. بالنسبة لأغراضي، أعتقد أن تخطي الرسائل المعيبة أمر مقبول نظرًا لأن عددها قليل، ومع ذلك أصبح لدينا الآن مخرجات إضافية إذا كانت مفيدة لحل المشكلة أو لجعل سكريبت الاستيراد أكثر متانة:

فشل فهرسة الرسالة في /shared/import/data/lammps-users/chunk_10.mbox عند الأسطر 726814-729353
انتهت مهلة التنفيذ
["/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/nokogumbo-2.0.2/lib/nokogumbo/html5.rb:243:in `escape_text'",
"/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/nokogumbo-2.0.2/lib/nokogumbo/html5.rb:214:in `serialize_node_internal'",
"/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/nokogumbo-2.0.2/lib/nokogumbo/html5/node.rb:58:in `write_to'",
"/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/nokogiri-1.10.10/lib/nokogiri/xml/node.rb:699:in `serialize'",
"/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/nokogiri-1.10.10/lib/nokogiri/xml/node.rb:855:in `to_format'",
"/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/nokogiri-1.10.10/lib/nokogiri/xml/node.rb:711:in `to_html'",
"/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/nokogumbo-2.0.2/lib/nokogumbo/html5/node.rb:28:in `block in inner_html'",
"/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/nokogiri-1.10.10/lib/nokogiri/xml/node_set.rb:238:in `block in each'",
"/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/nokogiri-1.10.10/lib/nokogiri/xml/node_set.rb:237:in `upto'",
"/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/nokogiri-1.10.10/lib/nokogiri/xml/node_set.rb:237:in `each'",
"/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/nokogumbo-2.0.2/lib/nokogumbo/html5/node.rb:28:in `map'",
"/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/nokogumbo-2.0.2/lib/nokogumbo/html5/node.rb:28:in `inner_html'",
"/var/www/discourse/lib/html_to_markdown.rb:74:in `block (2 levels) in hoist_line_breaks!'",
"/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/nokogiri-1.10.10/lib/nokogiri/xml/node_set.rb:238:in `block in each'",
"/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/nokogiri-1.10.10/lib/nokogiri/xml/node_set.rb:237:in `upto'",
"/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/nokogiri-1.10.10/lib/nokogiri/xml/node_set.rb:237:in `each'",
"/var/www/discourse/lib/html_to_markdown.rb:57:in `block in hoist_line_breaks!'",
"/var/www/discourse/lib/html_to_markdown.rb:54:in `loop'",
"/var/www/discourse/lib/html_to_markdown.rb:54:in `hoist_line_breaks!'",
"/var/www/discourse/lib/html_to_markdown.rb:16:in `initialize'",
"/var/www/discourse/lib/email/receiver.rb:387:in `new'",
"/var/www/discourse/lib/email/receiver.rb:387:in `select_body'",
"/var/www/discourse/script/import_scripts/mbox/support/indexer.rb:74:in `block (2 levels) in index_emails'", 
"/usr/local/lib/ruby/2.6.0/timeout.rb:108:in `timeout'",
"/var/www/discourse/script/import_scripts/mbox/support/indexer.rb:70:in `block in index_emails'", 
"/var/www/discourse/script/import_scripts/mbox/support/indexer.rb:139:in `block (2 levels) in all_messages'",
"/var/www/discourse/script/import_scripts/mbox/support/indexer.rb:171:in `block in each_mail'", 
"/var/www/discourse/script/import_scripts/mbox/support/indexer.rb:190:in `block in each_line'",
 "/var/www/discourse/script/import_scripts/mbox/support/indexer.rb:189:in `each_line'", 
"/var/www/discourse/script/import_scripts/mbox/support/indexer.rb:189:in `each_line'", 
"/var/www/discourse/script/import_scripts/mbox/support/indexer.rb:166:in `each_mail'", 
"/var/www/discourse/script/import_scripts/mbox/support/indexer.rb:132:in `block in all_messages'", 
"/var/www/discourse/script/import_scripts/mbox/support/indexer.rb:125:in `foreach'", 
"/var/www/discourse/script/import_scripts/mbox/support/indexer.rb:125:in `all_messages'", 
"/var/www/discourse/script/import_scripts/mbox/support/indexer.rb:66:in `index_emails'", 
"/var/www/discourse/script/import_scripts/mbox/support/indexer.rb:25:in `block in execute'", 
"/var/www/discourse/script/import_scripts/mbox/support/indexer.rb:22:in `each'", 
"/var/www/discourse/script/import_scripts/mbox/support/indexer.rb:22:in `execute'", 
"/var/www/discourse/script/import_scripts/mbox/importer.rb:43:in `index_messages'", 
"/var/www/discourse/script/import_scripts/mbox/importer.rb:27:in `execute'", 
"/var/www/discourse/script/import_scripts/base.rb:47:in `perform'", 
"script/import_scripts/mbox.rb:12:in `<module:Mbox>'", 
"script/import_scripts/mbox.rb:10:in `<module:ImportScripts>'", 
"script/import_scripts/mbox.rb:9:in `<main>'"]

كما من قبل، يمكنني مشاركة الرسالة المحددة إذا كانت مفيدة – هذه المرة تمنحني رسالة الخطأ أرقام الأسطر المحددة، لذا يمكننا على الأقل أن نكون واثقين بدرجة عالية من أننا حددنا الرسالة الصحيحة.

4 إعجابات

بالتأكيد، يرجى مشاركة الرسائل معي وسأقوم بمراجعتها. إذا كانت هناك مشكلة يمكننا حلها، فإن ذلك لن يحسّن أداة الاستيراد فحسب، بل سيحسن منصة Discourse نفسها، حيث تستخدم نفس المحلل للرسائل الواردة.

إعجاب واحد (1)

لقد قمت بتشغيل هذا السكربت يوميًا خلال الأشهر القليلة الماضية لموقع يحتاج حقًا إلى الانتقال إلى اشتراك الفئة في المجموعة، لكن هذا لم يتم بعد. يعمل بشكل جيد باستثناء أنني أحتاج بين الحين والآخر إلى الحصول على ملف cookies.txt جديد. منذ حوالي شهر، حدث شيء ما وبدأ السكربت يشكو قائلاً: “يبدو أنك لا تملك أذونات لعناوين البريد الإلكتروني. جاري الإلغاء.” قمت . . . بشيء ما . . . وعاد العمل مرة أخرى. منذ أكثر من أسبوع حدث الأمر مرة أخرى، وقد قمت بإعادة تنزيل ملفات تعريف الارتباط باستخدام متصفحات متعددة/إضافات ملفات تعريف الارتباط، لكنني ما زلت أحصل على نسخة المنشورات التي لا تحتوي على عناوين البريد. يمكنني رؤية العناوين عند تسجيل الدخول عبر متصفح الويب.

هل واجه أي شخص آخر مشاكل مؤخرًا؟ هل لديك أي أفكار حول ما يجب فعله؟ لقد جربت تجربة نطاقات مختلفة في استدعاء add_cookies في السكربت، لكن ذلك لم يساعد.

إعجاب واحد (1)

حسناً، أنا أراجع هذا مرة أخرى ويبدو أن الروابط مثل

 https://groups.google.com/forum/message/raw?msg=GROUP_NAME/THREAD_ID/POST_ID

كانت تتضمن سابقاً عناوين البريد الإلكتروني الكاملة، لكنها لم تعد تفعل ذلك الآن. يمكنني التأكيد أنه عندما أكون مسجّلاً الدخول، يمكنني النقر على «حول» ورؤية عناوين البريد الإلكتروني الكاملة في واجهة الويب لمجموعات جوجل، لكن إذا ضغطت على الرابط المذكور أعلاه الذي يستهدفه سكريبت الاستخراج في نفس متصفح الويب، فإن البيانات تُسترجع مع عناوين بريد إلكتروني محذوفة.

تخميني هو أنهم زادوا من الخصوصية أو شيء من هذا القبيل.

إليك دليل آخر: يمكنني فتح ذلك الرابط في متصفحي ويعمل، لكن إذا أخذت أمر “نسخ كـ cURL” فإن أمر curl لا يحصل على عناوين البريد الإلكتروني. آه. حسنًا، جربت ذلك بمتصفح آخر وعمل أمر curl. لا أستطيع تحديد السبب تمامًا لعدم حصول السكريبت على عناوين البريد الإلكتروني.

لذا ربما هناك شيء آخر خاص بالمتصفح يقوم به؟

لم أجرب ذلك مؤخرًا، لذا من الممكن أن تكون هناك تغييرات لا يمكن للماسح التعامل معها حاليًا.

لاحظ @riking أن Google Takeout يصدر ملفات mbox لـ أصحاب المجموعات، لذا قد يكون هذا خيارًا يستحق التحقق.

5 إعجابات

شكرًا لك. حسنًا، قبل أسبوع، نجح الأمر لموقع ثانٍ، ثم قمت بتحديث ملف ملفات تعريف الارتباط مرة أخرى، فتم تحميل البيانات للموقع الأول. يبدو أن الأمر نجح ليوم أو يومين فقط، والآن لا يعمل مرة أخرى، سواء للموقع الأول أو الثاني. أرى عنوان البريد الإلكتروني الكامل في متصفحي، وأقوم بتحميل ملفات تعريف الارتباط لتلك اللسان، لكن دون جدوى.

سأتحقق من takout. تعديل: حسنًا، للحصول على ملف mbox، يبدو أنك تحتاج إلى أن تكون مديرًا فائقًا، وليس مجرد مالك.

4 إعجابات

أداة سطر الأوامر لتحويل قائمة بريدية من Mailman2 (أي محتوى config.pck مع الخيارات، الأعضاء، المشرفين، الأعلام الخاصة أو العامة، إلخ) إلى فئة في Discourse متاحة هنا: Client Challenge

إعجاب واحد (1)

@gerhard هل لديك أي أفكار حول كيفية تكييف هذه التعليمات لاستخدام تثبيت التطوير بدلاً من التثبيت القياسي؟ أشعر أنني اقتربت من نجاح عملية ترحيل listserv باستخدام عدد قليل من الأوامر فقط، لكنني لا أستطيع إكمال الخطوة الأخيرة التي أظنها ضرورية باستخدام أي من الأمرين التاليين:

ruby /src/script/import_scripts/mbox.rb ~/import/settings.yml
bundle exec ruby /src/script/import_scripts/mbox.rb /home/discourse/import/settings.yml

كلا الأمرين يفشلان في جلب جميع التبعيات. انظر هنا للحصول على مجموعة الأوامر الكاملة التي استخدمتها والأخطاء الناتجة. هل لديك أي أفكار؟ هل ربما ينقصني استدعاءات d/bundle؟

الخطوة التالية التي سأجربها هي استخدام جهاز افتراضي Ubuntu وإجراء “تثبيت قياسي” هناك، لكن هذا يبدو مبالغًا فيه بعض الشيء نظرًا لأن تثبيت dev يعمل بشكل جيد جدًا في غير ذلك.

أنا جديد تمامًا في discourseruby، ومعظم docker)، لذا أعتذر إذا كان هذا واضحًا أو (والأسوأ) غير ذي صلة!

3 إعجابات

يبدو أنك قد عرفت معظم الأمر.

لم أجرب هذا من قبل مع التثبيت التطويري القائم على Docker، لكنني أظن أنك بحاجة إلى إضافة "gem 'sqlite3'" إلى ملف Gemfile وتنفيذ apt install -y libsqlite3-dev داخل الحاوية قبل تشغيل d/bundle install.

بعد ذلك، يجب أن يعمل الأمر bundle exec ruby ....

3 إعجابات

@gerhard شكرًا لك على التذكير اللطيف — لقد أعدت التشغيل من الصفر (بدءًا من git clone) مع إضافة gem 'sqlite3' في نهاية /src/Gemfile، حيث افترضت أن هذا هو ما تقصده، وقد نجح! وللعلم، إليك التعليمات التي استخدمتها (لقائمة البريد mne_analysis):

1. في مضيف Ubuntu

git clone https://github.com/discourse/discourse.git
cd discourse
d/boot_dev --init
d/rails db:migrate RAILS_ENV=development
d/shell
vim /src/Gemfile  # أضف gem 'sqlite3' في النهاية
exit
d/bundle

2. في قشرة Docker

sudo mkdir -p /shared/import/data
sudo chown -R discourse:discourse /shared/import
wget -r -l1 --no-parent --no-directories "https://mail.nmr.mgh.harvard.edu/pipermail//mne_analysis/" -P /shared/import/data/mne_analysis -A "*-*.txt.gz"
rm /shared/import/data/mne_analysis/robots.txt.tmp
gzip -d /shared/import/data/mne_analysis/*.txt.gz
wget https://gist.githubusercontent.com/larsoner/940cd6c7100b87c4c5668cb0bc540afb/raw/9e78513620d11355ad0e10f4a2470996c26ebc8c/mailmanToMBox.py -O ~/mailmanToMBox.py
python3 ~/mailmanToMBox.py /shared/import/data/mne_analysis/
rm /shared/import/data/mne_analysis/*.txt
sudo apt install -y libsqlite3-dev  # لا تأثير لي

# التحقق من النتائج
cat /shared/import/data/mne_analysis/*.mbox > ~/all.mbox
sudo apt install -y procmail
mkdir -p ~/split
export FILENO=0000
formail -ds sh -c 'cat > ~/split/msg.$FILENO' < ~/all.mbox
rm -rf ~/split ~/all.mbox

# الإعدادات
wget https://raw.githubusercontent.com/discourse/discourse/master/script/import_scripts/mbox/settings.yml -O /shared/import/settings.yml

# تشغيله
cd /src
bundle exec ruby script/import_scripts/mbox.rb /shared/import/settings.yml

أظهر هذا العديد من المخرجات المفيدة، وفي النهاية:

...
تحديث المواضيع المميزة في الفئات
        5 / 5 (100.0%)  [6890 عنصر/دقيقة]   ]  
إعادة تعيين عدادات المواضيع


تم (00س 06د 21ث)

ثم الخروج وعلى مضيف Ubuntu:

d/unicorn &
google-chrome http://0.0.0.0:9292

تم!

ربما سأقوم بضبط الإعدادات للتخلص من بادئة [Mne_analysis]، لكنني سعيد جدًا بأن الأمر يعمل بهذه الكفاءة بالفعل!

4 إعجابات

@gerhard هل يمكن استخدام مُستورد mbox الخاص بك فقط عند تثبيت Discourse لأول مرة، أم يمكن استخدامه لاحقًا بعد أن يبدأ مستخدمون آخرون في استخدام Discourse؟ وإذا تم استخدام المُستورد بينما يستخدمه أشخاص آخرون، فهل سيلاحظون أي آثار جانبية؟

إعجاب واحد (1)

لجعل المستورد يستخرج الرسائل من مجموعات Google، كان عليّ عكس هذا التغيير في /script/import_scripts/google_groups.rb
https://review.discourse.org/t/fix-google-groups-import-changed-login-url-9432/10615
أعدت السطر

    wait_for_url { |url| url.start_with?("https://accounts.google.com") }

إلى

    wait_for_url { |url| url.start_with?("https://myaccount.google.com") }

وإلا، كنت سأحصل على هذه الرسالة في كل مرة:

جاري تسجيل الدخول...
فشل تسجيل الدخول. يرجى التحقق من محتوى ملف cookies.txt الخاص بك
6 إعجابات

@gerhard لاحظت بعد الاستيراد أنه على الرغم من أن الرسائل تبدو سليمة، لا يوجد أي مستخدمون في مرحلة التجهيز (staged) على الإطلاق، رغم أنه يبدو أنه يجب أن يكون هناك (لقد استخدمت الإعداد الافتراضي staged: true). تبدو المخرجات كالتالي:

...
indexing replies and users

creating categories
        1 / 1 (100.0%)  [13440860 items/min]  
creating users

creating topics and posts
     7399 / 7399 (100.0%)  [1421 items/min]     
...

هل من المفترض أن يُظهر عدادًا للمستخدمين أيضًا؟

لقد جربت أيضًا التشغيل باستخدام staged: false وظلت المخرجات نفسها، ولم يكن أي من مستخدمي القائمة البريدية ضمن أي مجموعات. في حال كان من المفيد رؤية ما يتم معالجته فعليًا، إليك أحد ملفات .mbox العديدة التي يتم استيرادها:

2020-December.zip (49.5 KB)

الإعداد الوحيد غير الافتراضي كان إضافة:

tags:
  "Mne_analysis": "mne_analysis"

سيكون رائعًا لو ظهرت هذه المستخدمين في مرحلة التجهيز (staged) بحيث يمكنهم المطالبة بمنشوراتهم القديمة عند التسجيل، لذا أي نصائح أو أفكار موصى بها!

إعجاب واحد (1)

ربما يجب أن يقبل كلاهما ببساطة؟