Olá, eu e meu grupo de idiotas malucos estamos muito perto de finalmente migrar nosso fórum Vbulletin3 para o Discourse, depois de termos escrito um script ad-hoc que finalmente conseguiu migrar todas as 21 milhões de respostas do banco de dados original para o Discourse.
Agora, temos o problema dos links para os tópicos/respostas escritos nas próprias respostas.
Na migração que escrevemos, criamos um mapeamento dos IDs “antigos” de tópico e postagem para o que eles mapeiam no Discourse.
Por exemplo:
id | topic_id | name | value | created_at | updated_at
--------+----------+-----------+--------+----------------------------+----------------------------
581727 | 581736 | import_id | 599137 | 2023-02-08 16:30:01.600759 | 2023-02-08 16:30:01.600759
O que eu estava pensando agora é em um plugin que simplesmente intercepte links para o formato antigo do fórum e os transforme com referência ao novo tópico/resposta.
Dispararia uma busca na tabela topics_custom_field usando o valor 123456, encontraria o topic_id do Discourse, então consultaria a tabela topic_links com esse ID e encontraria a url. Finalmente, substituiria no post do lado do cliente (assumindo JavaScript para manipular o conteúdo).
Algo semelhante para as postagens.
No entanto, não consigo encontrar nenhum bom exemplo de como começar a criar algo assim para o Discourse.
Alguém pode me dar algumas dicas, exemplos ou plugins que fariam algo semelhante (verificar respostas em busca de alguma substring e substituí-la, consultar a API? DB? para um valor para recuperar outro?).
Só para confirmar, devo executar essa lógica após a migração ter sido concluída, certo?
Assim, ela percorre todas as respostas novamente e altera os permalinks.
Quando migramos o conteúdo de uma resposta com, por exemplo: https://oldforum.something.com/showthread.php?t=123456 não sabe qual id esse tópico terá no discourse… não?
Infelizmente não podemos usar esse código porque a importação leva uma eternidade para importar 20 milhões de posts e a importação em massa simplesmente não funciona. Faltam peças.
É por isso que tivemos que escrever nosso próprio script de migração. Ele faz tudo (pm, usuários, grupos de usuários, categorias, tópicos, respostas) em cerca de 6 horas com 4 núcleos, 8gb de ram, mas notamos que faltavam os permalinks
Estávamos tentando evitar percorrer todas as mais de 20 milhões de respostas novamente, mas percebemos que soluções alternativas (plugin, redirecionamento nginx, etc.) seriam bastante complicadas ou dependeriam de fatores externos que a tornariam uma solução malfeita, então, simplesmente percorreremos as respostas novamente e processaremos os permalinks. Isso adicionará algum tempo à migração, mas esperançosamente não muito.
Todo o resto é “cozido” na hora, pois sabemos o que “cru” precisa ser convertido em HTML.
Para os permalinks, não podemos fazer isso, pois se um permalink for adicionado com uma edição, ele pode referenciar um tópico que ainda não foi processado (ID de tópico maior) e esses não serem encontrados na tabela topics_custom_field no momento em que está sendo processado.
Tópicos e todas as suas respostas são importados seguindo os IDs de tópicos do menor para o maior no banco de dados vbulletin. Isso também significa que estamos importando em ordem cronológica.
No entanto, isso levaria a pensar que, se você encontrar uma referência a outro tópico, seria sempre para um que já existia.
Mas há casos em que isso não é verdade, apenas alguns exemplos:
Tópico dividido com um comentário que levou à divisão. A divisão seria com um ID maior, mas existente em um tópico com um ID menor.
Edição para leitores futuros em que postagens de tópicos antigos têm referência a outros mais recentes.
Então, sim, enquanto topics_custom_field é gerado e preenchido enquanto a importação progride, como explicado no primeiro tópico, não é confiável fazer isso “em tempo real” porque você não pode ter certeza de encontrar sempre a correspondência correta entre os IDs.
É necessária outra passagem após a conclusão da importação completa.
Sobre TopicCustomField.each do |tcf|, não tenho certeza do que a parte tcf faria. Ruby não é uma linguagem que aprendi. Nosso script é escrito em C#, pois a maioria das pessoas que se ofereceram para trabalhar com ele já o utilizam no trabalho.