使用开放 URI 和大小小于 10kb 的回形针存储图像

发布于 2024-11-15 04:14:52 字数 472 浏览 3 评论 0原文

我想从我的旧网站导入一些图标。这些图标的大小小于 10kb。因此,当我尝试导入图标时,它会返回 stringio.txt 文件。

require "open-uri"
class Category < ActiveRecord::Base
   has_attached_file :icon,  :path => ":rails_root/public/:attachment/:id/:style/:basename.:extension"
  def icon_from_url(url)
    self.icon = open(url)
   end    
end

在耙子任务中。

   category = Category.new
   category.icon_from_url "https://xyz.com/images/dog.png"
   category.save

I want to import some icons from my old site. The size of those icons is less than 10kb. So when I am trying to import the icons its returning stringio.txt file.

require "open-uri"
class Category < ActiveRecord::Base
   has_attached_file :icon,  :path => ":rails_root/public/:attachment/:id/:style/:basename.:extension"
  def icon_from_url(url)
    self.icon = open(url)
   end    
end

In rake task.

   category = Category.new
   category.icon_from_url "https://xyz.com/images/dog.png"
   category.save

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

羁拥 2024-11-22 04:14:52

尝试:

def icon_from_url(url)
  extname = File.extname(url)
  basename = File.basename(url, extname)

  file = Tempfile.new([basename, extname])
  file.binmode

  open(URI.parse(url)) do |data|  
    file.write data.read
  end

  file.rewind

  self.icon = file
end

Try:

def icon_from_url(url)
  extname = File.extname(url)
  basename = File.basename(url, extname)

  file = Tempfile.new([basename, extname])
  file.binmode

  open(URI.parse(url)) do |data|  
    file.write data.read
  end

  file.rewind

  self.icon = file
end
呆橘 2024-11-22 04:14:52

要覆盖 Paperclip 中“假文件上传”的默认文件名(小文件上的 stringio.txt 或大文件上几乎随机的临时名称),您有两种主要可能性:

定义一个 original_filename IO 上的

def icon_from_url(url)
  io = open(url)
  io.original_filename = "foo.png"
  self.icon = io
end

您还可以从 URI 获取文件名:

io.original_filename = File.basename(URI.parse(url).path)

或者替换 :path 中的 :basename

has_attached_file :icon, :path => ":rails_root/public/:attachment/:id/:style/foo.png", :url => "/:attachment/:id/:style/foo.png"

请记住始终更改 :网址 时您更改 :path,否则 icon.url 方法将是错误的。

您还可以定义自己的自定义插值(例如 :rails_root/公共/:无论如何)。

To override the default filename of a "fake file upload" in Paperclip (stringio.txt on small files or an almost random temporary name on larger files) you have 2 main possibilities:

Define an original_filename on the IO:

def icon_from_url(url)
  io = open(url)
  io.original_filename = "foo.png"
  self.icon = io
end

You can also get the filename from the URI:

io.original_filename = File.basename(URI.parse(url).path)

Or replace :basename in your :path:

has_attached_file :icon, :path => ":rails_root/public/:attachment/:id/:style/foo.png", :url => "/:attachment/:id/:style/foo.png"

Remember to alway change the :url when you change the :path, otherwise the icon.url method will be wrong.

You can also define you own custom interpolations (e.g. :rails_root/public/:whatever).

小耗子 2024-11-22 04:14:52

我想你已经快到了,尝试打开解析的 uri,而不是字符串。

require "open-uri"
class Category < ActiveRecord::Base
   has_attached_file :icon,  :path =>:rails_root/public/:attachment/:id/:style/:basename.:extension"
  def icon_from_url(url)
    self.icon = open(URI.parse(url))
  end    
end

当然这不处理错误

You are almost there I think, try opening parsed uri, not the string.

require "open-uri"
class Category < ActiveRecord::Base
   has_attached_file :icon,  :path =>:rails_root/public/:attachment/:id/:style/:basename.:extension"
  def icon_from_url(url)
    self.icon = open(URI.parse(url))
  end    
end

Of course this doesn't handle errors

旧竹 2024-11-22 04:14:52

您还可以禁用 OpenURI 创建 StringIO 对象,并强制它创建临时文件。请参阅这个答案:

为什么 Ruby open-uri 的 open 在我的单元测试中返回 StringIO,但在我的控制器中返回 FileIO?

You can also disable OpenURI from ever creating a StringIO object, and force it to create a temp file instead. See this SO answer:

