ruby-smugmug 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +19 -0
- data/README.md +37 -0
- data/Rakefile +12 -0
- data/lib/ruby-smugmug.rb +8 -0
- data/lib/smugmug/api_category.rb +12 -0
- data/lib/smugmug/api_methods.rb +18 -0
- data/lib/smugmug/client.rb +85 -0
- data/lib/smugmug/exceptions.rb +41 -0
- data/lib/smugmug/http.rb +160 -0
- data/lib/smugmug/version.rb +3 -0
- metadata +87 -0
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2011 Placester, Inc
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
Overview
|
2
|
+
===
|
3
|
+
Library for interacting with the SmugMug 1.3.0 API using OAuth authentication. This does not do any OAuth authorization or setup, it's assumed you're using another gem such as omniauth-oauth that handles that part.
|
4
|
+
|
5
|
+
Compability
|
6
|
+
-
|
7
|
+
Tested against Ruby 1.8.7, 1.9.2, 2.0.0 and JRuby, build history is available [here](http://travis-ci.org/zanker/ruby-smugmug).
|
8
|
+
|
9
|
+
<img src="https://secure.travis-ci.org/zanker/ruby-smugmug.png?branch=master&.png"/>
|
10
|
+
|
11
|
+
Examples
|
12
|
+
-
|
13
|
+
This is just a thin wrapper around the [SmugMug 1.3.0 API](http://wiki.smugmug.net/display/API/API+1.3.0), it's a 1:1 wrapper, so all of the documentation on the SmugMug page applies to this library. You can use any arguments that the SmugMug 1.3.0 documentation shows under the OAuth option.
|
14
|
+
|
15
|
+
client = SmugMug::Client.new(:api_key => "1234-api", :oauth_secret => "4321-secret", :user => {:token => "abcd-token", :secret => "abcd-secret"})
|
16
|
+
|
17
|
+
data = client.users.getStats(:Month => 2, :Year => 2012)
|
18
|
+
puts data # {"Bytes"=>0, "Hits"=>0, "Large"=>0, "Medium"=>0, "Small"=>0, "Video110"=>0, "Video200"=>0, "Video320"=>0, "Video640"=>0, "X2Large"=>0, "X3Large"=>0, "XLarge"=>0}
|
19
|
+
|
20
|
+
data = client.styles.getTemplates
|
21
|
+
puts data # [{"id"=>0, "Name"=>"Viewer Controlled"}, {"id"=>3, "Name"=>"SmugMug"}, {"id"=>4, "Name"=>"Traditional"}, {"id"=>7, "Name"=>"All Thumbs"}, {"id"=>8, "Name"=>"Slideshow"}, {"id"=>9, "Name"=>"Journal (Old)"}, {"id"=>10, "Name"=>"SmugMug Small"}, {"id"=>11, "Name"=>"Filmstrip"}, {"id"=>12, "Name"=>"Critique"}, {"id"=>16, "Name"=>"Journal"}, {"id"=>17, "Name"=>"Thumbnails"}]
|
22
|
+
|
23
|
+
|
24
|
+
Because uploading is a special case and not under the same group of APIs, it's called slightly differently. See http://wiki.smugmug.net/display/API/Uploading for more information or the documentation linked below for a list of arguments.
|
25
|
+
|
26
|
+
client = SmugMug::Client.new(:api_key => "1234-api", :oauth_secret => "4321-secret", :user => {:token => "abcd-token", :secret => "abcd-secret"})
|
27
|
+
data = client.upload_media(:file => File.new("/Users/foobar/Desktop/image.jpeg", :AlbumID => 51343)
|
28
|
+
puts data # {"id"=>1970029991, "Key"=>"rnSfAak", "URL"=>"http://foobar.smugmug.com/Other/Foo/51343_k8W1aR#1970029991_rnSfAak"}
|
29
|
+
|
30
|
+
|
31
|
+
Documentation
|
32
|
+
-
|
33
|
+
See http://rubydoc.info/github/zanker/ruby-smugmug/master/frames for full documentation.
|
34
|
+
|
35
|
+
License
|
36
|
+
-
|
37
|
+
Available under the MIT license, see LICENSE for more information.
|
data/Rakefile
ADDED
data/lib/ruby-smugmug.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
module SmugMug
|
2
|
+
class ApiCategory
|
3
|
+
def initialize(http, category)
|
4
|
+
@http, @category = http, category
|
5
|
+
end
|
6
|
+
|
7
|
+
def method_missing(method, *args)
|
8
|
+
return super unless SmugMug::API_METHODS[@category][method.to_s]
|
9
|
+
@http.request("#{@category}.#{method}", args.pop || {})
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module SmugMug
|
2
|
+
API_METHODS = {
|
3
|
+
"accounts" => {"browse" => true},
|
4
|
+
"albums" => {"applyWatermark" => true, "browse" => true, "changeSettings" => true, "comments" => true, "create" => true, "delete" => true, "get" => true, "getInfo" => true, "getStats" => true, "removeWatermark" => true, "reSort" => true},
|
5
|
+
"albumtemplates" => {"changeSettings" => true, "create" => true, "delete" => true, "get" => true}, "auth" => {"checkAccessToken" => true, "getAccessToken" => true, "getRequestToken" => true},
|
6
|
+
"categories" => {"create" => true, "delete" => true, "get" => true, "rename" => true}, "communities" => {"get" => true}, "coupons" => {"create" => true, "get" => true, "getInfo" => true, "modify" => true, "restrictions" => true},
|
7
|
+
"family" => {"add" => true, "get" => true, "remove" => true, "removeAll" => true}, "fans" => {"get" => true}, "featured" => {"albums" => true}, "friends" => {"add" => true, "get" => true, "remove" => true, "removeAll" => true},
|
8
|
+
"images" => {"applyWatermark" => true, "changePosition" => true, "changeSettings" => true, "collect" => true, "comments" => true, "crop" => true, "delete" => true, "get" => true, "getEXIF" => true, "getInfo" => true, "getStats" => true, "getURLs" => true, "removeWatermark" => true, "rotate" => true, "uploadFromURL" => true, "zoomThumbnail" => true},
|
9
|
+
"printmarks" => {"create" => true, "delete" => true, "get" => true, "getInfo" => true, "modify" => true},
|
10
|
+
"service" => {"ping" => true},
|
11
|
+
"sharegroups" => {"albums" => true, "browse" => true, "create" => true, "delete" => true, "get" => true, "getInfo" => true, "modify" => true},
|
12
|
+
"styles" => {"getTemplates" => true},
|
13
|
+
"subcategories" => {"create" => true, "delete" => true, "get" => true, "getAll" => true, "rename" => true},
|
14
|
+
"themes" => {"get" => true},
|
15
|
+
"users" => {"getInfo" => true, "getStats" => true, "getTree" => true},
|
16
|
+
"watermarks" => {"changeSettings" => true, "create" => true, "delete" => true, "get" => true, "getInfo" => true}
|
17
|
+
}
|
18
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module SmugMug
|
2
|
+
class Client
|
3
|
+
##
|
4
|
+
# Creates a new client instance that can be used to access the SMugMug API
|
5
|
+
# @param [Hash] args
|
6
|
+
# @option args [String] :api_key Your SmugMug API key
|
7
|
+
# @option args [String] :oauth_secret Your SmugMug OAuth secret key
|
8
|
+
# @option args [Hash] :user Configuration for the user you are requesting/updating data for
|
9
|
+
# * :token [String] OAuth token for the user
|
10
|
+
# * :secret [String] OAuth secret token for the user
|
11
|
+
# @option args [String, Optional :user_agent Helps SmugMug identify API calls
|
12
|
+
# @option args [Hash, Optional] :http Additional configuration for the HTTP requests
|
13
|
+
# * :verify_mode [Integer, Optional] How to verify the SSL certificate when connecting through HTTPS, either OpenSSL::SSL::VERIFY_PEER or OpenSSL::SSL::VERIFY_NONE, defaults to OpenSSL::SSL::VERIFY_NONE
|
14
|
+
# * :ca_file [String, Optional] Path to the CA certification file in PEM format
|
15
|
+
# * :ca_path [String, Optional] Path to the directory containing CA certifications in PEM format
|
16
|
+
#
|
17
|
+
# @raise [ArgumentError]
|
18
|
+
def initialize(args)
|
19
|
+
raise ArgumentError, "API Key required" unless args.has_key?(:api_key)
|
20
|
+
raise ArgumentError, "API OAuth secret required" unless args.has_key?(:oauth_secret)
|
21
|
+
raise ArgumentError, "Must specify the users OAuth datA" unless args[:user].is_a?(Hash)
|
22
|
+
raise ArgumentError, "Users OAuth token required" unless args[:user][:token]
|
23
|
+
raise ArgumentError, "Users OAuth secret token required" unless args[:user][:secret]
|
24
|
+
|
25
|
+
@http = HTTP.new(args)
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Uploading media files to SmugMug, see http://wiki.smugmug.net/display/API/Uploading for more information
|
30
|
+
# @param [Hash] args
|
31
|
+
# @option args [File] :file File or stream that can have the content read to upload
|
32
|
+
# @option args [String] :file Binary contents of the file to upload
|
33
|
+
# @option args [String] :FileName What the file name is, only required when passing :file as a string
|
34
|
+
# @option args [Integer] :AlbumID SmugMug Album ID to upload the media to
|
35
|
+
# @option args [Integer, Optional] :ImageID Image ID to replace if reuploading media rather than adding new
|
36
|
+
# @option args [String, Optional] :Caption The caption for the media
|
37
|
+
# @option args [Boolean, Optional] :Hidden Whether the media should be visible
|
38
|
+
# @option args [String, Optional] :Keywords Keywords to tag the media as
|
39
|
+
# @option args [Integer, Optional] :Altitude Altitude the media was taken at
|
40
|
+
# @option args [Float, Optional] :Latitude Latitude the media was taken at
|
41
|
+
# @option args [Float, Optional] :Longitude Latitude the media was taken at
|
42
|
+
#
|
43
|
+
# @raise [SmugMug::OAuthError]
|
44
|
+
# @raise [SmugMug::HTTPError]
|
45
|
+
# @raise [SmugMug::RequestError]
|
46
|
+
# @raise [SmugMug::ReadonlyModeError]
|
47
|
+
# @raise [SmugMug::UnknownAPIError]
|
48
|
+
def upload_media(args)
|
49
|
+
raise ArgumentError, "File is required" unless args.has_key?(:file)
|
50
|
+
raise ArgumentError, "AlbumID is required" unless args.has_key?(:AlbumID)
|
51
|
+
|
52
|
+
if args[:file].is_a?(String)
|
53
|
+
args[:FileName] ||= File.basename(args[:file])
|
54
|
+
args[:content] = File.read(args[:file])
|
55
|
+
elsif args[:file].is_a?(File)
|
56
|
+
args[:FileName] ||= File.basename(args[:file].path)
|
57
|
+
args[:content] = args[:file].read
|
58
|
+
else
|
59
|
+
raise ArgumentError, "File must be a String or File"
|
60
|
+
end
|
61
|
+
|
62
|
+
args.delete(:file)
|
63
|
+
@http.request(:uploading, args)
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Direct mapping of SmugMug 1.3.0 API, either see http://wiki.smugmug.net/display/API/API+1.3.0 or the README for examples
|
68
|
+
#
|
69
|
+
# @raise [SmugMug::OAuthError]
|
70
|
+
# @raise [SmugMug::HTTPError]
|
71
|
+
# @raise [SmugMug::RequestError]
|
72
|
+
# @raise [SmugMug::ReadonlyModeError]
|
73
|
+
# @raise [SmugMug::UnknownAPIError]
|
74
|
+
def method_missing(method, *args)
|
75
|
+
api_cat = method.to_s
|
76
|
+
return super unless SmugMug::API_METHODS[api_cat]
|
77
|
+
|
78
|
+
if klass = self.instance_variable_get("@#{api_cat}_wrapper")
|
79
|
+
klass
|
80
|
+
else
|
81
|
+
self.instance_variable_set("@#{api_cat}_wrapper", SmugMug::ApiCategory.new(@http, api_cat))
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module SmugMug
|
2
|
+
##
|
3
|
+
# Generic module that provides access to the code and text separately of the exception
|
4
|
+
module ReplyErrors
|
5
|
+
attr_reader :reply_text, :reply_code
|
6
|
+
|
7
|
+
def initialize(msg, reply_code=nil, reply_text=nil)
|
8
|
+
super(msg)
|
9
|
+
@reply_code, @reply_text = reply_code, reply_text
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
##
|
14
|
+
# Errors specific to the OAuth request
|
15
|
+
class OAuthError < StandardError
|
16
|
+
include ReplyErrors
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# HTTP errors
|
21
|
+
class HTTPError < StandardError
|
22
|
+
include ReplyErrors
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Problem with the request
|
27
|
+
class RequestError < StandardError
|
28
|
+
include ReplyErrors
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# SmugMug is in read-only mode
|
34
|
+
class ReadonlyModeError < StandardError
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Trying to call an API that doesn't exist
|
39
|
+
class UnknownAPIError < StandardError
|
40
|
+
end
|
41
|
+
end
|
data/lib/smugmug/http.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
require "cgi"
|
2
|
+
require "openssl"
|
3
|
+
require "base64"
|
4
|
+
require "net/http"
|
5
|
+
require "json"
|
6
|
+
|
7
|
+
module SmugMug
|
8
|
+
class HTTP
|
9
|
+
API_URI = URI("https://api.smugmug.com/services/api/json/1.3.0")
|
10
|
+
UPLOAD_URI = URI("http://upload.smugmug.com/")
|
11
|
+
UPLOAD_HEADERS = [:AlbumID, :Caption, :Altitude, :ImageID, :Keywords, :Latitude, :Longitude, :Hidden, :FileName]
|
12
|
+
OAUTH_ERRORS = {30 => true, 32 => true, 33 => true, 35 => true, 36 => true, 37 => true, 38 => true, 98 => true}
|
13
|
+
|
14
|
+
##
|
15
|
+
# Creates a new HTTP wrapper to handle the network portions of the API requests
|
16
|
+
# @param [Hash] args Same as [SmugMug::HTTP]
|
17
|
+
#
|
18
|
+
def initialize(args)
|
19
|
+
@config = args
|
20
|
+
@digest = OpenSSL::Digest::Digest.new("SHA1")
|
21
|
+
|
22
|
+
@headers = {"Accept-Encoding" => "gzip"}
|
23
|
+
if args[:user_agent]
|
24
|
+
@headers["User-Agent"] = "#{args.delete(:user_agent)} (ruby-smugmug v#{SmugMug::VERSION})"
|
25
|
+
else
|
26
|
+
@headers["User-Agent"] = "Ruby-SmugMug v#{SmugMug::VERSION}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def request(api, args)
|
31
|
+
uri = api == :uploading ? UPLOAD_URI : API_URI
|
32
|
+
args[:method] = "smugmug.#{api}" unless api == :uploading
|
33
|
+
|
34
|
+
http = ::Net::HTTP.new(uri.host, uri.port)
|
35
|
+
http.set_debug_output(@config[:debug_output]) if @config[:debug_output]
|
36
|
+
|
37
|
+
# Configure HTTPS if needed
|
38
|
+
if uri.scheme == "https"
|
39
|
+
http.use_ssl = true
|
40
|
+
|
41
|
+
if @config[:http] and @config[:http][:verify_mode]
|
42
|
+
http.verify_mode = @config[:http][:verify_mode]
|
43
|
+
http.ca_file = @config[:http][:ca_file]
|
44
|
+
http.ca_path = @config[:http][:ca_path]
|
45
|
+
else
|
46
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Upload request, which requires special handling
|
51
|
+
if api == :uploading
|
52
|
+
postdata = args.delete(:content)
|
53
|
+
headers = @headers.merge("Content-Length" => postdata.length.to_s, "Content-MD5" => Digest::MD5.hexdigest(postdata), "X-Smug-Version" => "1.3.0", "X-Smug-ResponseType" => "JSON")
|
54
|
+
|
55
|
+
UPLOAD_HEADERS.each do |key|
|
56
|
+
next unless args[key] and args[key] != ""
|
57
|
+
headers["X-Smug-#{key}"] = args[key].to_s
|
58
|
+
end
|
59
|
+
|
60
|
+
oauth = self.sign_request("POST", uri, nil)
|
61
|
+
headers["Authorization"] = "OAuth oauth_consumer_key=\"#{oauth["oauth_consumer_key"]}\", oauth_nonce=\"#{oauth["oauth_nonce"]}\", oauth_signature_method=\"#{oauth["oauth_signature_method"]}\", oauth_signature=\"#{oauth["oauth_signature"]}\", oauth_timestamp=\"#{oauth["oauth_timestamp"]}\", oauth_version=\"#{oauth["oauth_version"]}\", oauth_token=\"#{oauth["oauth_token"]}\""
|
62
|
+
|
63
|
+
# Normal API method
|
64
|
+
else
|
65
|
+
postdata = self.sign_request("POST", uri, args)
|
66
|
+
headers = @headers
|
67
|
+
end
|
68
|
+
|
69
|
+
response = http.request_post(uri.request_uri, postdata, headers)
|
70
|
+
if response.code == "204"
|
71
|
+
return nil
|
72
|
+
elsif response.code != "200"
|
73
|
+
raise SmugMug::HTTPError.new("HTTP #{response.code}, #{response.message}", response.code, response.message)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Check for GZIP encoding
|
77
|
+
if response.header["content-encoding"] == "gzip"
|
78
|
+
begin
|
79
|
+
body = Zlib::GzipReader.new(StringIO.new(response.body)).read
|
80
|
+
rescue Zlib::GzipFile::Error
|
81
|
+
raise
|
82
|
+
end
|
83
|
+
else
|
84
|
+
body = response.body
|
85
|
+
end
|
86
|
+
|
87
|
+
return nil if body == ""
|
88
|
+
|
89
|
+
data = JSON.parse(body)
|
90
|
+
|
91
|
+
if data["stat"] == "fail"
|
92
|
+
# Special casing for SmugMug being in Read only mode
|
93
|
+
if data["code"] == 99
|
94
|
+
raise SmugMug::ReadonlyModeError.new("SmugMug is currently in read only mode, try again later")
|
95
|
+
end
|
96
|
+
|
97
|
+
klass = OAUTH_ERRORS[data["code"]] ? SmugMug::OAuthError : SmugMug::RequestError
|
98
|
+
raise klass.new("Error ##{data["code"]}, #{data["message"]}", data["code"], data["message"])
|
99
|
+
end
|
100
|
+
|
101
|
+
data.delete("stat")
|
102
|
+
data.delete("method")
|
103
|
+
|
104
|
+
# smugmug.albums.changeSettings at the least doesn't return any data
|
105
|
+
return nil if data.length == 0
|
106
|
+
|
107
|
+
# It seems all smugmug APIs only return one hash of data, so this should be fine and not cause issues
|
108
|
+
data.each do |_, value|
|
109
|
+
return value
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
##
|
114
|
+
# Generates an OAuth signature and updates the args with the required fields
|
115
|
+
# @param [String] method HTTP method that the request is sent as
|
116
|
+
# @param [String] uri Full URL of the request
|
117
|
+
# @param [Hash] form_args Args to be passed to the server
|
118
|
+
def sign_request(method, uri, form_args)
|
119
|
+
# Convert non-string keys to strings so the sort works
|
120
|
+
args = {}
|
121
|
+
if form_args
|
122
|
+
form_args.each do |key, value|
|
123
|
+
next unless value and value != ""
|
124
|
+
|
125
|
+
key = key.to_s unless key.is_a?(String)
|
126
|
+
args[key] = value
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Add the necessary OAuth args
|
131
|
+
args["oauth_version"] = "1.0"
|
132
|
+
args["oauth_consumer_key"] = @config[:api_key]
|
133
|
+
args["oauth_nonce"] = Digest::MD5.hexdigest("#{Time.now.to_f}#{rand(10 ** 30)}")
|
134
|
+
args["oauth_signature_method"] = "HMAC-SHA1"
|
135
|
+
args["oauth_timestamp"] = Time.now.utc.to_i
|
136
|
+
args["oauth_token"] = @config[:user][:token]
|
137
|
+
|
138
|
+
# Sort the params
|
139
|
+
sorted_args = []
|
140
|
+
args.sort.each do |key, value|
|
141
|
+
sorted_args.push("#{key.to_s}=#{CGI::escape(value.to_s)}")
|
142
|
+
end
|
143
|
+
|
144
|
+
postdata = sorted_args.join("&")
|
145
|
+
|
146
|
+
# Final string to hash
|
147
|
+
sig_base = "#{method}&#{CGI::escape("#{uri.scheme}://#{uri.host}#{uri.path}")}&#{CGI::escape(postdata)}"
|
148
|
+
|
149
|
+
signature = OpenSSL::HMAC.digest(@digest, "#{@config[:oauth_secret]}&#{@config[:user][:secret]}", sig_base)
|
150
|
+
signature = CGI::escape(Base64.encode64(signature).chomp)
|
151
|
+
|
152
|
+
if uri == API_URI
|
153
|
+
"#{postdata}&oauth_signature=#{signature}"
|
154
|
+
else
|
155
|
+
args["oauth_signature"] = signature
|
156
|
+
args
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-smugmug
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Zachary Anker
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-17 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: json
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.7.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.7.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 2.8.0
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.8.0
|
46
|
+
description: Gem for reading and writing data from the SmugMug 1.3.0 API.
|
47
|
+
email:
|
48
|
+
- zach.anker@gmail.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- lib/ruby-smugmug.rb
|
54
|
+
- lib/smugmug/api_category.rb
|
55
|
+
- lib/smugmug/api_methods.rb
|
56
|
+
- lib/smugmug/client.rb
|
57
|
+
- lib/smugmug/exceptions.rb
|
58
|
+
- lib/smugmug/http.rb
|
59
|
+
- lib/smugmug/version.rb
|
60
|
+
- LICENSE
|
61
|
+
- README.md
|
62
|
+
- Rakefile
|
63
|
+
homepage: http://github.com/zanker/ruby-smugmug
|
64
|
+
licenses: []
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ! '>='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ! '>='
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 1.3.6
|
81
|
+
requirements: []
|
82
|
+
rubyforge_project: ruby-smugmug
|
83
|
+
rubygems_version: 1.8.23
|
84
|
+
signing_key:
|
85
|
+
specification_version: 3
|
86
|
+
summary: SmugMug 1.3.0 API gem
|
87
|
+
test_files: []
|