Avatars missing after import

I’ve got a vbulletin import for a hosted customer. The avatars have disappeared and are now showing as a generic blank person shape like this.

I’m pretty sure that they were there at some point. The URLs look like the should have something. Is there some way that I can find them?

Maybe related to that?

Do you have a backup where you can check the URL?
Are they in the tombstone?

I did a fresh import and all of the avatars are missing. Sidekiq still has 13M things to process, but I don’t see how that could be the problem. I did another import on another site with what I believe to be the same import script and the avatars are fine there.

pry(main)> User.find_by_username('MysteryManAvatar').uploaded_avatar
=> #<Upload:0x0000558a0d31b478
 id: 97,
 user_id: 114,
 original_filename: "clevername.jpg",
 filesize: 2028,
 width: 90,
 height: 67,
 url: "/uploads/default/original/1X/080817dcf59ddc838054fba9716b62fce9ae3d83.jpg",
 created_at: Thu, 19 Apr 2018 23:51:15 UTC +00:00,
 updated_at: Thu, 19 Apr 2018 23:51:15 UTC +00:00,
 sha1: "080817dcf59ddc838054fba9716b62fce9ae3d83",
 origin: nil,
 retain_hours: nil,
 extension: "jpg">

But that file isn’t in uploads (or tombstone).

I looked at Avatars not showing after import and that didn’t seem to be related.

Я восстановил базу данных из резервной копии (были выполнены миграции базы данных из старой версии, а в файле backup.sql.gz содержался только SQL, без файлов загрузок).

К сожалению, аватары на сайте не отображаются (показывается только заглушка по умолчанию).

Они, похоже, корректно сохранены в базе данных, URL верный, а PNG-файл существует:

root@og-app:/var/www/discourse# rails c
[1] pry(main)> User.find_by_username('Overgrow').uploaded_avatar
=> #<Upload:0x0000565323a78880
 id: 2936,
 user_id: 1,
 original_filename: "avatar.png",
 filesize: 161585,
 width: nil,
 height: nil,
 url:     "/uploads/default/original/2X/f/fbba12aa89b1bc45676efcfa55affd4b7a76edf1.png",
 created_at: Sat, 03 Sep 2016 10:26:23 UTC +00:00,
 updated_at: Sat, 22 Feb 2020 11:57:35 UTC +00:00,
 sha1: "fbbe22aa89b1bc45676efcfa55affd4b7a76edf1",
 origin: nil,
 retain_hours: nil,
 extension: "unknown",
 thumbnail_width: nil,
 thumbnail_height: nil,
 etag: nil,
 secure: false,
 access_control_post_id: nil,
 original_sha1: nil>

Подскажите, пожалуйста, что можно попробовать сделать дальше? Заранее спасибо!

Обновление:

Некоторые аватары были пересозданы в фоновом режиме.. Можно ли ускорить этот процесс? Или запустить его вручную?

Судя по моим наблюдениям, может ли эта часть указывать на проблему?

extension: "unknown",

Кажется, что у пересозданных аватаров теперь это поле заполнено:

extension: "JPG",

Каким-то образом после восстановления резервной копии и миграции с версии 1.6 на 2.5 в базе данных Discourse отсутствовали значения width, height и extension для таблицы Upload (указатели на файлы были верными, а сами файлы на своих местах).

В итоге я написал скрипт, который проходит по всем пользовательским аватарам, загруженным вручную, исправляет расширение, размеры и заново генерирует все OptimizedImages с миниатюрами версии 2, которых мне не хватало.

Для тех, кому это интересно, вот он:

fix-avatars.rb

require File.expand_path("../../config/environment", __FILE__)

generated_count = 0

scope = UserAvatar.where("custom_upload_id > 0")

scope.find_each do |ua|

  upload_id = ua.custom_upload_id

  upload = Upload.find_by(id: upload_id)
  
  unless upload
    puts "\nне найдена загрузка для этого аватара пользователя"
    next
  end
  
  # исправление неизвестного
  if upload.extension === 'unknown'
    upload.extension = nil 
    upload.save!
    puts "\rupload_id #{upload.id} расширение unknown -> nil"
  end

  if upload.extension.nil?
    puts "\rupload_id #{upload.id} исправление расширения"

    upload.fix_image_extension

    if upload.height == 0 || upload.width == 0
      puts "\rupload_id #{upload.id} исправление размеров"
      upload.fix_dimensions!
    end

    # проверка оптимизированной версии
    correct_optimized = OptimizedImage.where(upload_id: upload_id)
      .where(version: 2)

    if correct_optimized.count < 1
      puts "\rupload_id #{upload.id} отсутствуют миниатюры версии 2"

      # удаление старых оптимизированных
      puts "\rupload_id #{upload.id} удаление аватаров"
      optimized = OptimizedImage.where(upload_id: upload_id)

      if optimized
        optimized.destroy_all
      end

      # генерация оптимизированных
      puts "\rupload_id #{upload.id} создание аватаров"
      Discourse.avatar_sizes.each {|size| OptimizedImage.create_for(upload, size, size, allow_animation: SiteSetting.allow_animated_avatars)}

      generated_count += 1

      puts "\rСгенерировано всего аватаров: #{generated_count}"

    end
  end

end