Mais je ne peux pas lister les fichiers car ils sont sur votre bucket et je suis à peu près sûr d’avoir besoin d’identifiants pour une liste.
rake uploads:fix_missing_s3 semble avoir récupéré (la plupart ?) des éléments vers le système de fichiers local (les téléchargements ne sont pas encore sur s3 pour ce site)
J’ai donc fait ceci pour corriger les téléchargements :
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
Cela a corrigé la plupart d’entre eux. Mais il semble y avoir des messages qui ont une entrée uploads:// pour laquelle il n’y a pas d’Upload dans la base de données. Les refaire aboutit à un transparent.png.
J’ai donc essayé quelque chose comme ceci :
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
Cela fonctionne en grande partie, mais dans mes tests, j’échoue parfois à déduire la bonne URL S3 à partir du sha que je déduis de l’URL courte. Je ne suis pas sûr de la façon de corriger cela.
De plus, l’un d’eux a fini par avoir un sha différent de celui du nom de fichier du chemin s3.
Ma pensée actuelle est de commencer par parcourir tous les cooked et de récupérer toutes les URL https://discourse-cloud-file-uploads, puis de mettre à jour les enregistrements Upload qui y font référence et de créer ceux qui manquent.
Est-ce que je rate quelque chose d’évident ?