Movendo um site que usa integrações do Discourse para comentários

Olá a todos,

Estou usando integrações do Discourse para hospedar comentários em um blog localizado em um subdomínio, mas quero mover o blog para uma subpasta do domínio principal.

Exemplo: atualmente o blog está em

blog.somedomain.com

mas quero movê-lo para

somedomain.com/blog

Como atualizar os tópicos de comentários existentes do Discourse para apontar para a nova localização do blog?

Acho que posso atualizar manualmente o conteúdo dos posts, mas acessar o novo site do blog vai criar novos tópicos, já que eles agora estão em uma URL diferente?

(O blog é um blog Ghost, caso isso seja relevante)

Qualquer ajuda é bem-vinda.
Brad

1 curtida

Lidei com algo semelhante a isso recentemente. Nesse caso, o site já havia alterado o domínio do blog. O resultado disso foi que tópicos duplicados foram criados no Discourse para qualquer postagem do blog que já tivesse gerado tópicos no Discourse.

A solução foi executar um script no console Rails do site para encontrar todas as entradas TopicEmbed que tivessem um embed_url no domínio antigo. Esses valores de embed_url foram então atualizados para o domínio correto após a exclusão da entrada TopicEmbed do tópico duplicado. Os novos tópicos que haviam sido gerados foram então excluídos.

Isso parece uma maneira difícil de resolver o problema. Posso postar detalhes sobre o script que usei, mas seria ótimo ouvir se alguém mais tem ideias sobre como abordar o problema. É algo que certamente surgirá de vez em quando com tópicos incorporados.

1 curtida

Olá Simon,

Obrigado.

Isso seria incrível (e qualquer informação sobre como executá-lo seria útil).

Acho que vou precisar atualizar manualmente o conteúdo dos posts onde há links de volta para o artigo original. (ou seja, a parte do texto do post que diz “Este é um tópico de discussão complementar para a entrada original em…”).

Concordo — algo que raramente precisa ser feito, mas parece uma dor de cabeça total quando acontece.

Brad

Vou compartilhar o script aqui. Tenha em mente que não tenho certeza se essa é a melhor abordagem para o problema. O script precisa ser executado após o início da criação de tópicos duplicados como resultado da mudança de nome de domínio. Como os tópicos só serão criados quando os usuários começarem a visitar suas postagens de blog no novo domínio, provavelmente será necessário executar o script várias vezes para capturar todos os tópicos. Certifique-se de substituir old.domain.com na primeira linha do script pelo domínio real onde seu blog estava anteriormente.

# Execute isto primeiro:
original_embeds = TopicEmbed.where("embed_url LIKE ?", "%old.domain.com%")

# Em seguida:
original_embeds.each do |original_embed|
  original_topic = Topic.find(original_embed.topic_id)
  if (original_topic && original_topic.title)
    possible_dups = Topic.where(title: original_topic.title).order(:created_at)
    if possible_dups.length === 2
      new_embed = TopicEmbed.find_by(topic_id: possible_dups.last.id)
      new_embed_url = new_embed.embed_url
      puts "Destruindo TopicEmbed: #{new_embed.id} Tópico: #{new_embed.topic_id}"
      new_embed.destroy
      puts "Atualizando TopicEmbed: #{original_embed.id} Novo embed_url: #{new_embed_url}"
      original_embed.update(embed_url: new_embed_url)
    end
  end
end

Para executar o script, acesse o console Rails do seu site, copie a primeira linha do script para o console e execute-a. Isso definirá a variável original_embeds como um array de registros TopicEmbed. Uma vez feito isso, você pode copiar o restante do script para o console e executá-lo.

Por segurança, você deve criar um backup do banco de dados do seu site antes de executar o script. Também seria uma boa ideia fazer uma execução de teste (dry run) do script que não realiza nenhuma alteração. Isso funcionará para esse fim:

