Comment trouver n'importe quelle image manquante ?

Bien sûr. Voici le texte raw :

"Il semble que \"Fung-Wong\", \"Mario\", ou simplement \"Typhon #16\" fera [atterrir en terre au Japon jeudi](http://www.jma.go.jp/jp/typh/1416l.html) :

![Typhon 16](/uploads/default/35/4608d96d1b27846f.png)"

Et voici le texte cooked :

"<p>Il semble que “Fung-Wong”, “Mario”, ou simplement “Typhon <span class=\"hashtag\">#16</span>” fera <a href=\"http://www.jma.go.jp/jp/typh/1416l.html\" rel=\"nofollow noopener\">atterrir en terre au Japon jeudi</a> :</p>\n<p><div class=\"lightbox-wrapper\"><a class=\"lightbox\" href=\"/uploads/default/original/2X/0/01bb9fb7e29c2b65fd663cdc58705d1720f8fea7.png\" title=\"4608d96d1b27846f.png\"><img src=\"/uploads/default/original/2X/0/01bb9fb7e29c2b65fd663cdc58705d1720f8fea7.png\" alt=\"Typhon 16\" width=\"602\" height=\"500\"><div class=\"meta\">\n<svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\"><use xlink:href=\"#far-image\"></use></svg><span class=\"filename\">4608d96d1b27846f.png</span><span class=\"informations\">800×664</span><svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\"><use xlink:href=\"#discourse-expand\"></use></svg>\n</div></a></div></p>"

Ces textes sont difficiles à lire lorsqu’ils sont compressés sur une seule ligne, voici donc le texte raw mis en forme :

