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 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 || '1.2.0'
24
+ @api_version ||= '1.2.0'
20
25
  end
21
-
26
+
22
27
  def api_key
23
- @api_key || 'RXcw7ywveg9pEj1n6HBJfuDXqsFsx4jw'
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
- communities family friends orders pricing propricing sharegroups
47
- styles themes watermarks)
50
+
51
+ communities family friends orders pricing propricing sharegroups
52
+ styles themes watermarks)
48
53
  end
49
-
50
- def get(passed_params, headers={}, transport='http')
54
+
55
+ def build_uri(passed_params, scheme='http')
51
56
  params = default_params.merge(passed_params)
52
57
 
53
- url = transport + "://" + api_path + "?" +
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 transport == 'https'
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
- when 'gzip'
79
- Zlib::GzipReader.new(StringIO.new(response.body)).read
80
- when 'deflate'
81
- Zlib::Inflate.inflate(response.body)
82
- when nil
83
- response.body
84
- else
85
- raise "Unknown encoding #{response['content-encoding']}"
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
- XMLStruct.new(doc)
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 = {}, transport = "http")
108
- parse_response(get(params, {}, transport))
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
@@ -1,6 +1,8 @@
1
1
  class SmugMugAPI
2
2
 
3
3
  def login(email, password)
4
+ self.nickname = email # it works here, or you can just set it manually
5
+
4
6
  res = SmugMugAPI.https_call(
5
7
  :method => 'smugmug.login.withPassword',
6
8
  :EmailAddress => email,
@@ -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' => 'image/jpeg',
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],
@@ -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
@@ -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
- if xml.is_a?(REXML::Document)
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 self.attrib_key(key)
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
- SmugMugAPI.camelize(key)
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
- # puts "Finding #{attrib} hmmm: #{@xml.elements[attrib]}"
32
- result = XMLStruct.new(@xml.elements[attrib])
33
- # puts "Found #{result}"
34
- result
44
+ XMLStruct.new(@xml.elements[attrib], @feed)
35
45
  else
36
- # key = XMLStruct.attrib_key(attrib)
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
- @xml.elements.each do |xml|
64
- yield XMLStruct.new(xml)
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
- method = SmugMugAPI.camelize(args.shift)
70
- path = "#{method}"
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
- self[method]
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.2"
10
+ VERSION = "0.9.5"
10
11
 
11
- def initialize(base="smugmug")
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
- param_hash = params.first || {}
21
- SmugMugAPI.call(
22
- { :method => cmd }.merge(param_hash)
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.2
7
- date: 2007-12-05 00:00:00 -05:00
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