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?

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…

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

@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 }

Come seguito al comando sopra, eseguire rake posts:rebake rigenererĂ  tutti (?) gli altri immagini ottimizzate mancanti.

Team, mi sono trovato bloccato in una situazione relativa all’immagine del profilo, che mi ha fatto perdere circa 6 ore :frowning: ma ho trovato la soluzione perfetta, quindi la condivido qui.

ARCHIVIAZIONE: Utilizzo di AWS S3 con CDN davanti.

Problema 1: Ero riuscito a caricare l’immagine del profilo dall’area di modifica, ma non veniva visualizzata nel profilo. Ho aggiornato il mio codice all’ultima versione di Discourse e l’immagine del profilo ha iniziato a essere visualizzata nell’interfaccia :slight_smile:

CODICE VECCHIO - Non mostrava l’immagine del profilo

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

SOLUZIONE: CODICE AGGIORNATO - Ha iniziato a mostrare l’immagine del profilo per i nuovi caricamenti

module FileStore

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

Nota: Ragazzi, continuate ad aggiornare regolarmente il vostro codice con l’upstream di Discourse; questo manterrà il vostro codice aggiornato con le correzioni di sicurezza e senza bug.

Problema 2: Io e il mio team abbiamo provato a cambiare le immagini del profilo prima di correggere il bug menzionato nel Problema 1. Ciò ha creato molte voci nella tabella uploads con il valore unknown nella colonna extension. Il codice non elaborava correttamente l’immagine del profilo nel processo di ottimizzazione delle immagini (MODELLO: OptimizedImage) a causa di un percorso file S3 errato.

Quindi, ho anche trovato una soluzione alternativa per correggere questo tipo di voci create prima della mia correzione del codice.

Soluzione

Multi Sito
Possiamo eseguire il codice sottostante direttamente nella console di Rails in produzione - o tramite un task 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

Normale - Singolo Sito
Possiamo eseguire il codice sottostante direttamente nella console di Rails in produzione - o tramite un task 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 }

Penso che questo possa aiutare molte persone :slight_smile:

Grazie

@supermathie Grazie per il tuo consiglio. Se sembra che tutte le immagini ottimizzate per gli avatar siano mancanti, sarebbe sufficiente eseguire semplicemente la seconda riga?

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

Ho giĂ  eseguito un post rebake, che ha richiesto molto tempo. Quindi, idealmente, vorrei evitare di cancellare i file ottimizzati esistenti per le immagini dei post, se possibile.

probabilmente, ma è molto possibile che il codice sia cambiato; non lo controllo da un po’ di tempo.

Farò delle ricerche…

Grazie @supermathie, lo apprezzo molto! :slight_smile:

Quindi ho provato (solo la seconda riga), ma non sembra funzionare. Ha restituito molti record come:

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>,

Ne ho trovato uno con custom_upload_id impostato su un ID e ho recuperato il profilo dell’utente usando: User.find_by(id: 123456)

Tuttavia, quando visualizzo il loro profilo, l’avatar risulta ancora vuoto. Inoltre, posso vedere che non sono stati effettuati nuovi caricamenti su S3 di recente (nessuno nelle ultime 6 ore). Quindi non credo che le immagini ottimizzate vengano generate come conseguenza.


La buona notizia è che quando cerco un avatar tramite un comando Rails:

User.find_by_username('username').uploaded_avatar

source

I record sembrano corretti e gli URL per tutti gli URL S3 che ho controllato finora funzionano. I record sono coerenti con un’altra istanza che ha utilizzato S3 fin dall’inizio.

Poi, quando uso:
OptimizedImage.where(upload_id: upload_id).where(version: 2)

Nell’istanza precedente, vedo un sacco di immagini ottimizzate. Ma nella nuova istanza, non ci sono record. Il che sembra corretto. Per quell’utente con l’ID di caricamento personalizzato impostato, sembrano esserci immagini ottimizzate per lui su S3, ma quei record risalgono a giorni fa.

Quindi sembra che debba solo trovare un modo per attivare la generazione delle immagini avatar ottimizzate.

La nuova istanza è attualmente in modalità sola lettura; non sono sicuro se questo possa essere un fattore. La ricottura dei post sembrava funzionare bene in modalità sola lettura.


Modifica: vedo molti job in Sidekiq per la creazione di miniature degli avatar :slight_smile:

Quindi forse devo solo uscire dalla modalitĂ  sola lettura per permettere loro di essere elaborati. Aggiorno.

Quindi vedo che Jobs::CreateAvatarThumbnails viene eseguito in Sidekiq. Ma nulla è stato caricato nel bucket S3 da 9 ore. Quindi non sono sicuro di cosa pensare.