Why does Ruby open-uri's open return a StringIO in my unit test, but a FileIO in my controller?

入怼 2024-11-22 04:14:52

过去,我发现检索远程文件最可靠的方法是使用命令行工具“wget”。以下代码大部分是直接从现有的生产 (Rails 2.x) 应用程序复制而来,并进行了一些调整以适合您的代码示例:

class CategoryIconImporter
  def self.download_to_tempfile (url)
    system(wget_download_command_for(url))
    @@tempfile.path
  end

  def self.clear_tempfile
    @@tempfile.delete if @@tempfile && @@tempfile.path && File.exist?(@@tempfile.path)
    @@tempfile = nil
  end

  def self.set_wget
    # used for retrieval in NrlImage (and in future from other sies?)
    if !@@wget
      stdin, stdout, stderr = Open3.popen3('which wget')
      @@wget = stdout.gets
      @@wget ||= '/usr/local/bin/wget'
      @@wget.strip!
    end
  end
  def self.wget_download_command_for (url)
    set_wget
    @@tempfile = Tempfile.new url.sub(/\?.+$/, '').split(/[\/\\]/).last
    command = [ @@wget ]
    command << '-q'
    if url =~ /^https/
      command << '--secure-protocol=auto'
      command << '--no-check-certificate'
    end
    command << '-O'
    command << @@tempfile.path
    command << url
    command.join(' ')
  end

  def self.import_from_url (category_params, url)
    clear_tempfile

    filename = url.sub(/\?.+$/, '').split(/[\/\\]/).last
    found = MIME::Types.type_for(filename)
    content_type = !found.empty? ? found.first.content_type : nil

    download_to_tempfile url

    nicer_path = RAILS_ROOT + '/tmp/' + filename
    File.copy @@tempfile.path, nicer_path

    Category.create(category_params.merge({:icon => ActionController::TestUploadedFile.new(nicer_path, content_type, true)}))
  end
end

rake 任务逻辑可能如下所示:

[
  ['Cat', 'cat'],
  ['Dog', 'dog'],
].each do |name, icon|
  CategoryIconImporter.import_from_url {:name => name}, "https://xyz.com/images/#{icon}.png"
end

这使用 mime-types gem 进行内容类型发现:

gem 'mime-types', :require => 'mime/types'

In the past, I found the most reliable way to retrieve remote files was by using the command line tool "wget". The following code is mostly copied straight from an existing production (Rails 2.x) app with a few tweaks to fit with your code examples:

class CategoryIconImporter
  def self.download_to_tempfile (url)
    system(wget_download_command_for(url))
    @@tempfile.path
  end

  def self.clear_tempfile
    @@tempfile.delete if @@tempfile && @@tempfile.path && File.exist?(@@tempfile.path)
    @@tempfile = nil
  end

  def self.set_wget
    # used for retrieval in NrlImage (and in future from other sies?)
    if !@@wget
      stdin, stdout, stderr = Open3.popen3('which wget')
      @@wget = stdout.gets
      @@wget ||= '/usr/local/bin/wget'
      @@wget.strip!
    end
  end
  def self.wget_download_command_for (url)
    set_wget
    @@tempfile = Tempfile.new url.sub(/\?.+$/, '').split(/[\/\\]/).last
    command = [ @@wget ]
    command << '-q'
    if url =~ /^https/
      command << '--secure-protocol=auto'
      command << '--no-check-certificate'
    end
    command << '-O'
    command << @@tempfile.path
    command << url
    command.join(' ')
  end

  def self.import_from_url (category_params, url)
    clear_tempfile

    filename = url.sub(/\?.+$/, '').split(/[\/\\]/).last
    found = MIME::Types.type_for(filename)
    content_type = !found.empty? ? found.first.content_type : nil

    download_to_tempfile url

    nicer_path = RAILS_ROOT + '/tmp/' + filename
    File.copy @@tempfile.path, nicer_path

    Category.create(category_params.merge({:icon => ActionController::TestUploadedFile.new(nicer_path, content_type, true)}))
  end
end

The rake task logic might look like:

[
  ['Cat', 'cat'],
  ['Dog', 'dog'],
].each do |name, icon|
  CategoryIconImporter.import_from_url {:name => name}, "https://xyz.com/images/#{icon}.png"
end

This uses the mime-types gem for content type discovery:

gem 'mime-types', :require => 'mime/types'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文