Migrer une liste de diffusion vers Discourse (mbox, Listserv, Google Groups, etc)

J’essaie d’importer un fichier mbox standard issu d’une liste de diffusion, mais je rencontre des problèmes de « Processus tué », généralement après un long temps passé sur l’étape « indexation […]mbox ». Cela provient d’un fichier mbox volumineux provenant d’un projet open-source avec dix ans de messages.

Voici ce que j’ai essayé :

  • Diviser le fichier mbox en plusieurs parties. Cela a partiellement fonctionné et de nombreux messages ont été importés avec succès, mais je suis maintenant bloqué sur l’indexation de l’une de ces parties. J’ai essayé de diviser ce fichier à nouveau en plusieurs parties : la première a fini par être importée, tandis que la seconde semble maintenant bloquée.

  • Augmenter la mémoire disponible sur notre serveur. L’utilisation de la mémoire augmente lentement pendant l’indexation et plafonne actuellement autour de 16 Go (sur 32 Go) pour une tentative d’importation de l’une de ces parties, un fichier mbox de 80 Mo :

Pendant ce temps, un seul CPU reste constamment à 100 %.

Tous conseils seraient grandement appréciés, en particulier concernant l’augmentation de la verbosité des sorties de débogage si le processus est peut-être bloqué sur un message spécifique. Le fichier index.db dans le dossier import fait environ 800 Mo.

Je suis nouveau dans Ruby et n’utilise pas régulièrement SQL, il m’est donc difficile de comprendre ce qui se passe. De plus, ce serveur de 32 Go est coûteux, je souhaiterais donc le réduire à 4 Go prochainement :slight_smile:

Merci pour toute aide !

1 « J'aime »

Je suppose que l’analyseur se bloque sur un e-mail particulier dans ce fichier mbox. Le fichier index.db est une base de données SQLite. Examinez la table email, filtrez par le nom du fichier mbox dans la colonne filename et trouvez la valeur la plus élevée dans la colonne last_line_number. Il est très probable que l’analyseur se bloque sur l’e-mail suivant après ce numéro de ligne dans le fichier mbox.

3 « J'aime »

Merci beaucoup @gerhard, j’ai réussi à identifier le dernier e-mail correctement indexé et l’e-mail qui le suit immédiatement et qui, je suppose, provoque le blocage. Cependant, il ne semble y avoir rien d’exceptionnel dans ces e-mails de mon point de vue. Est-ce que cela vous dérange si je vous envoie ces deux e-mails d’exemple en message privé pour voir si quelque chose attire l’attention ?

Bien sûr, vous pouvez m’envoyer un MP. Et essayez de supprimer ces e-mails du fichier mbox pour tester si l’indexation fonctionne.

3 « J'aime »

Merci, envoyé. Je n’ai pas pu vous envoyer un message privé directement, alors je l’ai fait via le groupe d’équipe, j’espère que cela convient. Je vais essayer de supprimer l’e-mail aussi et voir jusqu’où nous pouvons aller avant un nouveau plantage.

1 « J'aime »

Merci pour les e-mails. Je n’ai rien remarqué d’anormal et, lors de mes tests, tout s’est déroulé sans problème.

Ceci n’a pas été testé, mais vous pouvez essayer d’appliquer le correctif git suivant avant d’exécuter le script d’importation. Il ajoute un délai d’attente de 60 secondes pour l’analyse d’un e-mail. Cela pourrait vous aider à identifier le coupable et à passer à autre chose si cela n’affecte que quelques messages.

De 92efb4fc68724cfa20d5de48ba33b99c126a3a08 Lun 17 Sep 00:00:00 2001
De : Gerhard Schlager
Date : Ven, 2 Oct 2020 17:27:39 +0200
Objet : [PATCH] Ajout d'un délai d'attente pour l'analyse d'un e-mail dans l'importateur mbox

---
 script/import_scripts/mbox/support/indexer.rb | 14 +++++++++-----
 1 fichier modifié, 9 insertions(+), 5 suppressions(-)

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 « J'aime »

Un grand merci @gerhard, ton correctif fonctionne à merveille. Pour mon cas d’usage, je pense que passer outre les messages problématiques est acceptable puisqu’ils sont peu nombreux. Cependant, nous disposons désormais d’une sortie supplémentaire si cela peut aider à résoudre le problème ou à rendre le script d’importation plus robuste :

Échec de l'indexation du message dans /shared/import/data/lammps-users/chunk_10.mbox aux lignes 726814-729353
expiration de l'exécution
["/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>'"]

