Mas não consigo listar arquivos porque eles estão no seu bucket e tenho certeza de que preciso de credenciais para uma lista.
rake uploads:fix_missing_s3 parece ter puxado (a maioria?) das coisas para o sistema de arquivos local (os uploads ainda não estão no s3 para este site)
Então eu fiz isso para consertar os uploads:
def fix_bad_uploads(bad_uploads)
fixed = 0
retrieved = 0
missing = 0
bad_bucket="//discourse-cloud-file-uploads.s3.dualstack.us-west-2.amazonaws.com/business6/uploads/forumosa"
bad_uploads.each do |upload|
url = URI.parse("https:"+upload.url)
upload.url=upload.url.gsub(bad_bucket,"/uploads/default")
if File.exists?("/shared/#{upload.url}")
fixed += 1
print "1"
upload.save
# posts = Post.where("raw like '%#{upload.short_url}%'")
# posts.each do |post|
# post.rebake!
# print "."
# end
else
begin
# retrieve missing
filename = "/shared#{upload.url}"
dirname = File.dirname(filename)
unless File.directory?(dirname)
FileUtils.mkdir_p(dirname)
end
file = File.new(filename, "w")
Net::HTTP.start(url.host) do |http|
resp = http.get(url.path)
open(file, "wb") do |file|
file.write(resp.body)
end
end
file.close
print "+"
upload.save if File.exists?(filename)
rescue => e
puts "bad: #{e}"
missing += 0
sleep 1
print "0"
end
end
end
end
Isso consertou a maioria deles. Mas parece haver algumas postagens que têm uma entrada uploads:// para a qual não há um Upload no banco de dados. Rebaking essas acaba com um transparent.png.
Então eu tentei algo como isto:
def get_missing_short_url(short_url)
prefix = "https://discourse-cloud-file-uploads.s3.dualstack.us-west-2.amazonaws.com/business6/uploads/forumosa/original/3X"
remove_url = "https://discourse-cloud-file-uploads.s3.dualstack.us-west-2.amazonaws.com/business6/uploads/forumosa/"
sha1= Upload.sha1_from_short_url(short_url)
extension = short_url.split(".").last
upload = Upload.find_by(sha1: sha1)
if !upload
# try to find it in s3
one = sha1[0]
two=sha1[1]
url_link = "#{prefix}/#{one}/#{two}/#{sha1}.#{extension}"
puts "URL: #{url_link}"
sleep 1
url = URI.parse(url_link)
full_filename = url_link.gsub(remove_url,"/shared/uploads/default/")
filename = "/tmp/#{File.basename(url_link.gsub(remove_url,"/shared/uploads/default/"))}"
dirname = File.dirname(filename)
unless File.directory?(dirname)
FileUtils.mkdir_p(dirname)
end
File.open(filename, "w") do |file|
Net::HTTP.start(url.host) do |http|
resp = http.get(url.path)
open(file, "wb") do |file|
file.write(resp.body)
end
end
end
# make upload for file
File.open(filename, "r") do |file|
upload = UploadCreator.new(
file,
File.basename(file),
).create_for(Discourse.system_user.id)
end
if upload.persisted?
puts "We did it! #{upload.id}"
else
puts "darn. #{upload.errors.full_messages}"
sleep 5
end
File.open(filename, "w") do |file|
Net::HTTP.start(url.host) do |http|
resp = http.get(url.path)
open(file, "wb") do |file|
file.write(resp.body)
end
end
end
end
upload
end
Isso funciona na maioria das vezes, mas em meus testes, às vezes falho em inferir o URL S3 correto do sha que infiro do URL curto. Não tenho certeza de como consertar isso.
Além disso, um deles acabou de alguma forma com um sha que era diferente do que estava no nome do arquivo do caminho S3.
Meu pensamento atual agora é começar passando por todos os cooked e obtendo todos os URLs https://discourse-cloud-file-uploads e, em seguida, atualizando os registros Upload que se referem a eles e criando os que estão faltando.
Estou perdendo algo óbvio?