original_embeds.each do |original_embed|
  original_topic = Topic.find(original_embed.topic_id)
  if (original_topic && original_topic.title)
    possible_dups = Topic.where(title: original_topic.title).order(:created_at)
    if possible_dups.length === 2
      new_embed = TopicEmbed.find_by(topic_id: possible_dups.last.id)
      new_embed_url = new_embed.embed_url
      puts "(Execução de teste) Destruindo TopicEmbed: #{new_embed.id} Tópico: #{new_embed.topic_id}"
      #new_embed.destroy
      puts "(Execução de teste) Atualizando TopicEmbed: #{original_embed.id} Novo embed_url: #{new_embed_url}"
      #original_embed.update(embed_url: new_embed_url)
    end
  end
end

Certifique-se de que a saída pareça razoável antes de descomentar as linhas que realizam as alterações reais no seu banco de dados.

O que o script está fazendo:

  • a variável original_embeds é definida com todos os registros TopicEmbed que correspondem ao domínio antigo do seu blog

  • para cada um dos original_embeds, ele tenta encontrar um tópico com um título duplicado (o novo embed duplicado)

  • se um tópico duplicado for encontrado e um registro TopicEmbed for encontrado para o tópico duplicado, esse registro TopicEmbed é excluído e o valor da propriedade embed_url é transferido para o registro TopicEmbed antigo.

Recomendo fortemente fazer uma execução de teste (usando o segundo script desta postagem) antes de executar o script que realmente realiza alterações. Se houver erros retornados na execução de teste, você precisará identificar o que os está causando. Analisando o código agora, vejo um possível problema que pode ocorrer se houver um tópico no seu site Discourse com um título duplicado em relação a um tópico incorporado, mas sem um TopicEmbed associado. Se for esse o caso, é algo que pode ser resolvido.

3 curtidas

Olá Simon,

Isso foi realmente útil. Obrigado.

No meu caso, acho que as coisas são ainda mais simples, já que o site do blog ainda não foi movido e não tenho duplicatas. Acredito que tudo o que preciso fazer é atualizar as entradas de embed existentes com a nova URL.

Nunca usei Ruby antes, mas com base no seu exemplo, montei o script abaixo. Além de atualizar os embeds de tópicos, estendi-o para também atualizar o texto e os links nas postagens associadas.

Você se importaria de dar uma olhada rápida para garantir que estou no caminho certo? Executei-o com as atualizações comentadas e parece estar exibindo o conteúdo correto.

(a propósito: qual é a maneira normal de executar esses scripts? Tenho editado em um editor de texto e depois colado no console)

Brad

original_embeds = TopicEmbed.where("embed_url LIKE ?", "https://blog.cantabilesoftware.com%")

old_url_prefix = "https://blog.cantabilesoftware.com/"
new_url_prefix = "https://www.cantabilesoftware.com/blog/"
original_embeds.each do |original_embed|

    new_embed_url = original_embed.embed_url
    new_embed_url.sub!(old_url_prefix, new_url_prefix)
    puts "Atualizando TopicEmbed: #{original_embed.id} com nova url: #{new_embed_url}"
    #original_embed.update(embed_url: new_embed_url)

    post = Post.find_by(id: original_embed.post_id)
    new_raw = post.raw
    new_raw.gsub!(old_url_prefix, new_url_prefix)
    new_cooked = post.cooked
    new_cooked.gsub!(old_url_prefix, new_url_prefix)

    puts "Atualizando raw com #{new_raw}"
    puts "Atualizando cooked com #{new_cooked}"

    #post.update(raw: new_raw, cooked: new_cooked)
    
end
2 curtidas

Para constar, o procedimento acima funcionou perfeitamente. Aqui está o processo completo que segui:

  1. Configurei o Discourse para modo somente leitura
  2. Criei um backup
  3. Executei o script acima
  4. Verifiquei se as páginas do Discourse foram atualizadas corretamente
  5. Desliguei o blog antigo e iniciei o novo blog
  6. Configurei um redirecionamento do site do blog antigo para o novo
  7. Desativei o modo somente leitura do Discourse
  8. Reconfigurei as integrações do Discourse para bloquear o domínio antigo e aceitar o novo
  9. Configurei as integrações no novo blog.

Muito obrigado, @simon, pela ajuda nisso. :+1:

1 curtida