0

我正在努力使用 ruby​​ 脚本使用他们的 http 界面将一些图片上传到 moodstocks

这是我到目前为止的代码

curb = Curl::Easy.new
curb.http_auth_types = :digest
curb.username = MS_API
curb.password = MS_SECRET
curb.multipart_form_post = true

Dir.foreach(images_directory) do |image|
  if image.include? '.jpg'
    path = images_directory + image
    filename = File.basename(path, File.extname(path))

    puts "Upload #{path} with id #{filename}"

    raw_url = 'http://api.moodstocks.com/v2/ref/' + filename
    encoded_url = URI.parse URI.encode raw_url

    curb.url = encoded_url
    curb.http_put(Curl::PostField.file('image_file', path))
  end
end

这是我得到的错误

/Library/Ruby/Gems/2.0.0/gems/curb-0.8.5/lib/curl/easy.rb:57:in `add': no implicit        conversion of nil into String (TypeError)
    from /Library/Ruby/Gems/2.0.0/gems/curb-0.8.5/lib/curl/easy.rb:57:in `perform'
    from upload_moodstocks.rb:37:in `http_put'
    from upload_moodstocks.rb:37:in `block in <main>'
    from upload_moodstocks.rb:22:in `foreach'
    from upload_moodstocks.rb:22:in `<main>'

我认为问题在于我如何为 http_put 方法提供参数,但我试图寻找一些 Curl::Easy.http_put 的例子,但到目前为止什么也没找到。

任何人都可以向我指出一些有关它的文档或帮助我解决这个问题。

先感谢您

4

1 回答 1

2

这里有几个问题:

1. URI::HTTP 代替字符串

首先,TypeError您遇到的原因是您传递了一个URI::HTTP实例 ( encoded_url)curb.url而不是一个普通的 Ruby 字符串。

您可能想使用encoded_url.to_s,但问题是为什么要在这里进行解析/编码?

2. PUT w/multipart/form-data

第二个问题与遏制有关。在撰写本文时(v0.8.5),遏制不支持multipart/form-data使用编码执行 HTTP PUT 请求的能力。

如果您参考源代码,您可以看到:

  1. multipart_form_post设置仅用于 POST 请求,
  2. 设置put_data器不支持Curl::PostField-s

要解决您的问题,您需要一个 HTTP 客户端库,它可以结合 Digest Authentication、multipart/form-data 和 HTTP PUT。

在 Ruby 中,您可以使用rufus-verbs,但您需要使用rest-client来构建多部分正文。

还有HTTParty,但它与 Digest Auth 有问题。

这就是为什么我强烈建议继续使用 Python 并使用Requests

import requests
from requests.auth import HTTPDigestAuth
import os

MS_API_KEY = "kEy"
MS_API_SECRET = "s3cr3t"

filename = "sample.jpg"

with open(filename, "r") as f:
  base = os.path.basename(filename)
  uid = os.path.splitext(base)[0]

  r = requests.put(
    "http://api.moodstocks.com/v2/ref/%s" % uid,
    auth = HTTPDigestAuth(MS_API_KEY, MS_API_SECRET),
    files = {"image_file": (base, f.read())}
  )

  print(r.status_code)
于 2014-03-18T11:53:46.363 回答