Atualizar URLs dentro de uma enquete após alterar o CDN

Criei uma enquete no meu fórum assim:

[poll name=freestyle type=multiple results=always min=1 max=14 public=true chartType=bar]
* **#1** ![DSC_2281.jpg|332x500, 33%](upload://ujMDcnd4syevNGdEN2O1qUTeWeK)
* **#2** ![IMG_3248.jpg|690x459, 33%](upload://tsecEjlruXEpg3faidWmENBupM4)
[/poll]

Migrei de uma CDN para nenhum CDN, e os URLs foram alterados de cdn.unicyclist.com para unicyclist.com.

No entanto, os URLs das imagens aqui continuam quebrados, apesar de aparecerem na prévia da postagem:

Reprocessar as postagens e executar rake 'posts:remap[cdn.unicyclist.com,unicyclist.com]' não resolveu o problema.

O ask.discourse.org sugere:

O que provavelmente está acontecendo

As opções da sua enquete não estão apenas no raw da postagem. No esquema do seu site, as enquetes também armazenam o HTML renderizado das opções em:

  • polls
  • poll_options.html

Então a prévia da postagem pode parecer correta, mas o renderizador da enquete ainda pode estar usando HTML desatualizado com o antigo hostname da CDN.

Documentação relacionada:

Aviso importante

Faça um backup completo primeiro.

Além disso, evite “apenas editar” a enquete se ela tiver votos, porque edições em enquetes normalmente limpam os votos:

Abordagem mais segura: inspecione uma enquete quebrada primeiro

No container:

cd /var/discourse
./launcher enter app
rails c

Então encontre a enquete daquela postagem:

poll = Poll.find_by(post_id: POST_ID, name: "freestyle")
PollOption.where(poll_id: poll.id).pluck(:id, :html)

Se você vir cdn.unicyclist.com naquele HTML, isso confirma.

Corrigir essa única enquete

poll = Poll.find_by(post_id: POST_ID, name: "freestyle")

PollOption.where(poll_id: poll.id).find_each do |opt|
  new_html = opt.html.gsub("cdn.unicyclist.com", "unicyclist.com")
  opt.update_columns(html: new_html, updated_at: Time.zone.now)
end

Depois, reprocessar essa postagem também:

Post.find(POST_ID).rebake!

Se funcionar, corrigir em massa todas as opções de enquete

PollOption.find_each do |opt|
  next unless opt.html&.include?("cdn.unicyclist.com")
  opt.update_columns(
    html: opt.html.gsub("cdn.unicyclist.com", "unicyclist.com"),
    updated_at: Time.zone.now
  )
end

Por que posts:remap não ajudou

Porque essa tarefa rake é para conteúdo de postagens, enquanto suas referências de imagens quebradas provavelmente estão no cache do HTML das opções da enquete em vez disso:

Recomendação

  1. testar em uma enquete quebrada
  2. confirmar se as imagens carregam
  3. apenas então executar a correção em massa

Se quiser, posso escrever um script para copiar e colar onde você só substitui POST_ID e executa com segurança em uma única enquete primeiro.

Isso parece bom para você? Vou fazer um backup primeiro, obviamente, mas prefiro evitar ter que restaurar meu fórum.

Preciso manter todos os resultados das enquetes :slight_smile:

Pergunta bônus: o Discourse deveria lidar nativamente com esses casos?

Acabei de ler esta postagem e, se você ainda não tiver resolvido isso, acho que você pode fazer isso usando a função integrada discourse remap.

Diferente da tarefa rake, discourse remap usa DbHelper.remap, que executa uma busca global por expressão regular e substituição em todas as colunas de texto em todas as tabelas do banco de dados PostgreSQL. Ele deve encontrar e atualizar com sucesso as URLs de CDN cozidas presas dentro de poll_options.html (assim como em quaisquer outras tabelas que a tarefa rake ignore).

cd /var/discourse
./launcher enter app
# crie um backup de segurança
discourse backup
# execute o remapeamento global (apenas o domínio, sem protocolo, para capturar todas as variações)
discourse remap 'cdn.unicyclist.com' 'unicyclist.com'
# limpe o cache do redis (crucial, pois o discourse armazena em cache o HTML cozido intensamente)
rake cache:clear

Fiz algo semelhante aqui (mas no sentido inverso): Chat thumbnails bypass s3_cdn_url & use raw S3 bucket URLs - #8 by Lilly