Comme précédemment, je peux partager le message spécifique si cela s’avère utile – cette fois, le message d’erreur m’indique les numéros de ligne précis, ce qui nous permet d’avoir au moins une forte certitude que nous avons bien identifié le message concerné.

4 « J'aime »

Bien sûr, veuillez partager les messages avec moi et je les examinerai. Si un problème est détecté, nous pourrons le résoudre, ce qui améliorera non seulement l’importateur, mais aussi Discourse lui-même, car il utilise le même analyseur pour les e-mails entrants.

1 « J'aime »

J’exécute ce script quotidiennement depuis plusieurs mois pour un site qui devrait vraiment passer à l’abonnement de la catégorie au groupe, mais cela n’a pas été fait. Tout fonctionne bien, sauf que de temps en temps, je dois obtenir un nouveau fichier cookies.txt. Il y a environ un mois, quelque chose s’est produit et le script a commencé à afficher l’erreur : « Il semble que vous n’ayez pas les autorisations pour voir les adresses e-mail. Abandon. » J’ai fait… quelque chose… et cela a recommencé à fonctionner. Il y a un peu plus d’une semaine, cela s’est reproduit et j’ai retéléchargé les cookies avec plusieurs navigateurs et extensions de gestion de cookies, mais je continue d’obtenir la version des publications sans les adresses e-mail. Je peux voir les adresses lorsque je suis connecté via le navigateur web.

Est-ce que quelqu’un d’autre a rencontré des problèmes récemment ? Avez-vous des idées sur la marche à suivre ? J’ai essayé de modifier les domaines inclus dans l’appel add_cookies du script, mais cela n’a pas aidé.

1 « J'aime »

Eh bien, je regarde à nouveau cela et il semble que des liens comme

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

incluaient auparavant les adresses e-mail complètes, mais plus maintenant. Je peux confirmer que lorsque je suis connecté, je peux cliquer sur « À propos » et voir les adresses e-mail complètes dans l’interface web de Google Groups, mais si j’ouvre l’URL ci-dessus que le script d’extraction utilise dans le même navigateur web, les données sont récupérées avec les adresses e-mail masquées.

Je suppose qu’ils ont renforcé la confidentialité ou quelque chose dans ce genre.

Voici une autre piste : je peux ouvrir ce lien dans mon navigateur et cela fonctionne, mais si je récupère la commande « copier en cURL », la commande curl ne récupère pas les adresses e-mail. Soupir. Eh bien, j’ai essayé avec un autre navigateur et la commande curl a fonctionné. Je ne parviens pas vraiment à comprendre pourquoi le script ne récupère pas les adresses e-mail.

Alors peut-être y a-t-il quelque chose d’autre, spécifique au navigateur, qu’il fait ?

Je n’ai pas essayé récemment, il est donc possible que des changements aient été apportés que le scraper ne peut pas gérer pour le moment.

@riking a remarqué que Google Takeout exporte des fichiers mbox pour les propriétaires de groupes, ce qui pourrait être une option à examiner.

5 « J'aime »

Merci. Bon, il y a une semaine, cela a fonctionné pour un deuxième site, puis j’ai mis à jour mon fichier de cookies une dernière fois et les données du premier site ont été téléchargées. Cela n’a semblé fonctionner que pendant un jour ou deux, et maintenant, cela ne fonctionne plus, ni pour l’un ni pour l’autre site. Je vois l’adresse e-mail complète dans mon navigateur, je télécharge les cookies pour cet onglet, mais rien ne se passe.

Je vais regarder le takout. EDIT : Bon, pour obtenir le fichier mbox, il semble que vous deviez être un super administrateur, et pas seulement un propriétaire.

4 « J'aime »

Un outil en ligne de commande permettant de convertir une liste de diffusion Mailman2 (c’est-à-dire le contenu du fichier config.pck avec options, membres, modérateurs, drapeaux privés ou publics, etc.) en une catégorie Discourse est disponible ici : Client Challenge

1 « J'aime »

@gerhard As-tu des idées pour adapter ces instructions afin d’utiliser une installation de développement plutôt que l’installation standard ? J’ai l’impression d’avoir presque réussi à faire fonctionner une migration de listserv avec quelques commandes, mais je n’arrive pas à faire fonctionner ce que je suppose être la dernière étape, que ce soit avec l’une ou l’autre des commandes suivantes :

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

