smugmugr 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,32 +1,22 @@
1
1
  require 'rubygems'
2
2
  require 'curb'
3
- # TODO: look for json_pure, then json
4
3
  require 'json'
5
4
  require 'yaml'
6
5
 
7
- require 'smugmugr/base'
6
+ require 'smugmugr/user'
8
7
  require 'smugmugr/album'
9
- require 'smugmugr/category'
10
- require 'smugmugr/community'
11
- require 'smugmugr/family'
12
- require 'smugmugr/friend'
13
8
  require 'smugmugr/image'
14
9
  require 'smugmugr/session'
15
- require 'smugmugr/share_group'
16
- require 'smugmugr/sub_category'
17
- require 'smugmugr/theme'
18
- require 'smugmugr/user'
19
- require 'smugmugr/watermark'
20
-
21
10
 
22
11
  module Smugmugr
23
12
  # TODO: attempt to load from a configuration file
24
13
  end
25
14
 
15
+ # TODO: keep this?
26
16
  def logger
27
17
  @logger ||= if Module.constants.include?('RAILS_DEFAULT_LOGGER')
28
18
  RAILS_DEFAULT_LOGGER
29
19
  else
30
- Logger.new('smugmugr.log')
20
+ Logger.new('simple_smugmug.log')
31
21
  end
32
22
  end
@@ -1,22 +1,18 @@
1
1
  module Smugmugr
2
- class Album < Smugmugr::Base
3
- attr_accessor :user, :id, :title, :key, :pub_key, :session_id
2
+ class Album
3
+ attr_accessor :user, :id, :title, :key, :pub_key, :session_id, :extras
4
4
 
5
5
  #############################################
6
6
  # all attributes available on an Album
7
7
  #############################################
