smugmugapi 0.9.2 → 0.9.5
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/History.txt +11 -0
- data/Rakefile +15 -0
- data/examples/upload.rb +2 -0
- data/lib/smugmug/core.rb +66 -30
- data/lib/smugmug/logon.rb +2 -0
- data/lib/smugmug/upload.rb +2 -1
- data/lib/smugmug/utility.rb +1 -0
- data/lib/smugmug/xmlstruct.rb +49 -23
- data/lib/smugmugapi.rb +24 -7
- data.tar.gz.sig +0 -0
- metadata +11 -2
- metadata.gz.sig +0 -0
data/History.txt
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
== 0.9.5 / 2007-12-09
|
2
|
+
|
3
|
+
* Added cookie handling to REST calls
|
4
|
+
* Added Feed wrapper for searching
|
5
|
+
|
6
|
+
== 0.9.3 / 2007-12-05
|
7
|
+
|
8
|
+
* Added proper mime/content-type encoding for uploads
|
9
|
+
* Added handy rake task for tagging releases
|
10
|
+
* added default VERSION for release gem
|
11
|
+
|
1
12
|
== 0.9.2 / 2007-12-04
|
2
13
|
|
3
14
|
* Fixed "automatic" URL endpoint for 1.2.1 api
|
data/Rakefile
CHANGED
@@ -5,6 +5,8 @@ require 'hoe'
|
|
5
5
|
require './lib/smugmugapi.rb'
|
6
6
|
|
7
7
|
Hoe.new('smugmugapi', SmugMugAPI::VERSION) do |p|
|
8
|
+
ENV["VERSION"] ||= SmugMugAPI::VERSION
|
9
|
+
|
8
10
|
p.rubyforge_name = 'smugmugapi'
|
9
11
|
p.author = 'Patrick Hurley'
|
10
12
|
p.email = 'phurley@gmail.com'
|
@@ -12,4 +14,17 @@ Hoe.new('smugmugapi', SmugMugAPI::VERSION) do |p|
|
|
12
14
|
p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
|
13
15
|
p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
|
14
16
|
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
17
|
+
p.extra_deps << ['mime-types']
|
15
18
|
end
|
19
|
+
|
20
|
+
desc "Tag current trunk in subversion with the current version"
|
21
|
+
task :tag_release do
|
22
|
+
puts "Tag trunk as #{ENV["VERSION"]}"
|
23
|
+
repo = nil
|
24
|
+
`svn info`.each_line do |line|
|
25
|
+
if line.match(/^Repository Root: (.*)/)
|
26
|
+
repo = $1
|
27
|
+
end
|
28
|
+
end
|
29
|
+
puts "svn copy #{repo}/trunk #{repo}/tags/#{ENV["VERSION"]} -m \"Tag release #{ENV["VERSION"]}\""
|
30
|
+
end
|
data/examples/upload.rb
CHANGED
@@ -15,5 +15,7 @@ smugmug.login("phurley@gmail.com", IO.read('password')) do
|
|
15
15
|
album = album.id
|
16
16
|
|
17
17
|
puts smugmug.upload('mona_lisa.jpg', :album_id => album, :caption => "Wow it actually works")
|
18
|
+
# This works too, just send a movie everything else takes care of itself
|
19
|
+
# puts smugmug.upload('movie.avi', :album_id => album, :caption => "Wow it actually works")
|
18
20
|
|
19
21
|
end
|
data/lib/smugmug/core.rb
CHANGED
@@ -9,18 +9,23 @@ class SmugMugAPI
|
|
9
9
|
class << self
|
10
10
|
USERAGENT = "SumMug Ruby API Library"
|
11
11
|
|
12
|
-
attr_writer :api_key, :agent, :api_version, :default_params
|
12
|
+
attr_writer :api_key, :agent, :api_version, :default_params, :cookies
|
13
|
+
attr_accessor :nickname
|
13
14
|
|
15
|
+
def cookies
|
16
|
+
@cookies ||= Hash.new
|
17
|
+
end
|
18
|
+
|
14
19
|
def default_params
|
15
20
|
@default_params ||= { :APIKey => api_key }
|
16
21
|
end
|
17
22
|
|
18
23
|
def api_version
|
19
|
-
@api_version
|
24
|
+
@api_version ||= '1.2.0'
|
20
25
|
end
|
21
|
-
|
26
|
+
|
22
27
|
def api_key
|
23
|
-
@api_key
|
28
|
+
@api_key ||= 'RXcw7ywveg9pEj1n6HBJfuDXqsFsx4jw'
|
24
29
|
end
|
25
30
|
|
26
31
|
def api_path
|
@@ -42,24 +47,26 @@ class SmugMugAPI
|
|
42
47
|
# get this information but this is a fairly exhaustive list
|
43
48
|
# and it will be easy to add to this as well
|
44
49
|
%w(albums albumtemplates categories images login subcategories users
|
45
|
-
|
46
|
-
|
47
|
-
|
50
|
+
|
51
|
+
communities family friends orders pricing propricing sharegroups
|
52
|
+
styles themes watermarks)
|
48
53
|
end
|
49
|
-
|
50
|
-
def
|
54
|
+
|
55
|
+
def build_uri(passed_params, scheme='http')
|
51
56
|
params = default_params.merge(passed_params)
|
52
57
|
|
53
|
-
url =
|
58
|
+
url = scheme + "://" + api_path +
|
59
|
+
"?" +
|
54
60
|
params.map { |k,v| URI.encode("#{SmugMugAPI.camelize(k)}=#{v}") }.join("&")
|
55
61
|
uri = URI.parse(url)
|
62
|
+
end
|
63
|
+
|
64
|
+
def get(uri, headers={})
|
56
65
|
headers['User-Agent'] ||= agent
|
57
66
|
headers['Accept-Encoding'] ||= 'gzip, deflate'
|
58
|
-
|
59
|
-
pp [:smugapi, params, headers, uri] if $DEBUG
|
60
|
-
|
67
|
+
|
61
68
|
http = Net::HTTP.new(uri.host, uri.port)
|
62
|
-
if
|
69
|
+
if uri.scheme == 'https'
|
63
70
|
http.use_ssl = true
|
64
71
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
65
72
|
end
|
@@ -69,43 +76,72 @@ class SmugMugAPI
|
|
69
76
|
end
|
70
77
|
end
|
71
78
|
|
72
|
-
def parse_response(response)
|
79
|
+
def parse_response(response, feed = false)
|
73
80
|
puts "HTTP #{response.code}: #{response.message}" if $DEBUG
|
74
|
-
|
81
|
+
if $DEBUG
|
82
|
+
response.each_header do |k,v|
|
83
|
+
puts "#{k}: #{v}"
|
84
|
+
p k if k.to_s.match(/cook/i)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
75
88
|
raise SmugMugAPI::Error.new("HTTP #{response.code}") unless response.code.to_i == 200
|
76
89
|
|
77
90
|
body = case response['content-encoding']
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
91
|
+
when 'gzip'
|
92
|
+
Zlib::GzipReader.new(StringIO.new(response.body)).read
|
93
|
+
when 'deflate'
|
94
|
+
Zlib::Inflate.inflate(response.body)
|
95
|
+
when nil
|
96
|
+
response.body
|
97
|
+
else
|
98
|
+
raise "Unknown encoding #{response['content-encoding']}"
|
99
|
+
end
|
100
|
+
|
101
|
+
if new_cookies = response.get_fields('Set-Cookie')
|
102
|
+
# not quite RFC 2109, but should be good enough for our needs
|
103
|
+
new_cookies.join(',').split(/,(?=[^;,]*=)|,$/).each do |cookie|
|
104
|
+
if cookie.match(/([^=]+)=([^;]+)/)
|
105
|
+
self.cookies[$1] = $2
|
106
|
+
end
|
107
|
+
end
|
86
108
|
end
|
87
109
|
|
88
110
|
doc = REXML::Document.new(body)
|
89
|
-
if doc.root.attributes['stat'] != 'ok'
|
111
|
+
if !feed && doc.root.attributes['stat'] != 'ok'
|
90
112
|
err = doc.root.elements['/rsp/err']
|
91
113
|
code = err.attributes['code']
|
92
114
|
msg = err.attributes['msg']
|
115
|
+
puts body if $DEBUG
|
93
116
|
raise SmugMugAPI::Error.new("#{code}: #{msg}")
|
94
117
|
end
|
95
118
|
|
96
|
-
|
119
|
+
if feed
|
120
|
+
doc = doc.root
|
121
|
+
end
|
122
|
+
|
123
|
+
XMLStruct.new(doc, feed)
|
97
124
|
end
|
98
|
-
|
125
|
+
|
99
126
|
def https_call(params={})
|
100
127
|
call(params, 'https')
|
101
128
|
end
|
102
|
-
|
129
|
+
|
103
130
|
def http_call(params={})
|
104
131
|
call(params, 'http')
|
105
132
|
end
|
133
|
+
|
134
|
+
def get_feed(feed)
|
135
|
+
uri = URI.parse(feed)
|
136
|
+
|
137
|
+
# process to support passworded feeds
|
138
|
+
headers= { 'Cookie' => SmugMugAPI.cookies.map { |k,v| "#{k}=#{v}"}.join("; ") }
|
139
|
+
parse_response(get(uri, headers), true)
|
140
|
+
end
|
106
141
|
|
107
|
-
def call(params = {},
|
108
|
-
|
142
|
+
def call(params = {}, scheme = "http")
|
143
|
+
uri = build_uri(params, scheme)
|
144
|
+
parse_response(get(uri, {}))
|
109
145
|
end
|
110
146
|
end
|
111
147
|
end
|
data/lib/smugmug/logon.rb
CHANGED
data/lib/smugmug/upload.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'digest/md5'
|
2
|
+
require 'mime/types'
|
2
3
|
require "pp"
|
3
4
|
|
4
5
|
class SmugMugAPI
|
@@ -10,7 +11,7 @@ class SmugMugAPI
|
|
10
11
|
|
11
12
|
Net::HTTP.start(uri.host, uri.port) do |http|
|
12
13
|
headers = {
|
13
|
-
'Content-Type' =>
|
14
|
+
'Content-Type' => MIME::Types.type_for(base_name).to_s,
|
14
15
|
'Content-Lenth' => image.size.to_s,
|
15
16
|
'Content-MD5' => Digest::MD5.hexdigest(image),
|
16
17
|
'X-Smug-SessionID' => SmugMugAPI.default_params[:SessionID],
|
data/lib/smugmug/utility.rb
CHANGED
@@ -8,6 +8,7 @@ class SmugMugAPI
|
|
8
8
|
str = str.gsub(/URL/i, "URL").gsub(/EXIF/i, "EXIF")
|
9
9
|
str = str.gsub(/(?!^)ID$/i, "ID")
|
10
10
|
str = str.gsub(/EXIF/i, "EXIF")
|
11
|
+
str = str.gsub(/MD5Sum/i, "MD5Sum")
|
11
12
|
str = str.gsub(/X(.?)Large/i) { "X#{$1}Large" }
|
12
13
|
str = "method" if str == "Method" #special case
|
13
14
|
str
|
data/lib/smugmug/xmlstruct.rb
CHANGED
@@ -1,46 +1,54 @@
|
|
1
1
|
|
2
|
+
|
2
3
|
class SmugMugAPI
|
3
4
|
class XMLStruct
|
4
5
|
include Enumerable
|
5
6
|
|
7
|
+
# hide Enumerable#entries
|
8
|
+
undef entries
|
9
|
+
|
6
10
|
def id(*args)
|
7
11
|
method_missing(:id, *args)
|
8
12
|
end
|
9
13
|
|
10
|
-
def initialize(xml)
|
11
|
-
|
14
|
+
def initialize(xml, feed=false)
|
15
|
+
@feed = feed
|
16
|
+
if xml.is_a?(REXML::Document) && !feed
|
12
17
|
@xml = xml.root.elements[2]
|
13
18
|
else
|
14
19
|
@xml = xml
|
15
20
|
end
|
16
21
|
end
|
17
22
|
|
18
|
-
def
|
23
|
+
def feed?
|
24
|
+
@feed
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.attrib_key(key, feed)
|
19
28
|
case key
|
20
29
|
when "Id", "id", :id
|
21
30
|
"id"
|
22
31
|
when Fixnum
|
23
32
|
key
|
24
33
|
else
|
25
|
-
|
34
|
+
if feed
|
35
|
+
key.to_s
|
36
|
+
else
|
37
|
+
SmugMugAPI.camelize(key)
|
38
|
+
end
|
26
39
|
end
|
27
40
|
end
|
28
41
|
|
29
42
|
def [](attrib)
|
30
43
|
if attrib.is_a?(Fixnum)
|
31
|
-
|
32
|
-
result = XMLStruct.new(@xml.elements[attrib])
|
33
|
-
# puts "Found #{result}"
|
34
|
-
result
|
44
|
+
XMLStruct.new(@xml.elements[attrib], @feed)
|
35
45
|
else
|
36
|
-
|
37
|
-
# puts "Searching for #{key}"
|
38
|
-
@xml.attributes[XMLStruct.attrib_key(attrib)]
|
46
|
+
@xml.attributes[XMLStruct.attrib_key(attrib, @feed)]
|
39
47
|
end
|
40
48
|
end
|
41
49
|
|
42
50
|
def first
|
43
|
-
XMLStruct.new(@xml.elements[1])
|
51
|
+
XMLStruct.new(@xml.elements[1], @feed)
|
44
52
|
end
|
45
53
|
|
46
54
|
def size
|
@@ -52,31 +60,49 @@ class SmugMugAPI
|
|
52
60
|
end
|
53
61
|
|
54
62
|
def last
|
55
|
-
XMLStruct.new(@xml.elements[@xml.elements.size])
|
63
|
+
XMLStruct.new(@xml.elements[@xml.elements.size], @feed)
|
56
64
|
end
|
57
65
|
|
58
66
|
def []=(attrib,value)
|
59
|
-
@xml.attributes[XMLStruct.attrib_key(attrib)] = value
|
67
|
+
@xml.attributes[XMLStruct.attrib_key(attrib, @feed)] = value
|
60
68
|
end
|
61
69
|
|
62
|
-
def each
|
63
|
-
|
64
|
-
|
70
|
+
def each(path=nil)
|
71
|
+
if path
|
72
|
+
@xml.elements.each(path) do |xml|
|
73
|
+
yield XMLStruct.new(xml, @feed)
|
74
|
+
end
|
75
|
+
else
|
76
|
+
@xml.elements.each do |xml|
|
77
|
+
yield XMLStruct.new(xml, @feed)
|
78
|
+
end
|
65
79
|
end
|
66
80
|
end
|
67
|
-
|
81
|
+
|
68
82
|
def method_missing(*args)
|
69
|
-
|
70
|
-
|
71
|
-
if node = @xml.elements[path]
|
72
|
-
XMLStruct.new(node)
|
83
|
+
if @feed && args.first == :entries
|
84
|
+
entries = @xml.get_elements("//entry").map { |e| XMLStruct.new(e, true) }
|
73
85
|
else
|
74
|
-
|
86
|
+
path = XMLStruct.attrib_key(args.shift, @feed)
|
87
|
+
node = @xml.elements[path] rescue nil
|
88
|
+
if node
|
89
|
+
XMLStruct.new(node, @feed)
|
90
|
+
else
|
91
|
+
self[path]
|
92
|
+
end
|
75
93
|
end
|
76
94
|
end
|
77
95
|
|
78
96
|
def to_s
|
97
|
+
@xml.text
|
98
|
+
end
|
99
|
+
|
100
|
+
def to_xml
|
79
101
|
@xml.to_s
|
80
102
|
end
|
103
|
+
|
104
|
+
def dump
|
105
|
+
@xml.write($stdout, 3, true)
|
106
|
+
end
|
81
107
|
end
|
82
108
|
end
|
data/lib/smugmugapi.rb
CHANGED
@@ -4,25 +4,42 @@ require File.join(File.dirname(__FILE__), "smugmug/xmlstruct")
|
|
4
4
|
require File.join(File.dirname(__FILE__), "smugmug/exception")
|
5
5
|
require File.join(File.dirname(__FILE__), "smugmug/upload")
|
6
6
|
require File.join(File.dirname(__FILE__), "smugmug/logon")
|
7
|
+
require File.join(File.dirname(__FILE__), "smugmug/feed")
|
7
8
|
|
8
9
|
class SmugMugAPI
|
9
|
-
VERSION = "0.9.
|
10
|
+
VERSION = "0.9.5"
|
10
11
|
|
11
|
-
def
|
12
|
+
def nickname=(name)
|
13
|
+
SmugMugAPI.nickname = name
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(base="smugmug", feed=false)
|
12
17
|
@base = base
|
18
|
+
@feed = feed
|
13
19
|
end
|
14
20
|
|
15
21
|
def method_missing(method, *params)
|
16
22
|
cmd = @base + "." + SmugMugAPI.camelize(method, false)
|
17
23
|
if SmugMugAPI.groups.include?(method.to_s)
|
18
|
-
SmugMugAPI.new(cmd)
|
24
|
+
SmugMugAPI.new(cmd, @feed)
|
25
|
+
elsif [:global_feed, :user_feed].include?(method)
|
26
|
+
SmugMugAPI.new(cmd, method)
|
19
27
|
else
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
28
|
+
|
29
|
+
if @feed
|
30
|
+
process_feed(method, params)
|
31
|
+
else
|
32
|
+
process_api(cmd, params)
|
33
|
+
end
|
34
|
+
|
24
35
|
end
|
25
36
|
end
|
37
|
+
|
38
|
+
def process_api(cmd, params)
|
39
|
+
param_hash = params.first || {}
|
40
|
+
SmugMugAPI.call( {:method => cmd}.merge(param_hash))
|
41
|
+
end
|
42
|
+
|
26
43
|
end
|
27
44
|
|
28
45
|
# added here for pretty interface
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: smugmugapi
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.9.
|
7
|
-
date: 2007-12-
|
6
|
+
version: 0.9.5
|
7
|
+
date: 2007-12-10 00:00:00 -05:00
|
8
8
|
summary: A very light wrapper around the SmugMug REST API
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -85,6 +85,15 @@ extensions: []
|
|
85
85
|
requirements: []
|
86
86
|
|
87
87
|
dependencies:
|
88
|
+
- !ruby/object:Gem::Dependency
|
89
|
+
name: mime-types
|
90
|
+
version_requirement:
|
91
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: 0.0.0
|
96
|
+
version:
|
88
97
|
- !ruby/object:Gem::Dependency
|
89
98
|
name: hoe
|
90
99
|
version_requirement:
|
metadata.gz.sig
CHANGED
Binary file
|