"Il semble que \"Fung-Wong\", \"Mario\", ou simplement
\"Typhon #16\" fera
[atterrir en terre au Japon jeudi]
(http://www.jma.go.jp/jp/typh/1416l.html) :

![Typhon 16](/uploads/default/35/4608d96d1b27846f.png)"

Et voici le texte cooked mis en forme :

"<p>
  Il semble que “Fung-Wong”, “Mario”, ou simplement
  “Typhon <span class=\"hashtag\">#16</span>” fera
  <a href=\"http://www.jma.go.jp/jp/typh/1416l.html\" rel=\"nofollow noopener\">
    atterrir en terre au Japon jeudi
  </a> :
 </p>\n
 <p>
   <div class=\"lightbox-wrapper\">
     <a class=\"lightbox\" href=\"/uploads/default/original/2X/0/01bb9fb7e29c2b65fd663cdc58705d1720f8fea7.png\" title=\"4608d96d1b27846f.png\">
       <img src=\"/uploads/default/original/2X/0/01bb9fb7e29c2b65fd663cdc58705d1720f8fea7.png\" alt=\"Typhon 16\" width=\"602\" height=\"500\">
       <div class=\"meta\">\n
         <svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\">
           <use xlink:href=\"#far-image\"></use>
         </svg>
         <span class=\"filename\">4608d96d1b27846f.png</span>
         <span class=\"informations\">800×664</span>
         <svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\">
           <use xlink:href=\"#discourse-expand\"></use>
         </svg>\n
       </div>
     </a>
   </div>
 </p>"

Pour information, il y a pas mal de publications (plus d’une centaine) comme celle-ci sur mon site :

[1] pry(main)> Post.where("raw ~* :regex AND cooked !~* :regex", regex: '/uploads/default/[0-9]+/').count
=> 135

Vous ne devriez pas avoir différents formats d’URL dans les contenus brut et cuit. Pouvez-vous s’il vous plaît essayer de re-cuire le message ci-dessus ? Vous pouvez le faire via le menu du message Reconstruire le HTML ou avec la commande post.rebake!. Existe-t-il des champs personnalisés de message liés aux “uploads” dans ce message ? Vous pouvez lire tous les champs personnalisés avec la commande post.custom_fields.

Voici tous les autres champs personnalisés de ce message spécifique (avant d’exécuter la commande Rebuild HTML) :

  id: 43,
  user_id: 1,
  topic_id: 36,
  post_number: 3,
  created_at: Mon, 22 Sep 2014 05:05:16 UTC +00:00,
  updated_at: Mon, 22 Sep 2014 05:11:22 UTC +00:00,
  reply_to_post_number: nil,
  reply_count: 0,
  quote_count: 0,
  deleted_at: nil,
  off_topic_count: 0,
  like_count: 0,
  incoming_link_count: 0,
  bookmark_count: 0,
  avg_time: 58,
  score: 1.2,
  reads: 6,
  post_type: 1,
  sort_order: 3,
  last_editor_id: -1,
  hidden: false,
  hidden_reason_id: nil,
  notify_moderators_count: 0,
  spam_count: 0,
  illegal_count: 0,
  inappropriate_count: 0,
  last_version_at: Mon, 22 Sep 2014 05:11:22 UTC +00:00,
  user_deleted: false,
  reply_to_user_id: nil,
  percent_rank: 0.585365853658537,
  notify_user_count: 0,
  like_score: 0,
  deleted_by_id: nil,
  edit_reason: "téléchargé des copies locales des images",
  word_count: 34,
  version: 2,
  cook_method: 1,
  wiki: false,
  baked_at: Sun, 14 Apr 2019 09:28:00 UTC +00:00,
  baked_version: 2,
  hidden_at: nil,
  self_edits: 2,
  reply_quoted: false,
  via_email: false,
  raw_email: nil,
  public_version: 2,
  action_code: nil,
  image_url: "/uploads/default/original/2X/0/01bb9fb7e29c2b65fd663cdc58705d1720f8fea7.png",
  locked_by_id: nil

Je ne vois pas de champ uploads, mais peut-être que image_url est ce que vous recherchez ? Sa valeur — avant d’exécuter la commande Rebuild HTML — était :

/uploads/default/original/2X/0/01bb9fb7e29c2b65fd663cdc58705d1720f8fea7.png

L’exécution de la commande Rebuild HTML semble avoir modifié la valeur du champ image_url en :

https://{{SITE FQDN}}/uploads/default/35/4608d96d1b27846f.png

Toutes les URLs dans le texte cuisiné semblent également avoir été mises à jour :

"<p>
  Il semble que « Fung-Wong », « Mario », ou simplement
  « Typhon <span class=\"hashtag\">#16</span> » sera
  <a href=\"http://www.jma.go.jp/jp/typh/1416l.html\" rel=\"nofollow noopener\">
    à l'atterrissage au Japon jeudi
  </a> :
 </p>\n
 <p>
   <div class=\"lightbox-wrapper\">
     <a class=\"lightbox\" href=\"https://{{SITE FQDN}}/uploads/default/35/4608d96d1b27846f.png\">
       <img src=\"https://{{SITE FQDN}}/uploads/default/35/4608d96d1b27846f.png\" alt=\"Typhon 16\" width=\"602\" height=\"500\">
       <div class=\"meta\">\n
         <svg class=\"fa d-icon d-icon-far-image svg-icon\" aria-hidden=\"true\">
           <use xlink:href=\"#far-image\"></use>
         </svg>
         <span class=\"filename\">4608d96d1b27846f.png</span>
         <span class=\"informations\">800×664</span>
         <svg class=\"fa d-icon d-icon-discourse-expand svg-icon\" aria-hidden=\"true\">
           <use xlink:href=\"#discourse-expand\"></use>
         </svg>\n
       </div>
     </a>
   </div>
 </p>"

Quelle est la relation entre 4608d96d1b27846f.png et 01bb9fb7e29c2b65fd663cdc58705d1720f8fea7.png ? Elles ont les mêmes dimensions et semblent identiques au premier coup d’œil, mais ce sont clairement des fichiers différents :

$ diff /var/discourse/shared/standalone/uploads/default/35/4608d96d1b27846f.png /var/discourse/shared/standalone/uploads/default/original/2X/0/01bb9fb7e29c2b65fd663cdc58705d1720f8fea7.png
Binary files /var/discourse/shared/standalone/uploads/default/35/4608d96d1b27846f.png and /var/discourse/shared/standalone/uploads/default/original/2X/0/01bb9fb7e29c2b65fd663cdc58705d1720f8fea7.png differ

$ ls -l /var/discourse/shared/standalone/uploads/default/35/4608d96d1b27846f.png
-rw-r--r-- 1 chris www-data 150319 Jan 19 01:14 /var/discourse/shared/standalone/uploads/default/35/4608d96d1b27846f.png

$ ls -l /var/discourse/shared/standalone/uploads/default/original/2X/0/01bb9fb7e29c2b65fd663cdc58705d1720f8fea7.png
-rw-r--r-- 1 chris chris 95005 Jul  3 15:25 /var/discourse/shared/standalone/uploads/default/original/2X/0/01bb9fb7e29c2b65fd663cdc58705d1720f8fea7.png

Et, bien sûr, la question à un million de dollars reste : Comment dois-je procéder pour migrer /uploads/default/35/4608d96d1b27846f.png vers le nouveau schéma de téléchargement ?

Il semble que vos téléchargements n’aient pas été correctement migrés vers le nouveau schéma. La modification de SiteSetting.migrate_to_new_scheme = true devrait suffire à régler ce problème. Je ne suis pas certain de la raison pour laquelle cela ne se produit pas dans votre cas. Veuillez vérifier le nombre de téléchargements qui n’ont pas été migrés vers le nouveau schéma. Exécutez les commandes ci-dessous pour obtenir les résultats.

Upload.by_users.where("url NOT LIKE '%/original/_X/%' AND url LIKE '%/uploads/default%'").count
SiteSetting.migrate_to_new_scheme = true
Jobs::MigrateUploadScheme.new.execute(nil)
Upload.by_users.where("url NOT LIKE '%/original/_X/%' AND url LIKE '%/uploads/default%'").count

Non, il ne s’agit pas de champs personnalisés. Vous devez obtenir les valeurs des champs personnalisés via la commande post.custom_fields.

Oh, désolé ! J’ai complètement mal compris ce que vous entendiez par champs personnalisés.

Je pourrais me tromper, mais il ne semble pas que ce post particulier en ait :

[1] pry(main) > Post.find_by(:id => 43).custom_fields
=> {}

Eh bien, c’est intéressant…

[2] pry(main) > Upload.by_users.where("url NOT LIKE '%/original/_X/%' AND url LIKE '%/uploads/default%'").count
=> 0
[3] pry(main) > Post.find_by(:id => 43).image_url
=> "https://{{SITE FQDN}}/uploads/default/35/4608d96d1b27846f.png"

Il semble qu’il n’y ait aucun résultat correspondant à la requête que vous avez fournie. Ce comportement est-il attendu ?

Aussi :

Avez-vous une idée de ce que pourrait être la réponse à cette question ?

Il semble que vos téléchargements aient déjà été migrés vers le nouveau système. Cependant, les publications n’ont pas été correctement redirigées vers les nouvelles URL du système. Ces publications sont désormais dans un état incohérent. Puis-je obtenir vos identifiants de site via un message privé ? Ainsi, je pourrai investiguer davantage lorsque j’aurai du temps libre.

Ah, c’est exactement ce que je craignais. Malheureusement, il s’agit d’une installation privée et je ne suis pas certain d’avoir l’autorisation d’accorder un accès (root) au serveur à un tiers. Je suppose qu’il n’y a rien d’autre que je puisse faire pour diagnostiquer le problème ?

Je constate des images manquantes depuis la fin avril environ, mais je n’ai commencé à m’en occuper que ce soir.

rake posts:missing_uploads
26766 téléchargements de publications sont manquants.

22693 téléchargements sont manquants.
22683 sur 22693 proviennent de l'ancien schéma de téléchargement.
9352 des 535188 publications sont concernées.

Nous sommes sur une version stable… Étant donné les derniers messages dans ce fil, je ne suis pas sûr de savoir quoi faire ensuite.

Édition : J’ai sélectionné un fichier GIF particulier et constaté qu’il manquait dans le répertoire uploads du serveur en production. En revanche, il est présent dans le répertoire tombstone de mon serveur de sauvegarde. J’ai copié ce fichier via scp depuis mon serveur de sauvegarde (discourse/shared/standalone/uploads/tombstone/default/39/ee8670816301d4c4.gif) vers le répertoire tombstone correspondant sur le serveur en production, puis j’ai relancé la tâche rake ci-dessus à titre de test.

L’image s’affiche désormais dans la publication concernée et les chiffres globaux sont maintenant passés à :

26750 téléchargements de publications sont manquants.

22692 téléchargements sont manquants.
22682 sur 22692 proviennent de l'ancien schéma de téléchargement.
9336 des 535190 publications sont concernées.

Il semble que le répertoire tombstone sur le serveur en production fasse 138 Mo, tandis que sur le serveur de sauvegarde il fait 9,5 Go. Je vais donc lancer un rsync de ce répertoire et relancer la tâche rake à nouveau, dans l’espoir que cela réduise encore les comptes signalés.

@kansaichris, il semble que vous n’ayez que 3 messages avec des téléchargements manquants. Dans ce cas, vous devriez modifier manuellement le contenu brut du message avec l’URL correcte du téléchargement.

@skl, vous avez beaucoup de téléchargements de l’ancien schéma. Après avoir copié les téléchargements « tombstone » depuis le serveur de sauvegarde, vous devez exécuter les commandes ci-dessous pour les migrer vers le nouveau schéma.

rake posts:missing_uploads    # assurez-vous que `rsync` a copié les fichiers
rake uploads:recover          # s'il y a des téléchargements manquants après rsync
SiteSetting.migrate_to_new_scheme = true
Jobs::MigrateUploadScheme.new.execute(nil)
Upload.by_users.where("url NOT LIKE '%/original/_X/%' AND url LIKE '%/uploads/default%'").count
# assurez-vous que le compte est 0
rake posts:missing_uploads    # vérifiez à nouveau les statistiques

Merci pour votre aide, @vinothkannans. J’ai suivi vos instructions (cela a pris environ 12 heures pour s’exécuter) et les chiffres ont diminué dans une certaine mesure :

22 614 téléchargements de messages sont manquants.
19 830 téléchargements sont manquants.
19 821 sur 19 830 sont des téléchargements selon l’ancien schéma.
7 339 sur 535 224 messages sont concernés.

Comme il reste encore des téléchargements manquants, j’ai regardé en dehors du dossier tombstone et j’ai constaté que uploads/default sur le serveur en production affiche 22 885 répertoires vides (sur le serveur de sauvegarde, il y en a 10). Il y a également une différence de taille de plus de 10 Go sur la sauvegarde, donc je vais maintenant exécuter rsync pour copier uploads/default depuis la sauvegarde vers le serveur en production, puis réexécuter vos instructions.

Édition : rake posts:missing_uploads semble être une tâche monothread liée au CPU qui tourne depuis plus de 30 heures, j’ai donc temporairement redimensionné le serveur vers une instance CPU dédiée. Les images semblent être revenues pour le moment, bien que selon l’ancien schéma, ce qui suggère qu’une mise à jour de Discourse a probablement provoqué la suppression initiale.

Hmm… s’il n’y a vraiment que 3 publications avec des uploads manquants, pourquoi semble-t-il y en avoir 135 dont le texte brut utilise l’ancien schéma d’upload, alors que le texte formaté utilise le nouveau schéma ?

[1] pry(main)> Post.where("raw ~* :regex AND cooked !~* :regex", regex: '/uploads/default/[0-9]+/').count
=> 135

C’est dû aux incompatibilités de schéma d’URL de téléversement dans les colonnes raw et cooked. La tâche rake posts:missing_uploads vérifie les téléversements uniquement par rapport à la colonne cooked. Vous devez corriger ces URLs de téléversement incompatibles d’une manière ou d’une autre. Je ne peux pas vous aider sans examiner la base de données.

:crossed_fingers:

Ah, d’accord, je ne réalisais pas que la tâche posts:missing_uploads ne vérifie que la colonne cooked — cela expliquerait certainement la divergence. :+1:

Peut-on dire que le processus de migration, lancé en définissant SiteSetting.migrate_to_new_scheme à true, vérifie également uniquement la valeur de la colonne cooked ?

La nouvelle migration de schéma remplacera les URL à la fois dans raw et cooked. Mais cela ne s’est pas produit dans votre cas.

Je le pense. Vous pouvez également vérifier la colonne last_updated_at des messages concernés.

La tâche a échoué avec une erreur et affiche le même message à chaque tentative :

[2019-07-26T09:18:56.829375 #572]  WARN -- : IFD mal formé : méthode `map' non définie pour nil:NilClass
....rake aborted!
ArgumentError : longueur négative -2 fournie
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/exifr-1.3.6/lib/exifr/jpeg.rb:89:in `readframe'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/exifr-1.3.6/lib/exifr/jpeg.rb:116:in `examine'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/exifr-1.3.6/lib/exifr/jpeg.rb:34:in `block in initialize'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/exifr-1.3.6/lib/exifr/jpeg.rb:34:in `open'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/exifr-1.3.6/lib/exifr/jpeg.rb:34:in `initialize'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/discourse_image_optim-0.26.2/lib/image_optim/worker/jhead.rb:40:in `new'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/discourse_image_optim-0.26.2/lib/image_optim/worker/jhead.rb:40:in `oriented?'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/discourse_image_optim-0.26.2/lib/image_optim/worker/jhead.rb:27:in `optimize'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/discourse_image_optim-0.26.2/lib/image_optim.rb:122:in `block (5 niveaux) in optimize_image'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/discourse_image_optim-0.26.2/lib/image_optim/handler.rb:41:in `process'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/discourse_image_optim-0.26.2/lib/image_optim.rb:122:in `block (4 niveaux) in optimize_image'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/discourse_image_optim-0.26.2/lib/image_optim.rb:120:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/discourse_image_optim-0.26.2/lib/image_optim.rb:120:in `block (3 niveaux) in optimize_image'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/discourse_image_optim-0.26.2/lib/image_optim.rb:247:in `block in with_timeout'
Tâches : TOP => posts:missing_uploads

Êtes-vous sur la dernière version ou sur une version plus ancienne ?

Dernière version stable « 2.3.2 +4 »

Vous devrez probablement être sur la dernière version bêta.

Si vous hébergez vous-même, il n’y a pas vraiment de raison d’utiliser la version stable. C’est en fait plus difficile à prendre en charge.

Le client a spécifiquement demandé de rester sur la version stable. Il était catégorique à ce sujet lorsque j’ai repris le projet.