smugmugapi 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.9.0 / 2007-12-03
2
+
3
+ * Initial public release
4
+
data/Manifest.txt ADDED
@@ -0,0 +1,18 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/smugmugapi.rb
6
+ lib/smugmug/core.rb
7
+ lib/smugmug/exception.rb
8
+ lib/smugmug/logon.rb
9
+ lib/smugmug/proxy.rb
10
+ lib/smugmug/upload.rb
11
+ lib/smugmug/utility.rb
12
+ lib/smugmug/xmlstruct.rb
13
+ examples/upload.rb
14
+ test/test_smugmug.rb
15
+ test/test_smugmug.rb
16
+ test/test_smugmug.rb
17
+ test/test_utility.rb
18
+ test/test_xmlstruct.rb
data/README.txt ADDED
@@ -0,0 +1,61 @@
1
+ smugmug
2
+ by Patrick Hurley
3
+ http://rubygorge.org/projects/sumgmugapi/
4
+
5
+ == DESCRIPTION:
6
+
7
+ A very light wrapper around the 1.2.0 and 1.2.1 REST API at SmugMug
8
+ (http://smugmug.com/). The syntax is almost identical to the one
9
+ described at the wiki (http://smugmug.jot.com/WikiHome/1.2.0).
10
+
11
+ == FEATURES/PROBLEMS:
12
+
13
+ I have written some simple tests of my "local" code, but have not
14
+ attempted to mock out SmugMug or write a bunch of fragile hard coded
15
+ tests.
16
+
17
+ On top of that I just put the code together without tests as I was
18
+ "testing" against the API. So there are a few more rough edges than
19
+ I like, but it does seem to work :-)
20
+
21
+ So I know there will be bugs, sorry -- please let me know when you
22
+ find them and I will try and fix them as quickly as possible.
23
+
24
+ == SYNOPSIS:
25
+
26
+ See examples sub-directory, have a question (or a good example),
27
+ please drop me an email and I will add it to the examples directory,
28
+ at least till we get real documentation (don't hold your breath :-)
29
+
30
+ == REQUIREMENTS:
31
+
32
+ Internet tubes
33
+
34
+ == INSTALL:
35
+
36
+ sudo gem install smugmugapi
37
+
38
+ == LICENSE:
39
+
40
+ (The MIT License)
41
+
42
+ Copyright (c) 2007 Patrick Hurley
43
+
44
+ Permission is hereby granted, free of charge, to any person obtaining
45
+ a copy of this software and associated documentation files (the
46
+ 'Software'), to deal in the Software without restriction, including
47
+ without limitation the rights to use, copy, modify, merge, publish,
48
+ distribute, sublicense, and/or sell copies of the Software, and to
49
+ permit persons to whom the Software is furnished to do so, subject to
50
+ the following conditions:
51
+
52
+ The above copyright notice and this permission notice shall be
53
+ included in all copies or substantial portions of the Software.
54
+
55
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
56
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
57
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
58
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
59
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
60
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
61
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/smugmugapi.rb'
6
+
7
+ Hoe.new('smugmugapi', SmugMugAPI::VERSION) do |p|
8
+ p.rubyforge_name = 'smugmugapi'
9
+ p.author = 'Patrick Hurley'
10
+ p.email = 'phurley@gmail.com'
11
+ p.summary = 'A very light wrapper around the SmugMug REST API'
12
+ p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
13
+ p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
14
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
15
+ end
@@ -0,0 +1,19 @@
1
+ require "rubygems"
2
+ require "smugmugapi"
3
+
4
+ # And you thought I would put my password here for you :-)
5
+ smugmug.login("phurley@gmail.com", IO.read('password')) do
6
+
7
+ category = smugmug.categories.get.find { |e| e.title.match(/family/i) }.id
8
+
9
+ album = smugmug.albums.create(
10
+ :title => 'Test Album',
11
+ :category_id => category,
12
+ :description => 'Just made this album',
13
+ :keywords => 'blue apple foo bar'
14
+ )
15
+ album = album.id
16
+
17
+ puts smugmug.upload('mona_lisa.jpg', :album_id => album, :caption => "Wow it actually works")
18
+
19
+ end
@@ -0,0 +1,88 @@
1
+ require "rexml/document"
2
+ require "uri"
3
+ require "net/https"
4
+
5
+ class SmugMugAPI
6
+ class << self
7
+ USERAGENT = "SumMug Ruby API Library"
8
+
9
+ attr_writer :api_key, :agent, :api_version, :default_params
10
+
11
+ def default_params
12
+ @default_params ||= { :APIKey => api_key }
13
+ end
14
+
15
+ def api_version
16
+ @api_version || '1.2.0'
17
+ end
18
+
19
+ def api_key
20
+ @api_key || 'RXcw7ywveg9pEj1n6HBJfuDXqsFsx4jw'
21
+ end
22
+
23
+ def api_path
24
+ @url || "api.smugmug.com/hack/rest/#{api_version}/"
25
+ end
26
+
27
+ def agent
28
+ @agent || USERAGENT
29
+ end
30
+
31
+ def groups
32
+ # it would be better to have a smugmug reflection method to
33
+ # get this information but this is a fairly exhaustive list
34
+ # and it will be easy to add to this as well
35
+ %w(albums albumtemplates categories images login subcategories users
36
+
37
+ communities family friends orders pricing propricing sharegroups
38
+ styles themes watermarks)
39
+ end
40
+
41
+ def get(passed_params, headers={}, transport='http')
42
+ params = default_params.merge(passed_params)
43
+
44
+ url = transport + "://" + api_path + "?" +
45
+ params.map { |k,v| URI.encode("#{SmugMugAPI.camelize(k)}=#{v}") }.join("&")
46
+ uri = URI.parse(url)
47
+ headers['User-Agent'] = agent
48
+
49
+ http = Net::HTTP.new(uri.host, uri.port)
50
+ if transport == 'https'
51
+ http.use_ssl = true
52
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
53
+ end
54
+
55
+ http.start do
56
+ http.get(uri.path + '?' + uri.query, headers)
57
+ end
58
+ end
59
+
60
+ def parse_response(response)
61
+ puts "HTTP #{response.code}: #{response.message}" if $DEBUG
62
+
63
+ raise SmugMugAPI::Error.new("HTTP #{response.code} on #{url}") unless response.code.to_i == 200
64
+
65
+ doc = REXML::Document.new(response.body)
66
+ if doc.root.attributes['stat'] != 'ok'
67
+ err = doc.root.elements['/rsp/err']
68
+ code = err.attributes['code']
69
+ msg = err.attributes['msg']
70
+ raise SmugMugAPI::Error.new("#{code}: #{msg}")
71
+ end
72
+
73
+ XMLStruct.new(doc)
74
+ end
75
+
76
+ def https_call(params={})
77
+ call(params, 'https')
78
+ end
79
+
80
+ def http_call(params={})
81
+ call(params, 'http')
82
+ end
83
+
84
+ def call(params={}, transport = "http")
85
+ parse_response(get(params, {}, transport))
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,4 @@
1
+ class SmugMugAPI
2
+ class Error < Exception
3
+ end
4
+ end
@@ -0,0 +1,49 @@
1
+ class SmugMugAPI
2
+
3
+ def login(email, password)
4
+ res = SmugMugAPI.https_call(
5
+ :method => 'smugmug.login.withPassword',
6
+ :EmailAddress => email,
7
+ :Password => password
8
+ )
9
+
10
+ SmugMugAPI.default_params[:SessionID] = res.session.id
11
+
12
+ if block_given?
13
+ begin
14
+ yield res
15
+ ensure
16
+ logout
17
+ end
18
+ else
19
+ res
20
+ end
21
+ end
22
+
23
+ def login_with_hash(user, hash)
24
+ res = SmugMugAPI.https_call(
25
+ :method => 'smugmug.login.withHash',
26
+ :UserID => user,
27
+ :PasswordHash => hash
28
+ )
29
+
30
+ SmugMugAPI.default_params[:SessionID] = res.session.id
31
+
32
+ if block_given?
33
+ begin
34
+ yield res
35
+ ensure
36
+ logout
37
+ end
38
+ else
39
+ res
40
+ end
41
+ end
42
+
43
+ def logout
44
+ result = SmugMugAPI.call(:method => 'smugmug.logout')
45
+ SmugMugAPI.default_params.delete(:SessionID)
46
+ result
47
+ end
48
+
49
+ end
@@ -0,0 +1,37 @@
1
+ require "xmlstruct"
2
+
3
+ class SmugProxy
4
+ def initialize(base="", params = {})
5
+ @base = base
6
+ @params = params
7
+ end
8
+
9
+ def method_missing(method, params={})
10
+ method = method.to_s.gsub(/_(.)/) { $1.upcase }
11
+ method = method.gsub(/URL/i, "URL").gsub(/EXIF/i, "EXIF")
12
+
13
+ # it would be better to have a smugmug reflection method to get this information
14
+ # but this is a fairly exhaustive list and it will be easy to add to this as well
15
+ groups = %w(albums albumtemplates categories images login subcategories users
16
+ communities family friends orders pricing propricing sharegroups styles themes watermarks)
17
+
18
+ if groups.include?(method)
19
+ SmugProxy.new(@base + "." + method.to_s, params)
20
+ else
21
+ puts "CALL: #{@base + "." + method}(#{params.inspect})"
22
+ end
23
+ end
24
+
25
+ def to_s
26
+ @base + "(#{@params.inspect})"
27
+ end
28
+ end
29
+
30
+ sm = SmugProxy.new("smugmug")
31
+ puts sm
32
+
33
+ sm.users.get_tree("wow")
34
+ sm.users.getTree("wow")
35
+ sm.images.images.family.getURLs
36
+ sm.images.get_urls
37
+
@@ -0,0 +1,29 @@
1
+ require 'digest/md5'
2
+ require "pp"
3
+
4
+ class SmugMugAPI
5
+
6
+ def upload(fname, params={})
7
+ base_name = File.basename(fname)
8
+ uri = URI.parse("http://upload.smugmug.com/#{base_name}")
9
+ image = IO::read(fname)
10
+
11
+ Net::HTTP.start(uri.host, uri.port) do |http|
12
+ headers = {
13
+ 'Content-Type' => 'image/jpeg',
14
+ 'Content-Lenth' => image.size.to_s,
15
+ 'Content-MD5' => Digest::MD5.hexdigest(image),
16
+ 'X-Smug-SessionID' => SmugMugAPI.default_params[:SessionID],
17
+ 'X-Smug-Version' => SmugMugAPI.api_version,
18
+ 'X-Smug-ResponseType' => 'REST',
19
+ 'X-Smug-FileName' => base_name
20
+ }
21
+
22
+ adjusted_headers = Hash[*params.map { |k,v| [ "X-Smug-" + SmugMugAPI.camelize(k), v.to_s ] }.flatten ]
23
+ headers = headers.merge(adjusted_headers)
24
+
25
+ resp = http.send_request('PUT', uri.request_uri, image, headers)
26
+ SmugMugAPI.parse_response(resp)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,15 @@
1
+ class SmugMugAPI
2
+ def self.camelize(str, upcase_first_char = true)
3
+ if upcase_first_char
4
+ str = str.to_s.gsub(/(^|_)(.)/) { $2.upcase }
5
+ else
6
+ str = str.to_s.gsub(/_(.)/) { $1.upcase }
7
+ end
8
+ str = str.gsub(/URL/i, "URL").gsub(/EXIF/i, "EXIF")
9
+ str = str.gsub(/(?!^)ID$/i, "ID")
10
+ str = str.gsub(/EXIF/i, "EXIF")
11
+ str = str.gsub(/X(.?)Large/i) { "X#{$1}Large" }
12
+ str = "method" if str == "Method" #special case
13
+ str
14
+ end
15
+ end
@@ -0,0 +1,88 @@
1
+
2
+ class SmugMugAPI
3
+ class XMLStruct
4
+ include Enumerable
5
+
6
+ def id(*args)
7
+ method_missing(:id, *args)
8
+ end
9
+
10
+ def initialize(xml)
11
+ if xml.is_a?(REXML::Document)
12
+ @xml = xml.root.elements[2]
13
+ else
14
+ @xml = xml
15
+ end
16
+ end
17
+
18
+ def self.attrib_key(key)
19
+ case key
20
+ when "Id", "id", :id
21
+ "id"
22
+ when Fixnum
23
+ key
24
+ else
25
+ key = XMLStruct.camalize(key)
26
+ key = key.gsub(/ID$/i, "ID")
27
+ key = key.gsub(/EXIF/i, "EXIF")
28
+ key.gsub(/X(.?)Large/i) { "X#{$1}Large" }
29
+ end
30
+ end
31
+
32
+ def [](attrib)
33
+ if attrib.is_a?(Fixnum)
34
+ # puts "Finding #{attrib} hmmm: #{@xml.elements[attrib]}"
35
+ result = XMLStruct.new(@xml.elements[attrib])
36
+ # puts "Found #{result}"
37
+ result
38
+ else
39
+ # key = XMLStruct.attrib_key(attrib)
40
+ @xml.attributes[XMLStruct.attrib_key(attrib)]
41
+ end
42
+ end
43
+
44
+ def first
45
+ XMLStruct.new(@xml.elements[1])
46
+ end
47
+
48
+ def size
49
+ @xml.elements.size
50
+ end
51
+
52
+ def empty?
53
+ size == 0
54
+ end
55
+
56
+ def last
57
+ XMLStruct.new(@xml.elements[@xml.elements.size])
58
+ end
59
+
60
+ def []=(attrib,value)
61
+ @xml.attributes[XMLStruct.attrib_key(attrib)] = value
62
+ end
63
+
64
+ def each
65
+ @xml.elements.each do |xml|
66
+ yield XMLStruct.new(xml)
67
+ end
68
+ end
69
+
70
+ def method_missing(*args)
71
+ method = XMLStruct.camalize(args.shift)
72
+ path = "#{method}"
73
+ if node = @xml.elements[path]
74
+ XMLStruct.new(node)
75
+ else
76
+ self[method]
77
+ end
78
+ end
79
+
80
+ def self.camalize(str)
81
+ str.to_s.gsub(/(^|_)(.)/) { $2.upcase }
82
+ end
83
+
84
+ def to_s
85
+ @xml.to_s
86
+ end
87
+ end
88
+ end
data/lib/smugmugapi.rb ADDED
@@ -0,0 +1,33 @@
1
+ require File.join(File.dirname(__FILE__), "smugmug/core")
2
+ require File.join(File.dirname(__FILE__), "smugmug/utility")
3
+ require File.join(File.dirname(__FILE__), "smugmug/xmlstruct")
4
+ require File.join(File.dirname(__FILE__), "smugmug/exception")
5
+ require File.join(File.dirname(__FILE__), "smugmug/upload")
6
+ require File.join(File.dirname(__FILE__), "smugmug/logon")
7
+
8
+ class SmugMugAPI
9
+ VERSION = "0.9.0"
10
+
11
+ def initialize(base="smugmug")
12
+ @base = base
13
+ end
14
+
15
+ def method_missing(method, *params)
16
+ cmd = @base + "." + SmugMugAPI.camelize(method, false)
17
+ if SmugMugAPI.groups.include?(method.to_s)
18
+ SmugMugAPI.new(cmd)
19
+ else
20
+ param_hash = params.first || {}
21
+ SmugMugAPI.call(
22
+ { :method => cmd }.merge(param_hash)
23
+ )
24
+ end
25
+ end
26
+ end
27
+
28
+ # added here for pretty interface
29
+ module Kernel
30
+ def smugmug(*params)
31
+ @smugmug ||= SmugMugAPI.new
32
+ end
33
+ end
@@ -0,0 +1,10 @@
1
+ require "test/unit"
2
+
3
+ require "smugmugapi"
4
+
5
+ class TestSmugMugAPI < Test::Unit::TestCase
6
+ def test_case_name
7
+ assert(1 == 1)
8
+ # how to test something that is build on top of an online service...
9
+ end
10
+ end
@@ -0,0 +1,22 @@
1
+ require "test/unit"
2
+
3
+ require "smugmugapi"
4
+
5
+ class TestUtility < Test::Unit::TestCase
6
+
7
+ def test_camelize_specials
8
+ # special cases, used to smooth out the meta madness
9
+ test_data = [
10
+ ["PhotoID", "photo_id"],
11
+ ["PhotoEXIF", "photo_exif"],
12
+ ["PhotoURL", "photo_url"],
13
+ ["X3Large", "x3_large"],
14
+ ["X3Large", "x3large"],
15
+ ["method", "method"],
16
+ ]
17
+
18
+ test_data.each do |expected, raw|
19
+ assert_equal(expected, SmugMugAPI.camelize(raw))
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,44 @@
1
+ require "test/unit"
2
+
3
+ require "smugmugapi"
4
+
5
+ class TestXMLStruct < Test::Unit::TestCase
6
+ ALBUM = <<EOF
7
+ <?xml version='1.0' encoding='UTF-8'?>
8
+ <rsp stat='ok'>
9
+ <method>smugmug.albums.get</method>
10
+ <Albums>
11
+ <Album id='3903818' Title='Decorating for xmas 2007' Passworded='0' ImageCount='7'>
12
+ <Category Name='Holidays' id='31'/>
13
+ </Album>
14
+ <Album id='3903815' Title='Misc Fall 2007' Passworded='0' ImageCount='11'>
15
+ <Category Name='Other' id='0'/>
16
+ </Album>
17
+ <Album id='3903813' Title='Pat&apos;s 40th Birthday' Passworded='0' ImageCount='23'>
18
+ <Category Name='Other' id='0'/>
19
+ </Album>
20
+ <Album id='3903805' Title='Hurleyhome' Passworded='0' ImageCount='0'>
21
+ <Category Name='Family' id='9'/>
22
+ </Album>
23
+ </Albums>
24
+ </rsp>
25
+ EOF
26
+
27
+ def test_album_queries
28
+ albums = SmugMugAPI::XMLStruct.new(REXML::Document.new(ALBUM))
29
+
30
+ assert_equal(4, albums.size)
31
+ assert_equal(31, albums[1].category.id.to_i)
32
+ assert_equal('Holidays', albums[1].category.name)
33
+ assert_equal('Other', albums[2].category.name)
34
+ assert_equal('Family', albums.last.category.name)
35
+
36
+ assert_equal("Holidays", albums.first.category.name)
37
+ assert_equal("Decorating for xmas 2007", albums.first.title)
38
+
39
+ assert_equal("Pat's 40th Birthday", albums[3].title)
40
+ end
41
+
42
+ # need many more tests for my meta maddness
43
+ # feel free to write lots of tests :-)
44
+ end
data.tar.gz.sig ADDED
@@ -0,0 +1,2 @@
1
+ 2�e�3�鲌Ǡ��2#�v���r���8ܖz��1����C���z��<OW�a+��@�ɥ�XH�# b�\���|JZ�x������4��QN���u���VԸ�"��7� I&���9��ؿ�޾����J����)�G���)��ݿ
2
+ ø�b$#ٞ� ����l+�8!�U��-t:��� 7w��K���r���(=L�+�
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: smugmugapi
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.9.0
7
+ date: 2007-12-03 00:00:00 -05:00
8
+ summary: A very light wrapper around the SmugMug REST API
9
+ require_paths:
10
+ - lib
11
+ email: phurley@gmail.com
12
+ homepage: " by Patrick Hurley"
13
+ rubyforge_project: smugmugapi
14
+ description: "== FEATURES/PROBLEMS: I have written some simple tests of my \"local\" code, but have not attempted to mock out SmugMug or write a bunch of fragile hard coded tests. On top of that I just put the code together without tests as I was \"testing\" against the API. So there are a few more rough edges than I like, but it does seem to work :-) So I know there will be bugs, sorry -- please let me know when you find them and I will try and fix them as quickly as possible. == SYNOPSIS:"
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ - |
29
+ -----BEGIN CERTIFICATE-----
30
+ MIIDMDCCAhigAwIBAgIBADANBgkqhkiG9w0BAQUFADA+MRAwDgYDVQQDDAdwaHVy
31
+ bGV5MRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZFgNjb20w
32
+ HhcNMDcxMjAzMjAyNjU5WhcNMDgxMjAyMjAyNjU5WjA+MRAwDgYDVQQDDAdwaHVy
33
+ bGV5MRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZFgNjb20w
34
+ ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC00L0dHlSg1NL6oIUrcRBs
35
+ pU9MtYdRjYTqR+tERyl5Wk8UNIFuzIQNpeMrzg2NOe4O6xxycr8wzZ4w64LYxrtd
36
+ uzII7tJOJd5HchVGi31EDPpc+oHSeNPkOtOjIWkpkfdHSuyqpQcyvXb6sdmF9LGU
37
+ vZGoPdesijBE5hzQvZ2IOeXKZh+i5I4/HoXbd7vS6h5mxTDM3LUATxt7AdHgmq7R
38
+ 8XSib1pDniYAx5jPOc++aN3pGkCXragDa48CssEHMCgTE8hsYTOPNeN8BMCkit/r
39
+ py7uigHQ3ZCMc9g77WAHuJ5BR2kpZgdy/GQd9NgAGhJqr2Agd3ksGeGL2cgHDat9
40
+ AgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBSP1Olh
41
+ sOUBB6iyLHQFmbbUttDd9jANBgkqhkiG9w0BAQUFAAOCAQEAj6jHhZBNrhzYIUrv
42
+ DUUQ++8/9jCO2+NjBQC7O3Vme0bloMJtErIw4kHYICBaAbpk26Csx+0As4vquDmo
43
+ LJwA/nXRbJSB3rj9kAU4nWaWQhIyrm0R+Vt5WENNeo4FoBaZvkb/ghE0Ywni1aLq
44
+ 9fvn84MwVZzQenvY1drn9jARZH+eq/NDOUloFlndccrYeBgoZJKi81xYuzwgjzU0
45
+ +aeEWr1e/UCRL8/zg7K6ywuEbeCTszJfK0pWSbFkMMm+ZRgvgsKx3E3C0KZUUz/1
46
+ alHFBzBR9j68NPrORviWlClOXtvA16AyJPfIb/tJiSN11RZC2lyVwIdK3/1L/ckA
47
+ 9WgvxA==
48
+ -----END CERTIFICATE-----
49
+
50
+ post_install_message:
51
+ authors:
52
+ - Patrick Hurley
53
+ files:
54
+ - History.txt
55
+ - Manifest.txt
56
+ - README.txt
57
+ - Rakefile
58
+ - lib/smugmugapi.rb
59
+ - lib/smugmug/core.rb
60
+ - lib/smugmug/exception.rb
61
+ - lib/smugmug/logon.rb
62
+ - lib/smugmug/proxy.rb
63
+ - lib/smugmug/upload.rb
64
+ - lib/smugmug/utility.rb
65
+ - lib/smugmug/xmlstruct.rb
66
+ - examples/upload.rb
67
+ - test/test_smugmug.rb
68
+ - test/test_utility.rb
69
+ - test/test_xmlstruct.rb
70
+ test_files:
71
+ - test/test_smugmug.rb
72
+ - test/test_utility.rb
73
+ - test/test_xmlstruct.rb
74
+ rdoc_options:
75
+ - --main
76
+ - README.txt
77
+ extra_rdoc_files:
78
+ - History.txt
79
+ - Manifest.txt
80
+ - README.txt
81
+ executables: []
82
+
83
+ extensions: []
84
+
85
+ requirements: []
86
+
87
+ dependencies:
88
+ - !ruby/object:Gem::Dependency
89
+ name: hoe
90
+ version_requirement:
91
+ version_requirements: !ruby/object:Gem::Version::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: 1.3.0
96
+ version:
metadata.gz.sig ADDED
Binary file