# 如何从我不拥有的存储桶中提取图像

**URL:** <https://meta.discourse.org/t/how-to-pull-images-from-bucket-i-dont-own/218691>\
**Category:** Product Support\
**Created:** [2022 年2 月 18 日 14:51 UTC](https://meta.discourse.org/t/how-to-pull-images-from-bucket-i-dont-own/218691 "2022-02-18T14:51:37Z")\
**Posts on this page:** 1\
**Showing post:** 4

<div class="post-metadata">

作者： ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)\
发布日期： [2022 年2 月 25 日 17:38 UTC](https://meta.discourse.org/t/how-to-pull-images-from-bucket-i-dont-own/218691/4 "2022-02-25T17:38:54Z")

</div>

> [@Falco](#):
>
> 也许可以创建一个临时脚本，其中：
> 
> 1. 列出文件

但我无法列出文件，因为它们在您的存储桶中，而且我确信我需要凭据才能列出。

`rake uploads:fix_missing_s3` 似乎已将（大部分？）文件提取到本地文件系统（上传文件尚未在 S3 上）。

所以我这样修复了上传文件：

```ruby
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

```

这修复了大部分问题。但似乎有些帖子有一个 `uploads://` 条目，但数据库中没有对应的 `Upload`。重新烘焙它们最终会得到一个 `transparent.png`。

然后我尝试了类似这样的方法：

```plaintext
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

```

这大部分有效，但在我的测试中，有时我无法从我从短 URL 推断出的 sha 中正确推断出 S3 URL。我不确定如何解决这个问题。

另外，其中一个不知何故 ended up with a `sha` that was different from the one in the filename of the s3 path。

我现在想到的方法是，首先遍历所有 `cooked` 并获取所有 `https://discourse-cloud-file-uploads` URL，然后更新指向它们的 `Upload` 记录并创建缺失的记录。

我是否遗漏了什么明显的问题？

---

_[View the full topic](https://meta.discourse.org/t/how-to-pull-images-from-bucket-i-dont-own/218691)._