Les deux échouent à charger toutes les dépendances. Voir ici pour l’ensemble complet des commandes que j’ai utilisées et les erreurs. As-tu des idées ? Peut-être manque-t-il certains appels d/bundle ?

La prochaine chose que je vais essayer est d’utiliser une machine virtuelle Ubuntu et d’y faire une « installation standard », mais cela semble un peu excessif étant donné que l’installation dev fonctionne par ailleurs très bien.

Je suis un total débutant avec discourse (et ruby, et surtout docker), alors désolé si c’est évident ou (pire) sans rapport !

3 « J'aime »

Il semble que vous ayez compris la majeure partie du processus.

Je n’ai jamais essayé cela avec l’installation de développement basée sur Docker, mais je suppose que vous devez ajouter "gem 'sqlite3'" au Gemfile et exécuter apt install -y libsqlite3-dev à l’intérieur du conteneur avant d’exécuter d/bundle install.

Ensuite, bundle exec ruby ... devrait fonctionner.

3 « J'aime »

@gerhard merci pour le petit rappel – j’ai tout relancé depuis zéro (à partir de git clone) en ajoutant gem 'sqlite3' à la fin de /src/Gemfile, car je pensais que c’était celui que tu voulais dire, et ça a fonctionné ! Pour la trace, voici les instructions que j’ai utilisées (pour la liste de diffusion mne_analysis) :

1. Sur l’hôte 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  # ajouter gem 'sqlite3' à la fin
exit
d/bundle

2. Dans le shell 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  # sans effet pour moi

# vérifier les résultats
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

# paramètres
wget https://raw.githubusercontent.com/discourse/discourse/master/script/import_scripts/mbox/settings.yml -O /shared/import/settings.yml

# lancer le script
cd /src
bundle exec ruby script/import_scripts/mbox.rb /shared/import/settings.yml

Cela a produit pas mal de sorties informatives, et à la fin :

...
Mise à jour des sujets en vedette dans les catégories
        5 / 5 (100,0 %)  [6890 éléments/min]   ]  
Réinitialisation des compteurs de sujets


Terminé (00h 06min 21sec)

Puis quitter et, sur l’hôte Ubuntu :

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

C’est fait !

Je vais probablement ajuster les paramètres pour supprimer le préfixe [Mne_analysis], mais je suis ravi que cela fonctionne déjà si bien !

4 « J'aime »

@gerhard L’importateur mbox peut-il être utilisé uniquement lors de la première installation de Discourse, ou peut-il être utilisé plus tard, alors que d’autres utilisateurs utilisent déjà Discourse ? Si l’importateur est utilisé alors que Discourse est en cours d’utilisation par d’autres, verront-ils des effets secondaires ?

1 « J'aime »

Pour que l’importateur puisse extraire les messages de Google Groups, j’ai dû annuler ce changement dans /script/import_scripts/google_groups.rb
https://review.discourse.org/t/fix-google-groups-import-changed-login-url-9432/10615
J’ai remplacé la ligne

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

par

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

Sinon, j’obtenais systématiquement ce message :

Connexion en cours...
Échec de la connexion. Veuillez vérifier le contenu de votre fichier cookies.txt
6 « J'aime »

@gerhard J’ai remarqué qu’après l’importation, bien que les messages semblent corrects, il n’y a aucun utilisateur mis en attente (staged), alors qu’il devrait y en avoir (j’ai utilisé staged: true par défaut). Les résultats affichés sont les suivants :

...
indexation des réponses et des utilisateurs

création des catégories
        1 / 1 (100,0 %)  [13440860 éléments/min]  
création des utilisateurs

création des sujets et des messages
     7399 / 7399 (100,0 %)  [1421 éléments/min]     
...

Un compteur d’utilisateurs devrait-il également être affiché ?

J’ai également essayé d’exécuter avec staged: false et le même résultat a été affiché ; aucun des utilisateurs de la liste de diffusion ne fait partie de groupes. Au cas où cela aiderait à voir ce qui est réellement traité, voici l’un des nombreux fichiers .mbox en cours d’importation :

2020-December.zip (49,5 Ko)

Le seul paramètre non par défaut ajouté était :

tags:
  "Mne_analysis": "mne_analysis"

Il serait idéal que ces utilisateurs apparaissent comme étant mis en attente, afin qu’ils puissent réclamer leurs anciens messages lors de leur inscription. Toute astuce ou idée est donc la bienvenue !

1 « J'aime »

Il devrait probablement accepter les deux, non ?