Generating missing optimized images with S3

After our migration (back) to Amazon S3, we appear to have quite a few images where the optimized versions are missing, but the full-size ones are there (example).

There is a Rake task for regenerating optimized images, but it only appears to work with local storage. How would I do this with remote images?

إعجابَين (2)

A question for @zogstrip I think!

Still waiting for an update on this.

We have some quite noticeable missing post images, and had at least one broken scaled avatar…

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

I’m afraid you’ll have to write your own rake task for that. Here’s some pseudo code on how I’d start

FOR EACH oi IN optimized_images
   IF file_exists_on_s3?(oi.upload.url) AND NOT file_exists_on_s3?(oi.url) THEN
       OptimizedImage.create_for(oi.upload, oi.width, oi.height)
   END IF 
END FOR
إعجاب واحد (1)

@uppfinnarn Did you manage to solve this?

I just migrated to S3, and indeed the /optimized/ folder is not transferred in the migration. I’d like to get rid of the /optimized/ folder, as it adds significant weight to my daily backup.

I’m not sure if the following is complete, but this rails console command removes all optimized images then regenerates the ones used for avatars:

OptimizedImage.destroy_all
UserAvatar.all.each {|ua| uaid = ua.gravatar_upload_id || ua.custom_upload_id; Jobs::CreateAvatarThumbnails.perform_async(upload_id: uaid) if uaid }
4 إعجابات

As a followup to the above command, doing a rake posts:rebake will regenerate all(?) of the other missing optimized images.

4 إعجابات

فريق العمل، لقد علقت في موقف يتعلق بـ الصورة الشخصية وأهدرت حوالي 6 ساعات من وقتي :frowning: لكنني وجدت الحل المثالي، لذا سأشاركه هنا.

التخزين: استخدام AWS S3 مع CDN في المقدمة.

المشكلة 1: كنت قادرًا على رفع الصورة الشخصية من منطقة تغيير الصورة الشخصية، لكنها لم تظهر في الملف الشخصي. قمت بتحديث كودي إلى أحدث إصدار من Discourse وبدأت الصورة الشخصية بالظهور في واجهة المستخدم :slight_smile:

الكود القديم - لم يكن يعرض الصورة الشخصية


module FileStore

  class S3Store < BaseStore
     ...
    def path_for(upload)
      url = upload&.url
      if url && url[/^\/[^\/]/]
        FileStore::LocalStore.new.path_for(upload)
      else
        url
      end
    end
     ...
  end
end

الحل: أحدث كود - بدأ في عرض الصورة الشخصية للرفع الجديد

module FileStore

  class S3Store < BaseStore
     ...
    def path_for(upload)
      url = upload&.url
      FileStore::LocalStore.new.path_for(upload) if url && url[/^\/[^\/]/]
    end
     ...
  end
end

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

المشكلة 2: أنا وفريقي حاولنا تغيير الصور الشخصية قبل إصلاح الخطأ المذكور أعلاه في المشكلة 1. وقد أدى ذلك إلى إنشاء العديد من الإدخالات في جدول uploads بقيمة unknown في عمود extension. لم يكن الكود يعالج الصورة الشخصية بشكل صحيح في عملية تحسين الصور (النموذج: OptimizedImage) بسبب مسار ملف S3 الخاطئ.

لذلك، وجدت أيضًا حلاً بديلاً لإصلاح هذه النوعية من الإدخالات التي حدثت قبل إصلاح كودي.

الحل

متعدد المواقع
يمكننا تشغيل الكود أدناه مباشرة في وحدة تحكم Rails في الإنتاج - أو باستخدام مهمة rake.

RailsMultisite::ConnectionManagement.each_connection do |db|
  Upload.where(extension: "unknown").each do |upload|
    upload.update(extension: File.extname(upload.url).gsub(".",""))
  end
  OptimizedImage.destroy_all
  UserAvatar.all.each {|ua| uaid = ua.gravatar_upload_id || ua.custom_upload_id; 
  Jobs::CreateAvatarThumbnails.perform_async(upload_id: uaid) if uaid }
end