8
- class_inheritable_reader :attributes
9
- write_inheritable_attribute :attributes, [:id,:Key,:Backprinting,:CanRank,:Category,:Clean,:ColorCorrection,:Comments,:Community,
10
- :Description,:EXIF,:External,:FamilyEdit,:Filenames,:FriendEdit,:Geography,:Header,:HideOwner,:Highlight,:ImageCount,:Larges,:LastUpdated,
8
+ @@attributes = [:id,:Key,:Backprinting,:CanRank,:Category,:Clean,:ColorCorrection,:Comments,:Community,:Description,:EXIF,
9
+ :External,:FamilyEdit,:Filenames,:FriendEdit,:Geography,:Header,:HideOwner,:Highlight,:ImageCount,:Larges,:LastUpdated,
11
10
  :Originals,:Password,:PasswordHint,:Position,:Printable,:ProofDays,:Protected,:Public,:Share,:SmugSearchable,:SortDirection,
12
11
  :SortMethod,:SquareThumbs,:SubCategory,:Template,:Theme,:Title,:UnsharpAmount,:UnsharpRadius,:UnsharpSigma,:UnsharpThreshold,
13
12
  :Watermark,:Watermarking,:WorldSearchable,:X2Larges,:X3Larges,:XLarges]
14
-
15
- class_inheritable_reader :complex_attributes
16
- write_inheritable_attribute :complex_attributes, [:Album, :Category, :Community, :Highlight, :SubCategory, :Template, :Theme, :Watermark]
13
+ @@complex_attributes = [:Category, :Community, :Highlight, :SubCategory, :Template, :Theme, :Watermark]
17
14
 
18
15
  def initialize(user)
19
- @extras = {}
20
16
  @user = user
21
17
  end
22
18
 
@@ -28,7 +24,7 @@ module Smugmugr
28
24
  args[:heavy] ||= false
29
25
  args[:extras] ||= []
30
26
  params = {
31
- :method => smug_method + '.get'
27
+ :method => 'smugmug.albums.get'
32
28
  }
33
29
  params.merge!(:Heavy => args[:heavy].to_s) if args[:heavy]
34
30
  params.merge!(:Extras => args[:extras].collect(&:to_s).join(','))
@@ -38,30 +34,27 @@ module Smugmugr
38
34
  end
39
35
 
40
36
  def albums_from_json(json, user, extra_params=[])
41
- json["Albums"].map do |album|
42
- album_from_json(Smugmugr::Album.new(user), album, user, extra_params)
37
+ albums = json["Albums"].map do |album|
38
+ album_from_json(album, user, extra_params)
43
39
  end
44
40
  end
45
41
 
46
- def album_from_json(album, json, user, extras=[])
47
- album.id = json['id']
48
- album.title = json['Title']
49
- album.key = json['Key']
50
- album.extras = {}
51
- self.attributes.each{ |key|
42
+ def album_from_json(json, user, extras=[])
43
+ a = Album.new(user)
44
+ a.id = json['id']
45
+ a.title = json['Title']
46
+ a.key = json['Key']
47
+ a.extras = {}
48
+ @@attributes.each{ |key|
52
49
  next unless json.has_key?(key.to_s)
53
50
 
54
- album.extras[key] = if self.complex_attributes.include?(key)
51
+ a.extras[key] = if @@complex_attributes.include?(key)
55
52
  Object.class_eval("Smugmugr::Album::#{key}").new(json[key.to_s])
56
53
  else
57
54
  json[key.to_s]
58
55
  end
59
56
  }
60
- album
61
- end
62
-
63
- def smug_method
64
- "smugmug.albums"
57
+ a
65
58
  end
66
59
  end
67
60
 
@@ -70,21 +63,35 @@ module Smugmugr
70
63
  #############################################
71
64
  def images(*extras)
72
65
  extras = [extras] unless extras.is_a?(Array)
73
- Smugmugr::Image.get(self, :extras => extras)
66
+ Image.get(self, :extras => extras)
67
+ end
68
+
69
+ def call(params)
70
+ user.call(params)
74
71
  end
75
72
 
76
73
  def get_info
77
74
  params = {
78
- :method => Smugmugr::Album.smug_method + '.getInfo',
75
+ :method => 'smugmug.albums.getInfo',
79
76
  :AlbumID => self.id,
80
77
  :AlbumKey => self.key
81
78
  }
82
- json = call(params)
83
- return Smugmugr::Album.album_from_json(self, json["Album"], user, Smugmugr::Album.attributes)
79
+ json = user.call(params)
80
+ return Album.album_from_json(json["Album"], user, @@attributes)
84
81
  end
85
82
 
86
- def call(params)
87
- @user.call(params)
83
+ def method_missing(method)
84
+ # check extras for method_name, MethodName
85
+ methods = [method.to_s.classify, method.to_s]
86
+ methods.each do |extras_attribute|
87
+ return self.extras[extras_attribute.to_sym] if self.extras.has_key?(extras_attribute.to_sym)
88
+ end
89
+
90
+ # if it in @@attributes but not populated, return nil
91
+ return nil unless (methods.collect(&:to_sym) & @@attributes).empty?
92
+
93
+ # otherwise, move along
94
+ super(method)
88
95
  end
89
96
 
90
97
  class Simple
@@ -1,24 +1,20 @@
1
1
  module Smugmugr
2
- class Image < Smugmugr::Base
3
- attr_accessor :album, :id, :key
2
+ class Image
3
+ attr_accessor :album, :id, :key, :extras
4
4
 
5
- class_inheritable_reader :attributes
6
- write_inheritable_attribute :attributes, [:id,:Key,:Album,:Altitude,:Caption,:Date,:Duration,:FileName,:Format,:Height,:Hidden,
5
+ @@attributes = [:id,:Key,:Album,:Altitude,:Caption,:Date,:Duration,:FileName,:Format,:Height,:Hidden,
7
6
  :Keywords,:LargeURL,:LastUpdated,:Latitude,:Longitude,:MD5Sum,:MediumURL,:OriginalURL,:Position,:Serial,
8
7
  :Size,:SmallURL,:ThumbURL,:TinyURL,:Video320URL,:Video640URL,:Video960URL,:Video1280URL,:Video1920URL,:Width,
9
8
  :X2LargeURL,:X3LargeURL,:XLargeURL]
10
-
11
- class_inheritable_reader :complex_attributes
12
- write_inheritable_attribute :complex_attributes, [:Album]
9
+ @@complex_attributes = [:Album]
13
10
 
14
11
  def initialize(album)
15
- @extras = {}
16
12
  @album = album
17
13
  end
18
14
 
19
15
  def get(*extras)
20
16
  extras = [extras] unless extras.is_a?(Array)
21
- Smugmugr::Image.get(self.album, :extras => extras)
17
+ Image.get(self.album, :extras => extras)
22
18
  end
23
19
 
24
20
  class << self
@@ -34,47 +30,53 @@ module Smugmugr
34
30
  params.merge!(:Extras => args[:extras].collect(&:to_s).join(',')) if args[:extras].any?
35
31
 
36
32
  json = album.call(params)
37
- images_from_json(json, album, params[:Extras])
33
+ parse_response(json, album, params[:Extras])
38
34
  end
39
35
 
40
36
  def smug_method
41
37
  return "smugmug.images."
42
38
  end
43
39
 
44
- def images_from_json(json, album, extra_params=[])
45
- json['Album']['Images'].map{ |image_json|
46
- image_from_json(Smugmugr::Image.new(album), image_json, extra_params)
47
- }
48
- end
49
-
50
- def image_from_json(image, json, extras=[])
51
- image.id = json['id']
52
- image.key = json['Key']
53
- image.extras = {}
54
- self.attributes.each{ |key|
55
- next unless json.has_key?(key.to_s)
40
+ def parse_response(json, album, extra_params)
41
+ album = json['Album']
42
+ album['Images'].map{ |image_json|
43
+ image = Image.new(album)
44
+ image.id = image_json['id']
45
+ image.key = image_json['Key']
46
+ image.extras = {}
47
+ @@attributes.each{ |key|
48
+ next unless image_json.has_key?(key.to_s)
56
49
 
57
- image.extras[key] = if self.complex_attributes.include?(key)
58
- Object.class_eval("Smugmugr::Image::#{key}").new(json[key.to_s])
59
- else
60
- json[key.to_s]
61
- end
50
+ image.extras[key] = if @@complex_attributes.include?(key)
51
+ Object.class_eval("Smugmugr::Image::#{key}").new(image_json[key.to_s])
52
+ else
53
+ image_json[key.to_s]
54
+ end
55
+ }
56
+ image
62
57
  }
63
- image
64
58
  end
59
+
65
60
  end
66
61
 
67
- #############################################
68
- # instance
69
- #############################################
70
- def get_info
71
- params = {
72
- :method => Smugmugr::Image.smug_method + '.getInfo',
73
- :ImageID => self.id,
74
- :ImageKey => self.key
75
- }
76
- json = @album.call(params)
77
- return Smugmugr::Image.image_from_json(self, json["Image"], Smugmugr::Image.attributes)
62
+ def method_missing(method)
63
+ # check extras for method_name, MethodName
64
+ methods = [method.to_s.classify, method.to_s]
65
+
66
+ # handle _URL methods differently, .classify results in: "fancy_url".classify => "FancyUrl"
67
+ if method.to_s =~ /url|Url|URL/
68
+ methods << method.to_s.gsub(/url|Url/,'URL').classify
69
+ end
70
+
71
+ methods.each do |extras_attribute|
72
+ return self.extras[extras_attribute.to_sym] if self.extras.has_key?(extras_attribute.to_sym)
73
+ end
74
+
75
+ # if it in @@attributes but not populated, return nil
76
+ return nil unless (methods.collect(&:to_sym) & @@attributes).empty?
77
+
78
+ # otherwise, move along
79
+ super(method)
78
80
  end
79
81
 
80
82
  class Album
@@ -1,15 +1,14 @@
1
1
  require 'curl'
2
2
  require 'json'
3
- require 'cgi'
4
3
 
5
4
  module Smugmugr
6
5
  class Session
7
6
  attr_accessor :params, :host, :port, :timeout, :retry, :use_ssl, :session_id
8
7
  attr_accessor :api_path, :session, :api_key, :user, :attributes, :headers
9
8
 
10
- def initialize(user, args={})
9
+ def initialize(api_key, user, args={})
11
10
  @user = user
12
- @api_key = user.api_key
11
+ @api_key = api_key
13
12
  # TODO: externalize, make overrideable from ~/smugmugr.yml or RAILS_ROOT/config/smugmugr.yml
14
13
  attributes = {
15
14
  :host => 'api.smugmug.com',
@@ -61,7 +60,7 @@ module Smugmugr
61
60
  data = nil
62
61
  begin
63
62
  url = protocol + @host + build_url_request(params)
64
- # puts "\nsending: #{url}\n"
63
+ puts "\nsending: #{url}\n"
65
64
  response = Curl::Easy.perform(url) do |easy|
66
65
  easy.headers.merge!(headers)
67
66
  easy.timeout = @timeout
@@ -75,7 +74,7 @@ module Smugmugr
75
74
  # check status of response
76
75
  json = JSON.parse(data)
77
76
 
78
- unless json['stat'] == 'ok'
77
+ if json['stat'] != 'ok'
79
78
  # TODO: custom exception
80
79
  raise "error from smugmug: #{json.inspect}"
81
80
  end
@@ -103,11 +102,13 @@ module Smugmugr
103
102
  @user.filesize_limit = json['FileSizeLimit']
104
103
  end
105
104
 
105
+ private
106
+
106
107
  def protocol
107
108
  return "http#{'s' if @use_ssl}://"
108
109
  end
109
110
 
110
- # {:foo => 'bar', :baz => "blingy things"} => ['foo=bar','baz=blingy+things']
111
+ # {:foo => 'bar', :baz => "blingy things"} => ['foo=bar','baz=blingy%20things']
111
112
  def encode_params(raw_params)
112
113
  return raw_params.map{ |k,v|
113
114
  [k.to_s,CGI::escape(v.to_s)].join('=')
@@ -122,5 +123,4 @@ module Smugmugr
122
123
  end
123
124
 
124
125
  end
125
- end
126
-
126
+ end
@@ -1,17 +1,15 @@
1
1
  module Smugmugr
2
- class User < Smugmugr::Base
3
- attr_accessor :credentials, :session_id, :session, :email, :password, :api_key
2
+ class User
3
+ attr_accessor :credentials, :session_id, :session, :email, :password
4
4
  # set by smugmug response data
5
5
  attr_accessor :user_id, :nickname, :password_hash, :filesize_limit
6
6
 
7
7
  def initialize(api_key, args={})
8
8
  @credentials = {}
9
- self.api_key = api_key
10
9
  args.each{ |k,v|
11
10
  self.send("#{k}=", v) if self.respond_to?(k)
12
11
  }
13
- @session = Smugmugr::Session.new(self, args[:session_args] || {})
14
- return
12
+ @session = Smugmugr::Session.new(api_key, self, args[:session_args] || {})
15
13
  end
16
14
 
17
15
  def send_request_with_session(params)
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{smugmugr}
5
- s.version = "0.3.0"
5
+ s.version = "0.3.1"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Rob Sterner"]
@@ -20,35 +20,19 @@ Gem::Specification.new do |s|
20
20
  "Rakefile",
21
21
  "VERSION",
22
22
  "lib/smugmugr.rb",
23
- "lib/smugmugr/base.rb",
24
23
  "lib/smugmugr/album.rb",
25
- "lib/smugmugr/category.rb",
26
- "lib/smugmugr/community.rb",
27
- "lib/smugmugr/family.rb",
28
- "lib/smugmugr/friend.rb",
29
24
  "lib/smugmugr/image.rb",
30
25
  "lib/smugmugr/session.rb",
31
- "lib/smugmugr/share_group.rb",
32
- "lib/smugmugr/sub_category.rb",
33
- "lib/smugmugr/theme.rb",
34
26
  "lib/smugmugr/user.rb",
35
- "lib/smugmugr/watermark.rb",
36
27
  "smugmugr.gemspec",
37
28
  "spec/album_spec.rb",
38
- "spec/category_spec.rb",
39
- "spec/community_spec.rb",
40
- "spec/family_spec.rb",
41
- "spec/friend_spec.rb",
42
29
  "spec/image_spec.rb",
43
30
  "spec/response_stubs.rb",
44
31
  "spec/session_spec.rb",
45
- "spec/sub_category_spec.rb",
46
32
  "spec/test_helper.rb",
47
- "spec/theme_spec.rb",
48
- "spec/user_spec.rb",
49
- "spec/watermark_spec.rb",
33
+ "spec/user_spec.rb"
50
34
  ]
51
- s.has_rdoc = false
35
+ s.has_rdoc = true
52
36
  s.homepage = %q{http://github.com/fermion/smugmugr}
53
37
  s.rdoc_options = ["--charset=UTF-8"]
54
38
  s.require_paths = ["lib"]
@@ -56,18 +40,11 @@ Gem::Specification.new do |s|
56
40
  s.summary = %q{smugmugr, the smugmug API wrapper}
57
41
  s.test_files = [
58
42
  "spec/album_spec.rb",
59
- "spec/category_spec.rb",
60
- "spec/community_spec.rb",
61
- "spec/family_spec.rb",
62
- "spec/friend_spec.rb",
63
43
  "spec/image_spec.rb",
64
44
  "spec/response_stubs.rb",
65
45
  "spec/session_spec.rb",
66
- "spec/sub_category_spec.rb",
67
46
  "spec/test_helper.rb",
68
- "spec/theme_spec.rb",
69
- "spec/user_spec.rb",
70
- "spec/watermark_spec.rb",
47
+ "spec/user_spec.rb"
71
48
  ]
72
49
 
73
50
  if s.respond_to? :specification_version then
@@ -75,14 +52,8 @@ Gem::Specification.new do |s|
75
52
  s.specification_version = 2
76
53
 
77
54
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
78
- s.add_development_dependency(%q<mocha>, [">= 0"])
79
- s.add_development_dependency(%q<rspec>, [">= 0"])
80
55
  else
81
- s.add_development_dependency(%q<mocha>, [">= 0"])
82
- s.add_development_dependency(%q<rspec>, [">= 0"])
83
56
  end
84
57
  else
85
- s.add_development_dependency(%q<mocha>, [">= 0"])
86
- s.add_development_dependency(%q<rspec>, [">= 0"])
87
58
  end
88
59
  end
@@ -1,51 +1,13 @@
1
1
  require File.dirname(__FILE__) + '/test_helper'
2
2
  require File.dirname(__FILE__) + '/response_stubs'
3
3
 
4
- describe("Smugmugr::Album") do
5
- before(:all) do
6
- @user = Smugmugr::User.new('anapikey')
4
+ describe "Album" do
5
+ before do
6
+ @empty_album = mock('album')
7
+ @empty_album.stub!(:images).and_return([])
7
8
  end
8
9
 
9
- describe("album_get") do
10
- before(:all) do
11
- @user.stubs(:call).returns(JSON.parse(albums_get))
12
- @album = Smugmugr::Album.get(@user).first
13
- end
14
-
15
- it "should have a title" do
16
- @album.title.should == "My Birthday 2008"
17
- end
18
-
19
- it "should be in Category 'Other'" do
20
- @album.category.name.should == "Other"
21
- end
10
+ it "should have no images" do
11
+ @empty_album.images.should be_empty
22
12
  end
23
-
24
- describe("albums_get_info") do
25
- before(:all) do
26
- @album = Smugmugr::Album.new(@user)
27
- @user.stubs(:call).returns(JSON.parse(albums_get_info))
28
- @album.get_info
29
- end
30
-
31
- # spot checks that method_missing is working
32
- it "should have 20 images" do
33
- @album.image_count.should == 20
34
- end
35
-
36
- it "should handle try to handle sumgumg's exceptions to camel case naming" do
37
- # EXIF, for example
38
- @album.exif.should be_true
39
- end
40
-
41
- # spot checks that complex attributes function as expected
42
- it "should be watermarked with name: Smugmug" do
43
- @album.watermark.name.should == "SmugMug"
44
- end
45
-
46
- it "should be in a category named 'Other' with id 0" do
47
- @album.category.name.should == "Other"
48
- @album.category.id.should == 0
49
- end
50
- end
51
13
  end