عادي - موقع واحد
يمكننا تشغيل الكود أدناه مباشرة في وحدة تحكم Rails في الإنتاج - أو باستخدام مهمة rake.

Upload.where(extension: "unknown").each do |upload|
  upload.update(extension: File.extname(upload.url).gsub(".",""))
end
OptimizedImage.destroy_all
UserAvatar.all.each {|ua| uaid = ua.gravatar_upload_id || ua.custom_upload_id; 
Jobs::CreateAvatarThumbnails.perform_async(upload_id: uaid) if uaid }

أعتقد أن هذا سيساعد الكثير من الناس :slight_smile:

شكرًا لكم

إعجابَين (2)

@supermathie شكرًا لك على النصيحة. إذا بدا أن جميع الصور المحسنة لصور الرموز مفقودة، فهل من المرجح أن يكون تشغيل السطر الثاني كافيًا؟

UserAvatar.all.each {|ua| uaid = ua.gravatar_upload_id || ua.custom_upload_id; Jobs::CreateAvatarThumbnails.perform_async(upload_id: uaid) if uaid }

لقد قمت بالفعل بإعادة تحميص المنشورات، وهو ما استغرق وقتًا طويلًا. لذا، سأفضل تجنب حذف الملفات المحسنة الموجودة لصور المنشورات إذا أمكن.

إعجابَين (2)

ربما، ولكن من الممكن جدًا أن يكون الكود قد تغير؛ لم ألقِ نظرة عليه منذ فترة.

سأستفسر…

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

شكرًا لك @supermathie، أقدر ذلك حقًا! :slight_smile:

لذا قمت بتجربة الأمر (السطر الثاني فقط)، لكنه لا يبدو أنه يعمل. فقد أعاد الكثير من السجلات مثل:

id: 1234,
user_id: 1234,
custom_upload_id: nil,
gravatar_upload_id: nil,
last_gravatar_download_attempt: Thu, 07 May 2015 09:40:35 UTC +00:00,
created_at: Thu, 07 May 2015 09:40:35 UTC +00:00,
updated_at: Thu, 07 May 2015 09:40:36 UTC +00:00>,

وجدت سجلًا واحدًا يحتوي على custom_upload_id مُعيينًا إلى معرف، واستخدمت الأمر التالي للعثور على ملف المستخدم الشخصي: User.find_by(id: 123456)

لكن عند عرض ملفه الشخصي، لا يزال الرمز الظاهر فارغًا. كما يمكنني رؤية أنه لم يتم رفع أي ملفات جديدة إلى S3 مؤخرًا (لا يوجد أي ملف خلال آخر 6 ساعات). لذا أعتقد أن الصور المحسّنة لم يتم إنشاؤها نتيجة لذلك.


الخبر الجيد هو أنه عند البحث عن صورة رمزية عبر أمر rails:

User.find_by_username('username').uploaded_avatar

source

تبدو السجلات صحيحة، وروابط S3 التي تحققت منها حتى الآن تعمل جميعها. وتبدو السجلات متسقة مع مثيل آخر استخدم S3 منذ البداية.

ثم عند استخدام:
OptimizedImage.where(upload_id: upload_id).where(version: 2)

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

إذًا يبدو أنني بحاجة فقط إلى إيجاد طريقة لتحفيز إنشاء صور الرموز المحسّنة.

المثيل الجديد يعمل حاليًا في وضع القراءة فقط، ولا أعرف ما إذا كان هذا عاملًا مؤثرًا. فقد نجح إعادة بناء المنشورات بشكل جيد في وضع القراءة فقط.


تعديل: أرى العديد من الوظائف في sidekiq لإنشاء صور رمزية مصغرة :slight_smile:

لذا ربما أحتاج فقط إلى الخروج من وضع القراءة فقط للسماح بمعالجتها. سأقوم بتحديث النتيجة لاحقًا.

إذن أرى أن مهمة Jobs::CreateAvatarThumbnails تُنفَّذ عبر Sidekiq. لكن لم يتم تحميل أي شيء إلى سلة S3 منذ 9 ساعات. لذا لا أعرف ما الذي يُستدل منه على ذلك.