smile 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
1
  # Files
2
2
  *.swp
3
+ *.swo
3
4
  *.jpg
4
5
  .DS_Store
5
6
 
@@ -11,4 +12,6 @@ rdoc/
11
12
  pkg/
12
13
  doc/
13
14
 
15
+ *.gem
16
+ .yardoc
14
17
 
data/Rakefile CHANGED
@@ -1,7 +1,51 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
- require 'metric_fu'
4
- require 'config/metric_fu_config'
3
+ require 'date'
4
+
5
+ #############################################################################
6
+ ##
7
+ ## Helper functions
8
+ ##
9
+ ##############################################################################
10
+
11
+ def name
12
+ @name ||= Dir['*.gemspec'].first.split('.').first
13
+ end
14
+
15
+ def version
16
+ line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
17
+ line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
18
+ end
19
+
20
+ def date
21
+ Date.today.to_s
22
+ end
23
+
24
+ def rubyforge_project
25
+ name
26
+ end
27
+
28
+ def gemspec_file
29
+ "#{name}.gemspec"
30
+ end
31
+
32
+ def gem_file
33
+ "#{name}-#{version}.gem"
34
+ end
35
+
36
+ def replace_header(head, header_name)
37
+ head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
38
+ end
39
+
40
+ desc "Open an irb session preloaded with this library"
41
+ task :console do
42
+ sh "irb -rubygems -r ./lib/#{name}.rb"
43
+ end
44
+
45
+ desc "Run Shindo rake tasks"
46
+ task :test do
47
+ sh "shindo #{Dir.glob( 'test/**/*_test.rb' ).join(' ')}"
48
+ end
5
49
 
6
50
  begin
7
51
  require 'jeweler'
@@ -22,56 +66,7 @@ rescue LoadError
22
66
  puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
23
67
  end
24
68
 
25
- # These are new tasks
26
- # These are new tasks
27
- begin
28
- require 'rake/contrib/sshpublisher'
29
- namespace :rubyforge do
30
-
31
- desc "Release gem and RDoc documentation to RubyForge"
32
- task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
33
-
34
- namespace :release do
35
- desc "Publish RDoc to RubyForge."
36
- task :docs => [:rdoc] do
37
- config = YAML.load(
38
- File.read(File.expand_path('~/.rubyforge/user-config.yml'))
39
- )
40
-
41
- host = "#{config['username']}@rubyforge.org"
42
- remote_dir = "/var/www/gforge-projects/cajun-gems/"
43
- local_dir = 'rdoc'
44
-
45
- Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
46
- end
47
- end
48
- end
49
- rescue LoadError
50
- puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
51
- end
52
-
53
- require 'rake/testtask'
54
- Rake::TestTask.new(:test) do |test|
55
- test.libs << 'lib' << 'test'
56
- test.pattern = 'test/**/*_test.rb'
57
- test.verbose = true
58
- end
59
-
60
- begin
61
- require 'rcov/rcovtask'
62
- Rcov::RcovTask.new do |test|
63
- test.libs << 'test'
64
- test.pattern = 'test/**/*_test.rb'
65
- test.verbose = true
66
- end
67
- rescue LoadError
68
- task :rcov do
69
- abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
70
- end
71
- end
72
-
73
-
74
- task :default => :test
69
+ task :default => :test
75
70
 
76
71
  require 'rake/rdoctask'
77
72
  Rake::RDocTask.new do |rdoc|
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
+ :minor: 4
3
+ :patch: 0
2
4
  :major: 0
3
- :minor: 3
4
- :patch: 1
data/bin/smile CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby
1
+ #!/usr/bin/enbin/smile
2
2
  # -*- mode: ruby -*-
3
3
 
4
4
  require 'optparse'
data/lib/smile/album.rb CHANGED
@@ -1,88 +1,71 @@
1
1
  # The Album class will fetch any public/private album hosted on SmugMug.
2
- # The Album Objects will have the following fields on the response
3
2
  #
4
- # Result
3
+ # the album objects will have the following fields on the response
5
4
  #
6
- # STANDARD RESPONSE
5
+ # result
6
+ #
7
+ # standard response
8
+ #
7
9
  #
8
- # array Albums
9
- # Album
10
- # integer id
11
- # string Key
12
- # string Title
13
- # struct Category
14
- # string id
15
- # string Name
16
- # string id
17
- # string Name
18
- # struct SubCategory
19
- # string id
20
- # string Name
21
- # string id
22
- # string Name
10
+ # Album
11
+ # album_id
12
+ # album_key
13
+ # title
14
+ # category { id, name }
15
+ # subcategory { id, name }
23
16
  #
24
- # HEAVY RESPONSE
17
+ # HEAVY RESPONSE ( DEFAULT )
18
+ #
19
+ # Album
20
+ # album_id
21
+ # album_key
22
+ # title
23
+ # category { id, name }
24
+ # subcategory { id, name }
25
+ # string description
26
+ # string keywords
27
+ # boolean geography (owner)
28
+ # integer position
29
+ # struct hightlight (owner) { id }
30
+ # integer imagecount
31
+ # string lastupdated
32
+ # boolean header (owner, power & pro only)
33
+ # boolean clean (owner)
34
+ # boolean exif (owner)
35
+ # boolean filenames (owner)
36
+ # struct template (owner) { id }
37
+ # string sortmethod (owner)
38
+ # boolean sortdirection (owner)
39
+ # string password (owner)
40
+ # string passwordhint (owner)
41
+ # boolean public (owner)
42
+ # boolean worldsearchable (owner)
43
+ # boolean smugsearchable (owner)
44
+ # boolean external (owner)
45
+ # boolean protected (owner, power & pro only)
46
+ # boolean watermarking (owner, pro only)
47
+ # struct watermark (owner, pro only) { id }
48
+ # boolean hideowner (owner)
49
+ # boolean larges (owner, pro only)
50
+ # boolean xlarges (owner, pro only)
51
+ # boolean x2larges (owner)
52
+ # boolean x3larges (owner)
53
+ # boolean originals (owner)
54
+ # boolean canrank (owner)
55
+ # boolean friendedit (owner)
56
+ # boolean familyedit (owner)
57
+ # boolean comments (owner)
58
+ # boolean share (owner)
59
+ # boolean printable (owner)
60
+ # int colorcorrection (owner)
61
+ # integer proofdays (owner, pro only)
62
+ # string backprinting (owner, pro only)
63
+ # float unsharpamount (owner, power & pro only)
64
+ # float unsharpradius (owner, power & pro only)
65
+ # float unsharpthreshold (owner, power & pro only)
66
+ # float unsharpsigma (owner, power & pro only)
67
+ # struct community (owner) id
25
68
  #
26
- # array Albums
27
- # Album
28
- # integer id
29
- # string Key
30
- # string Title
31
- # struct Category
32
- # string id
33
- # string Name
34
- # struct SubCategory
35
- # string id
36
- # string Name
37
- # string Description
38
- # string Keywords
39
- # boolean Geography (owner)
40
- # integer Position
41
- # struct Hightlight (owner)
42
- # string id
43
- # integer ImageCount
44
- # string LastUpdated
45
- # boolean Header (owner, power & pro only)
46
- # boolean Clean (owner)
47
- # boolean EXIF (owner)
48
- # boolean Filenames (owner)
49
- # struct Template (owner)
50
- # string id
51
- # string SortMethod (owner)
52
- # boolean SortDirection (owner)
53
- # string Password (owner)
54
- # string PasswordHint (owner)
55
- # boolean Public (owner)
56
- # boolean WorldSearchable (owner)
57
- # boolean SmugSearchable (owner)
58
- # boolean External (owner)
59
- # boolean Protected (owner, power & pro only)
60
- # boolean Watermarking (owner, pro only)
61
- # struct Watermark (owner, pro only)
62
- # string id
63
- # boolean HideOwner (owner)
64
- # boolean Larges (owner, pro only)
65
- # boolean XLarges (owner, pro only)
66
- # boolean X2Larges (owner)
67
- # boolean X3Larges (owner)
68
- # boolean Originals (owner)
69
- # boolean CanRank (owner)
70
- # boolean FriendEdit (owner)
71
- # boolean FamilyEdit (owner)
72
- # boolean Comments (owner)
73
- # boolean Share (owner)
74
- # boolean Printable (owner)
75
- # int ColorCorrection (owner)
76
- # boolean DefaultColor (owner, pro only) deprecated
77
- # integer ProofDays (owner, pro only)
78
- # string Backprinting (owner, pro only)
79
- # float UnsharpAmount (owner, power & pro only)
80
- # float UnsharpRadius (owner, power & pro only)
81
- # float UnsharpThreshold (owner, power & pro only)
82
- # float UnsharpSigma (owner, power & pro only)
83
- # struct Community (owner)
84
- # string id
85
- #
86
69
  # @author Zac Kleinpeter
87
70
  # @date 2009-04-28.
88
71
  class Smile::Album < Smile::Base
@@ -90,16 +73,12 @@ class Smile::Album < Smile::Base
90
73
  class << self
91
74
  # Converts the json results from the web service into
92
75
  # Album object to use
93
- def from_json( json, session_id )
94
- result = JSON.parse( json )
95
- result["Albums"].map do |album_upcase|
96
- album = upper_hash_to_lower_hash( album_upcase )
97
-
76
+ def from_json( json )
77
+ json["albums"].map do |album_upper|
78
+ album = upper_hash_to_lower_hash( album_upper )
98
79
  album.merge!( :album_id => album["id"] )
99
-
100
- a = Smile::Album.new( album )
101
- a.session_id = session_id
102
- a
80
+
81
+ Smile::Album.new( album )
103
82
  end
104
83
  end
105
84
 
@@ -112,23 +91,12 @@ class Smile::Album < Smile::Base
112
91
  # @param options [optional, String] :password password for the albums
113
92
  # @param options [optional, String] :site_password password for the site
114
93
  def find( options={} )
115
- params = default_params.merge(
116
- :method => 'smugmug.albums.getInfo'
117
- )
94
+ json = web_method_call( { :method => 'smugmug.albums.getInfo' }, options )
118
95
 
119
- options = Smile::ParamConverter.clean_hash_keys( options )
120
- params.merge!( options ) if( options )
121
-
122
- json = RestClient.post( Smile::Base::BASE, params ).body
123
-
124
- album_upper = JSON.parse(json)
125
-
126
- album = upper_hash_to_lower_hash( album_upper['Album'] )
96
+ album = json['album']
127
97
  album.merge!( :album_id => album["id"] )
128
98
 
129
- a = Smile::Album.new( album )
130
- a.session_id = session_id
131
- a
99
+ Smile::Album.new( album )
132
100
  end
133
101
 
134
102
  # Update the album from the following params
@@ -196,18 +164,9 @@ class Smile::Album < Smile::Base
196
164
  # Community
197
165
  # @option options [optional, Fixnum] :community_id ( 0 ) join the group
198
166
  def create( title, options )
199
- params = default_params.merge(
200
- :method => 'smugmug.albums.create',
201
- :AlbumID => album_id
202
- )
203
- options = Smile::ParamConverter.clean_hash_keys( options )
204
- params.merge!( options ) if( options )
167
+ json = web_method_call( { :method => 'smugmug.albums.create', :AlbumID => album_id })
205
168
 
206
- json = RestClient.post( BASE, params ).body
207
- json = JSON.parse( json )
208
- raise json["message"] if json["stat"] == 'fail'
209
- find( :album_id => json["Album"]["id"], :album_key => json["Album"]["key"] )
210
- true
169
+ self.from_json( json )
211
170
  end
212
171
  end
213
172
 
@@ -276,16 +235,8 @@ class Smile::Album < Smile::Base
276
235
  # Community
277
236
  # @option options [optional, Fixnum] :community_id join the group
278
237
  def update( options )
279
- params = default_params.merge(
280
- :method => 'smugmug.albums.changeSettings',
281
- :AlbumID => album_id
282
- )
283
- options = Smile::ParamConverter.clean_hash_keys( options )
284
- params.merge!( options ) if( options )
285
-
286
- json = RestClient.post( BASE, params ).body
287
- json = JSON.parse( json )
288
- raise json["message"] if json["stat"] == 'fail'
238
+ json = web_method_call( { :method => 'smugmug.albums.changeSettings', :AlbumID => album_id } )
239
+
289
240
  true
290
241
  end
291
242
 
@@ -297,18 +248,16 @@ class Smile::Album < Smile::Base
297
248
  # @option options [optional, string] :password password for the pics
298
249
  # @option options [optional, string] :site_password access via site password
299
250
  def photos( options=nil )
300
- params = default_params.merge(
301
- :method => 'smugmug.images.get',
302
- :AlbumID => album_id,
303
- :AlbumKey => key,
304
- :Heavy => 1
251
+ json = web_method_call(
252
+ {
253
+ :method => 'smugmug.images.get',
254
+ :AlbumID => self.album_id,
255
+ :AlbumKey => self.key,
256
+ :Heavy => 1
257
+ },
258
+ options
305
259
  )
306
- options = Smile::ParamConverter.clean_hash_keys( options )
307
- params.merge!( options ) if( options )
308
-
309
- json = RestClient.post( BASE, params ).body
310
-
311
- Smile::Photo.from_json( json, session_id )
260
+ Smile::Photo.from_json( json )
312
261
  end
313
262
 
314
263
  # Pull stats for an Album for a given Month and Year
@@ -318,23 +267,12 @@ class Smile::Album < Smile::Base
318
267
  # @option options [optional, Fixnum] :year (Date.today.year) the year and stuff
319
268
  # @option options [optional, 1 or 0] :heavy more details
320
269
  def stats( options =nil )
321
- params = default_params.merge(
322
- :method => 'smugmug.albums.getStats',
323
- :AlbumID => album_id,
324
- :month => Date.today.month,
325
- :year => Date.today.year
270
+ json = web_method_call(
271
+ { :method => 'smugmug.albums.getStats', :AlbumID => album_id, :month => Date.today.month, :year => Date.today.year },
272
+ options
326
273
  )
327
- options = Smile::ParamConverter.clean_hash_keys( options )
328
-
329
- params.merge!( options ) if( options )
330
-
331
- json = RestClient.post( Smile::Base::BASE, params ).body
332
-
333
- json = JSON.parse( json )
334
- raise json["message"] if json["stat"] == 'fail'
335
274
 
336
- stat = upper_hash_to_lower_hash( json['Album'] )
337
- OpenStruct.new( stat )
275
+ OpenStruct.new( json['album'] )
338
276
  end
339
277
 
340
278
  # Add an image or vid to the existing album
@@ -352,9 +290,9 @@ class Smile::Album < Smile::Base
352
290
  json = RestClient.put( UPLOAD + "/#{image}", File.read( image ),
353
291
  :content_length => File.size( image ),
354
292
  :content_md5 => MD5.hexdigest( File.read( image ) ),
355
- :x_smug_sessionid => session_id,
293
+ :x_smug_sessionid => self.session.id,
356
294
  :x_smug_version => VERSION,
357
- :x_smug_responseType => "JSON",
295
+ :x_smug_responseType => "Smile::Json",
358
296
  :x_smug_albumid => album_id,
359
297
  :x_smug_filename => File.basename( image ),
360
298
  :x_smug_caption => options[:caption],
@@ -363,35 +301,21 @@ class Smile::Album < Smile::Base
363
301
  :x_smug_longitude => options[:longitude],
364
302
  :x_smug_altitude => options[:altitude] ).body
365
303
 
366
- image = JSON.parse( json )
367
- if( image && image["Image"] && image["Image"]["id"] )
368
- Smile::Photo.find( :image_id => image["Image"]["id"] )
304
+ image = Smile::Json.parse( json )
305
+ if( image && image["image"] && image["image"]["id"] )
306
+ Smile::Photo.find( :image_id => image["image"]["id"] )
369
307
  else
370
- raise Exception.new( "Failed to upload #{image}" )
308
+ raise Smile::Exception.new( "Failed to upload #{image}" )
371
309
  end
372
310
  else
373
- raise Exception.new( "Cannot find file #{image}." )
311
+ raise Smile::Exception.new( "Cannot find file #{image}." )
374
312
  end
375
313
  end
376
314
 
377
315
  # Want to get rid of that album? Call this guy and see what gets removed!
378
316
  def delete!
379
- params = default_params.merge(
380
- :method => 'smugmug.albums.delete',
381
- :AlbumID => album_id
382
- )
383
-
384
- options = Smile::ParamConverter.clean_hash_keys( options )
385
-
386
- params.merge!( options ) if( options )
387
-
388
- json = RestClient.post( Smile::Base::BASE, params ).body
389
-
390
- json = JSON.parse( json )
391
- raise json["message"] if json["stat"] == 'fail'
392
-
393
- album_id = nil
394
- album_key = nil
317
+ json = web_method_call( { :method => 'smugmug.albums.delete', :AlbumID => album_id })
318
+
395
319
  nil
396
320
  end
397
321
 
@@ -400,22 +324,21 @@ class Smile::Album < Smile::Base
400
324
  # @option options [String] :by valid values: FileName, Caption, DateTime
401
325
  # @option options [String] :direction valid values: ASC, DESC
402
326
  def resort!( options =nil )
403
- params = default_params.merge(
404
- :method => 'smugmug.albums.reSort',
405
- :AlbumID => album_id
406
- )
407
-
408
- json = RestClient.post( Smile::Base::BASE, params ).body
409
-
410
- json = JSON.parse( json )
411
- raise json["message"] if json["stat"] == 'fail'
412
-
413
- album_id = nil
414
- album_key = nil
327
+ json = web_method_call( { :method => 'smugmug.albums.reSort', :AlbumID => album_id }, options)
328
+
415
329
  nil
416
330
  end
417
331
 
332
+ def reload!
333
+ replace_with = Smile::Album.find(self.album_id, self.album_key )
334
+ # self = replace_with
335
+ end
336
+
418
337
  def category
419
338
  ['category']
420
339
  end
340
+
341
+ def subcategory
342
+ ['subcategory']
343
+ end
421
344
  end
data/lib/smile/base.rb CHANGED
@@ -7,54 +7,19 @@
7
7
  #
8
8
  module Smile
9
9
  class Base < OpenStruct
10
- BASE = 'http://api.smugmug.com/hack/json/1.2.0/'
11
- BASE_SECURE = 'https://api.smugmug.com/hack/json/1.2.0/'
12
- API = 'HSoqGCJ8ilF42BeThMGDZqqqOgj1eXqN'
13
- UPLOAD = "http://upload.smugmug.com/"
10
+ include Smile::Common
14
11
 
15
- VERSION = '1.2.0'
16
-
17
12
  class << self
18
- attr_accessor :session_id
19
- # This will be included in every request once you have logged in
20
- def default_params
21
- base = { :APIKey => API }
22
- if( session_id )
23
- base.merge!( :SessionID => session_id )
24
- end
25
- base
26
- end
27
-
28
- def set_session
29
- if( session_id.nil? )
30
- smug = Smug.new
31
- smug.auth_anonymously
32
- self.session_id = smug.session_id
33
- end
13
+ include Smile::Common
14
+
15
+ def configure
16
+ yield( session )
34
17
  end
35
-
36
- def upper_hash_to_lower_hash( upper )
37
- if( Hash === upper )
38
- lower ={}
39
- upper.each_pair do |key, value|
40
- lower[key.downcase] = upper_hash_to_lower_hash( value )
41
- end
42
- lower
43
- else
44
- upper
45
- end
18
+
19
+ def clear_config!
20
+ session.clear_config!
46
21
  end
47
-
48
- end
49
-
50
- attr_accessor :session_id
51
- def default_params
52
- self.class.session_id = self.session_id
53
- self.class.default_params
54
22
  end
55
23
 
56
- def upper_hash_to_lower_hash( hash )
57
- self.class.upper_hash_to_lower_hash( hash )
58
- end
59
24
  end
60
- end
25
+ end
@@ -0,0 +1,56 @@
1
+ module Smile
2
+ module Common
3
+ BASE = 'http://api.smugmug.com/hack/json/1.2.0/'
4
+ BASE_SECURE = 'https://api.smugmug.com/hack/json/1.2.0/'
5
+ UPLOAD = "http://upload.smugmug.com/"
6
+
7
+ VERSION = '1.2.0'
8
+
9
+ def session
10
+ @session ||= Session.instance
11
+ end
12
+
13
+ # This will be included in every request once you have logged in
14
+ def default_params
15
+ @params ||= { :APIKey => session.api_key }
16
+ @params.merge!( :SessionID => session.id ) if( session.id )
17
+ @params
18
+ end
19
+
20
+ # This is the base work that will need to be done on ALL
21
+ # web calls. Given a set of web options and other params
22
+ # call the web service and convert it to json
23
+ def web_method_call( web_options, options = {} )
24
+ params = default_params.merge( web_options )
25
+ options = Smile::ParamConverter.clean_hash_keys( options )
26
+ params.merge!( options ) if( options )
27
+
28
+ logger.info( params.inspect )
29
+
30
+ json = RestClient.post( BASE, params ).body
31
+ upper_hash_to_lower_hash(Smile::Json.parse( json ) )
32
+ end
33
+
34
+ # This converts a hash that has mixed case
35
+ # into all lower case
36
+ def upper_hash_to_lower_hash( upper )
37
+ if( Hash === upper )
38
+ lower ={}
39
+ upper.each_pair do |key, value|
40
+ lower[key.downcase] = upper_hash_to_lower_hash( value )
41
+ end
42
+ lower
43
+ else
44
+ upper
45
+ end
46
+ end
47
+
48
+ def logger
49
+ session.logger
50
+ end
51
+
52
+ def logger_on?
53
+ session.logger_on?
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,12 @@
1
+ module Smile
2
+ class Exception < StandardError
3
+ def initialize( message =nil )
4
+ Smile::Base.logger.error( message )
5
+ super( message )
6
+ end
7
+ end
8
+
9
+ exceptions = %w[ InvalidLogin ]
10
+
11
+ exceptions.each { |ex| const_set( ex, Class.new(Smile::Exception) ) }
12
+ end
data/lib/smile/json.rb ADDED
@@ -0,0 +1,24 @@
1
+ module Smile
2
+ class Json
3
+
4
+ class << self
5
+ def parse( text )
6
+ @result = JSON.parse(text) # This is the default JSON parse
7
+ raise_exception! if has_error?
8
+ @result
9
+ end
10
+
11
+ def has_error?
12
+ @result["stat"] == 'fail'
13
+ end
14
+
15
+ def error_message
16
+ @result["message"] if has_error?
17
+ end
18
+
19
+ def raise_exception!
20
+ raise Smile::Exception.new( error_message )
21
+ end
22
+ end
23
+ end
24
+ end
@@ -4,101 +4,27 @@ module Smile::ParamConverter
4
4
  def convert( param, value=nil )
5
5
  key = nil
6
6
  key = case param.to_s.downcase.to_sym
7
- when :popular_category
8
- :popularCategory
9
- when :geo_all
10
- :geoAll
11
- when :geo_keyword
12
- :geoKeyword
13
- when :geo_search
14
- :geoSearch
15
- when :geo_community
16
- :geoCommunity
17
- when :open_search_keyword
18
- :openSearchKeyword
19
- when :user_keyword
20
- :userkeyword
21
- when :nickname_recent
22
- :nicknameRecent
23
- when :nickname_popular
24
- :nicknamePopular
25
- when :user_comments
26
- :userComments
27
- when :geo_user
28
- :geoUser
29
- when :geo_album
30
- :geoAlbum
7
+ when :popular_category, :geo_all, :geo_keyword,
8
+ :geo_search, :geo_community, :open_search_keyword, :user_keyword,
9
+ :nickname_recent, :nickname_popular, :user_comments, :geo_user,
10
+ :geo_album
11
+ first_letter_downcase( param.to_s.classify ).to_sym
31
12
  when :size
32
13
  value = value.titlecase
33
14
  :Size
34
- when :image_count
35
- :ImageCount
36
15
  when :data, :type, :description, :keywords, :geography, :position, :header,
37
16
  :clean, :filenames, :password, :public, :external, :protected, :watermarking,
38
17
  :larges, :originals, :comments, :share, :printable, :backprinting
39
18
  param.to_s.upcase.to_sym
40
- when :image_id
41
- :ImageID
42
- when :image_key
43
- :ImageKey
44
- when :image_count
45
- :ImageCount
46
- when :nickname, :nick_name
47
- :NickName
48
- when :category_id
49
- :CategoryID
50
- when :sub_categroy_id
51
- :SubCategoryID
52
- when :album_template_id
53
- :AlbumTemplateID
54
- when :highlight_id
55
- :HighlightID
19
+ when :image_id, :image_key, :image_count, :nick_name, :category_id,
20
+ :sub_category_id, :album_template_id, :highlight_id, :square_thumbs,
21
+ :template_id, :sort_method, :sort_direction, :password_hint, :word_searchable,
22
+ :smug_searchable, :watermark_id, :hide_owner, :x_larges, :x2_larges, :x3_larges,
23
+ :can_rank, :friend_edit, :family_edit, :color_correction, :default_color, :proof_days,
24
+ :unsharp_amount, :unsharp_radius, :unsharp_sigma, :community_id
25
+ param.to_s.classify.to_sym
56
26
  when :exif
57
27
  :EXIF
58
- when :square_thumbs
59
- :Square_Thumbs
60
- when :tempate_id
61
- :TemplateID
62
- when :sort_method
63
- :SortMethod
64
- when :sort_direction
65
- :SortDirection
66
- when :password_hint
67
- :PasswordHint
68
- when :word_searchable
69
- :WordSearchable
70
- when :smug_searchable
71
- :SmugSearchable
72
- when :watermark_id
73
- :WatermarkID
74
- when :hide_owner
75
- :HideOwner
76
- when :x_larges, :xlarges
77
- :XLarges
78
- when :x2_larges, :x2larges
79
- :X2Larges
80
- when :x3_larges, :x3larges
81
- :X3Larges
82
- when :can_rank
83
- :CanRank
84
- when :friend_edit
85
- :FriendEdit
86
- when :family_edit
87
- :FamilyEdit
88
- when :color_correction
89
- :ColorCorrection
90
- when :default_color
91
- :DefaultColor
92
- when :proof_days
93
- :ProofDays
94
- when :unsharp_amount
95
- :UnsharpAmount
96
- when :unsharp_radius
97
- :UnsharpRadius
98
- when :unsharp_sigma
99
- :UnsharpSigma
100
- when :community_id
101
- :CommunityID
102
28
  else
103
29
  key = param
104
30
  end
@@ -113,5 +39,9 @@ module Smile::ParamConverter
113
39
  end if( hash_to_clean )
114
40
  cleaned_hash
115
41
  end
116
-
42
+
43
+ def first_letter_downcase( stuff )
44
+ stuff.to_s.gsub( /^(\w)/, $1.downcase )
45
+ end
46
+
117
47
  end
data/lib/smile/photo.rb CHANGED
@@ -7,19 +7,15 @@ class Smile::Photo < Smile::Base
7
7
 
8
8
  class << self
9
9
  # Convert the given xml into photo objects to play with
10
- def from_json( json, session_id )
11
- result = JSON.parse( json )
12
-
13
- result["Images"].map do |image_upper|
10
+ def from_json( json )
11
+ json["images"].map do |image_upper|
14
12
  image = upper_hash_to_lower_hash( image_upper )
15
13
  image.merge!( :image_id => image["id"] )
16
14
  image.merge!( :album_key => image["album"]["key"] )
17
15
  image.merge!( :album_id => image["album"]["id"] )
18
16
  image.delete( 'album' )
19
-
20
- p = Smile::Photo.new( image )
21
- p.session_id = session_id
22
- p
17
+
18
+ Smile::Photo.new( image )
23
19
  end
24
20
  end
25
21
 
@@ -31,26 +27,17 @@ class Smile::Photo < Smile::Base
31
27
  # @option options [optional, String] :site_password password word for the site
32
28
  # @option options [optional, String] :image_key image key maybe?
33
29
  def find( options={} )
34
- set_session if( session_id.nil? )
35
- options = Smile::ParamConverter.clean_hash_keys( options )
36
-
37
- params = default_params.merge(
38
- :method => 'smugmug.images.getInfo'
30
+ image = web_method_call(
31
+ { :method => 'smugmug.images.getInfo' },
32
+ options
39
33
  )
40
34
 
41
- params.merge!( options ) if( options )
42
- json = RestClient.post( Smile::Base::BASE, params ).body
43
- image_upper = JSON.parse( json )
44
- image = upper_hash_to_lower_hash( image_upper['Image'] )
45
-
46
35
  image.merge!( :image_id => image["id"] )
47
36
  image.merge!( :album_key => image["album"]["key"] )
48
37
  image.merge!( :album_id => image["album"]["id"] )
49
38
  image.delete( 'album' )
50
39
 
51
- p = Smile::Photo.new( image )
52
- p.session_id = session_id
53
- p
40
+ Smile::Photo.new( image )
54
41
  end
55
42
  end
56
43
 
@@ -97,19 +84,11 @@ class Smile::Photo < Smile::Base
97
84
  # @option options [String] :password a password field
98
85
  # @option options [String] :site_password site password field
99
86
  def details( options =nil )
100
- params = default_params.merge(
101
- :method => "smugmug.images.getEXIF",
102
- :ImageID => self.image_id,
103
- :ImageKey => self.key
87
+ image = web_method_call(
88
+ { :method => "smugmug.images.getEXIF", :ImageID => self.image_id, :ImageKey => self.key },
89
+ options
104
90
  )
105
91
 
106
- params.merge!( options ) if( options )
107
- json = RestClient.post( Smile::Base::BASE, params ).body
108
-
109
- json = JSON.parse( json )
110
- raise json["message"] if json["stat"] == 'fail'
111
-
112
- image = upper_hash_to_lower_hash( json['Image'] )
113
92
  image.merge!( :image_id => image["id"] )
114
93
 
115
94
  OpenStruct.new( image )
@@ -156,19 +135,11 @@ class Smile::Photo < Smile::Base
156
135
  # integer "id"
157
136
  # String "Key"
158
137
  def info( options =nil )
159
- params = default_params.merge(
160
- :method => "smugmug.images.getInfo",
161
- :ImageID => self.image_id,
162
- :ImageKey => self.key
138
+ image = web_method_call(
139
+ { :method => "smugmug.images.getInfo", :ImageID => self.image_id, :ImageKey => self.key },
140
+ options
163
141
  )
164
-
165
- params.merge!( options ) if( options )
166
- json = RestClient.post( Smile::Base::BASE, params ).body
167
-
168
- json = JSON.parse( json )
169
- raise json["message"] if json["stat"] == 'fail'
170
142
 
171
- image = upper_hash_to_lower_hash( json['Image'] )
172
143
  image.merge!( :image_id => image["id"] )
173
144
 
174
145
  OpenStruct.new( image )
@@ -207,25 +178,17 @@ class Smile::Photo < Smile::Base
207
178
  # String "X3LargeURL" (if available)
208
179
  # String "OriginalURL" (if available)
209
180
  def urls( options =nil )
210
- params = default_params.merge(
211
- :method => "smugmug.images.getURLs",
212
- :ImageID => self.image_id,
213
- :ImageKey => self.key
181
+ image = web_method_call(
182
+ { :method => "smugmug.images.getURLs", :ImageID => self.image_id, :ImageKey => self.key },
183
+ options
214
184
  )
215
-
216
- params.merge!( options ) if( options )
217
- json = RestClient.post( Smile::Base::BASE, params ).body
218
-
219
- json = JSON.parse( json )
220
- raise json["message"] if json["stat"] == 'fail'
221
185
 
222
- image = upper_hash_to_lower_hash( json['Image'] )
223
186
  image.merge!( :image_id => image["id"] )
224
187
 
225
188
  OpenStruct.new( image )
226
189
  end
227
190
 
228
191
  def album
229
- Smile::Album.find( :AlbumID => album_id, :AlbumKey => album_key )
192
+ Smile::Album.find( :AlbumID => self.album_id, :AlbumKey => self.album_key )
230
193
  end
231
194
  end
@@ -0,0 +1,37 @@
1
+ module Smile
2
+ class Session
3
+ include Singleton
4
+ API = 'HSoqGCJ8ilF42BeThMGDZqqqOgj1eXqN'
5
+
6
+ attr_accessor :id, :api_key, :logger_on
7
+ attr_reader :log
8
+
9
+ def has_id?
10
+ @id.nil?
11
+ end
12
+
13
+ def api_key
14
+ @api_key || API
15
+ end
16
+
17
+ def logger
18
+ if( logger_on? )
19
+ @log ||= Logger.new( STDOUT )
20
+ RestClient.log ||= @log
21
+ @log
22
+ else
23
+ @blank ||= Logger.new nil
24
+ RestClient.log ||= @blank
25
+ @blank
26
+ end
27
+ end
28
+
29
+ def logger_on?
30
+ @logger_on
31
+ end
32
+
33
+ def clear_config!
34
+ @api_key, @log, @logger_on = nil,nil,nil
35
+ end
36
+ end
37
+ end
data/lib/smile/smug.rb CHANGED
@@ -15,19 +15,12 @@ module Smile
15
15
  #
16
16
  # @return [Smile::SmugMug.new] An Smug object that has been authenticated
17
17
  def auth( email, pass )
18
- params = default_params.merge(
19
- :method => 'smugmug.login.withPassword',
20
- :EmailAddress => email,
21
- :Password => pass
18
+ json = web_method_call(
19
+ { :method => 'smugmug.login.withPassword', :EmailAddress => email, :Password => pass }
22
20
  )
23
21
 
24
- json = RestClient.post( BASE, params ).body
25
- result = JSON.parse( json )
26
-
27
- self.session_id = result["Login"]["Session"]["id"]
28
- result
29
- rescue NoMethodError => e
30
- nil
22
+ self.session.id = json["login"]["session"]["id"]
23
+ json
31
24
  end
32
25
 
33
26
  # Login to SmugMug using an anonymously account
@@ -35,25 +28,15 @@ module Smile
35
28
  #
36
29
  # @return [Smile::SmugMug.new] An Smug object that has been authenticated
37
30
  def auth_anonymously
38
- params = default_params.merge(
39
- :method => 'smugmug.login.anonymously'
40
- )
31
+ json = web_method_call( { :method => 'smugmug.login.anonymously' } )
41
32
 
42
- json = RestClient.post( BASE, params ).body
43
- result = JSON.parse( json )
44
- self.session_id = result["Login"]["Session"]["id"]
45
- result
46
- rescue NoMethodError => e
47
- nil
33
+ self.session.id = json["login"]["session"]["id"]
34
+ json
48
35
  end
49
36
 
50
37
  # Close the session
51
38
  def logout
52
- params = default_params.merge(
53
- :method => 'smugmug.logout'
54
- )
55
-
56
- RestClient.post( BASE, params ).body
39
+ web_method_call( { :method => 'smugmug.logout' } )
57
40
  end
58
41
 
59
42
 
@@ -72,18 +55,12 @@ module Smile
72
55
  #
73
56
  # @see Smug::Album#new For more information about heavy ( true and false ) responces
74
57
  def albums( options=nil )
75
- params = default_params.merge(
76
- :method => 'smugmug.albums.get',
77
- :heavy => 1
58
+ json = web_method_call(
59
+ { :method => 'smugmug.albums.get', :heavy => 1 },
60
+ options
78
61
  )
79
62
 
80
- options = Smile::ParamConverter.clean_hash_keys( options )
81
- params = params.merge( options ) if( options )
82
- json = RestClient.post( BASE, params ).body
83
-
84
- Smile::Album.from_json( json, session_id )
85
- rescue
86
- nil
63
+ Smile::Album.from_json( json )
87
64
  end
88
65
  end
89
66
  end
data/lib/smile.rb CHANGED
@@ -1,11 +1,15 @@
1
1
  require 'active_support'
2
2
  require 'restclient'
3
3
  require 'ostruct'
4
- require 'lib/smile/base'
5
- require 'lib/smile/smug'
6
- require 'lib/smile/album'
7
- require 'lib/smile/photo'
8
- require 'lib/smile/param_converter'
4
+ require File.dirname(__FILE__) + '/smile/session'
5
+ require File.dirname(__FILE__) + '/smile/common'
6
+ require File.dirname(__FILE__) + '/smile/base'
7
+ require File.dirname(__FILE__) + '/smile/smug'
8
+ require File.dirname(__FILE__) + '/smile/album'
9
+ require File.dirname(__FILE__) + '/smile/photo'
10
+ require File.dirname(__FILE__) + '/smile/param_converter'
11
+ require File.dirname(__FILE__) + '/smile/exception'
12
+ require File.dirname(__FILE__) + '/smile/json'
9
13
  require 'cgi'
10
14
  require 'rss'
11
15
  require 'json'
data/smile.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{smile}
8
- s.version = "0.3.1"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["cajun"]
12
- s.date = %q{2010-04-17}
12
+ s.date = %q{2010-05-13}
13
13
  s.default_executable = %q{smile}
14
14
  s.email = %q{zac@kleinpeter.org}
15
15
  s.executables = ["smile"]
@@ -23,12 +23,15 @@ Gem::Specification.new do |s|
23
23
  "README.rdoc",
24
24
  "Rakefile",
25
25
  "VERSION.yml",
26
- "config/metric_fu_config.rb",
27
26
  "lib/smile.rb",
28
27
  "lib/smile/album.rb",
29
28
  "lib/smile/base.rb",
29
+ "lib/smile/common.rb",
30
+ "lib/smile/exception.rb",
31
+ "lib/smile/json.rb",
30
32
  "lib/smile/param_converter.rb",
31
33
  "lib/smile/photo.rb",
34
+ "lib/smile/session.rb",
32
35
  "lib/smile/smug.rb",
33
36
  "smile.gemspec",
34
37
  "test/smile_test.rb",
data/test/smile_test.rb CHANGED
@@ -1,63 +1,82 @@
1
1
  require File.dirname(__FILE__) + '/test_helper'
2
2
 
3
- class SmileTest < Test::Unit::TestCase
4
- def setup
3
+ Shindo.tests 'checking all the cool things smile can do' do
4
+ extend RR::Adapters::RRMethods
5
+
6
+ before do
7
+ # this resets the config to the base state before every test
8
+ Smile::Base.clear_config!
9
+ Smile::Base.configure do |config|
10
+ # config.logger_on = true
11
+ end
12
+
5
13
  @smug = Smile::Smug.new
6
14
  @smug.auth_anonymously
7
15
  end
8
-
9
- def test_auth
10
- assert_not_nil( @smug.auth_anonymously )
11
- end
12
-
13
- def test_have_albums
14
- assert_nothing_raised(Exception) do
15
- assert_not_nil( @smug.albums( :nick_name => 'kleinpeter' ) )
16
+
17
+ tests 'security checks', ['security'] do
18
+ test( 'testing basic auth anonymously' ) { @smug.auth_anonymously }
19
+
20
+ test 'InvalidLogin will get raised on foo bar login' do
21
+ all_good = false
22
+ begin
23
+ Smile.auth( 'foo', 'and mo bar' )
24
+ rescue Smile::Exception => ex
25
+ all_good = true
26
+ end
27
+
28
+ all_good
16
29
  end
17
30
  end
18
-
19
- def test_have_photos
20
- assert_nothing_raised(Exception) do
31
+
32
+ tests 'album and photo checks' do
33
+ test( 'checking to see if we have some albums', ['album']) do
34
+ @smug.albums( :nick_name => 'kleinpeter' )
35
+ end
36
+
37
+ test( 'we can reload albums from the site', ['album'])
38
+
39
+ test 'checking to see if we have photos in the albums', ['album'] do
21
40
  album = @smug.albums( :nick_name => 'kleinpeter' ).first
22
- assert_not_nil( album.photos )
41
+ !album.photos.empty?
23
42
  end
24
- end
25
-
26
- def test_photo_has_album
27
- assert_nothing_raised(Exception) do
43
+
44
+ test 'a photo is connected to its album', ['photo'] do
28
45
  album = @smug.albums( :nick_name => 'kleinpeter' ).first
29
46
  photo = album.photos.first
30
- assert_equal( album.album_id, photo.album.album_id )
31
- assert_equal( album.key, photo.album.key )
47
+ album.album_id == photo.album.album_id &&
48
+ album.key == photo.album.key
32
49
  end
33
50
  end
34
51
 
35
- def test_photo_has_album_has_photo
36
- assert_nothing_raised(Exception) do
37
- album = @smug.albums( :nick_name => 'kleinpeter' ).first
38
- photo = album.photos.first
39
- alt_photo = photo.album.photos.first
40
-
41
- assert_equal( photo.image_id, alt_photo.image_id )
52
+ tests 'confirm configuration settings', ['config'] do
53
+ test 'there is a default api key' do
54
+ Smile::Base.session.api_key
55
+ end
56
+
57
+ test 'we can set the api key in the config' do
58
+ Smile::Base.configure do |config|
59
+ config.api_key = 'foo'
60
+ end
61
+
62
+ Smile::Base.session.api_key
42
63
  end
43
64
  end
44
-
45
- # NOTE have to be logged in to test this one
46
- # def test_album_stats
47
- # assert_nothing_raised(Exception) do
48
- # album = @smug.albums( :nick_name => 'kleinpeter' ).first
49
- # assert_not_nil( album.stats )
50
- # end
51
- # end
52
-
53
- def test_photo_extras
54
- assert_nothing_raised(Exception) do
55
- album = @smug.albums( :nick_name => 'kleinpeter' ).first
56
- photo = album.photos.first
57
-
58
- assert_not_nil( photo.details )
59
- assert_not_nil( photo.info )
60
- assert_not_nil( photo.urls )
65
+
66
+ tests 'there is a logger and it does stuff' do
67
+ test 'the logger is off by default', ['log'] do
68
+ Smile::Base.clear_config!
69
+ !Smile::Base.logger_on?
70
+ end
71
+ end
72
+
73
+ tests 'looking now at the exception classes', ['exceptions'] do
74
+ test 'exceptions should log errors' do
75
+ @@error_got_called = false
76
+ mock(Smile::Base.logger).error( 'foo' ) { @@error_got_called = true }
77
+ Smile::Exception.new( 'foo' )
78
+ @@error_got_called
61
79
  end
62
80
  end
63
81
  end
82
+
data/test/test_helper.rb CHANGED
@@ -1,10 +1,8 @@
1
1
  require 'rubygems'
2
- require 'test/unit'
3
- require 'ruby-debug'
2
+ require 'shindo'
3
+ require 'rr'
4
+
4
5
 
5
6
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
7
  $LOAD_PATH.unshift(File.dirname(__FILE__))
7
8
  require 'smile'
8
-
9
- class Test::Unit::TestCase
10
- end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 3
8
- - 1
9
- version: 0.3.1
7
+ - 4
8
+ - 0
9
+ version: 0.4.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - cajun
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-17 00:00:00 -05:00
17
+ date: 2010-05-13 00:00:00 -05:00
18
18
  default_executable: smile
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -56,12 +56,15 @@ files:
56
56
  - README.rdoc
57
57
  - Rakefile
58
58
  - VERSION.yml
59
- - config/metric_fu_config.rb
60
59
  - lib/smile.rb
61
60
  - lib/smile/album.rb
62
61
  - lib/smile/base.rb
62
+ - lib/smile/common.rb
63
+ - lib/smile/exception.rb
64
+ - lib/smile/json.rb
63
65
  - lib/smile/param_converter.rb
64
66
  - lib/smile/photo.rb
67
+ - lib/smile/session.rb
65
68
  - lib/smile/smug.rb
66
69
  - smile.gemspec
67
70
  - test/smile_test.rb
@@ -1,31 +0,0 @@
1
- MetricFu::Configuration.run do |config|
2
- #define which metrics you want to use
3
- config.metrics = [:churn, :saikuro, :flog, :flay, :reek, :roodi, :rcov]
4
- config.graphs = [:flog, :flay, :reek, :roodi, :rcov]
5
- config.flay = { :dirs_to_flay => ['lib'],
6
- :minimum_score => 100 }
7
- config.flog = { :dirs_to_flog => ['lib'] }
8
- config.reek = { :dirs_to_reek => ['lib'] }
9
- config.roodi = { :dirs_to_roodi => ['lib'] }
10
- config.saikuro = { :output_directory => 'scratch_directory/saikuro',
11
- :input_directory => ['lib'],
12
- :cyclo => "",
13
- :filter_cyclo => "0",
14
- :warn_cyclo => "5",
15
- :error_cyclo => "7",
16
- :formater => "text"} #this needs to be set to "text"
17
- config.churn = { :start_date => "1 year ago", :minimum_churn_count => 10}
18
- config.rcov = { :environment => 'test',
19
- :test_files => ['test/*_test.rb'],
20
- :rcov_opts => ["--sort coverage",
21
- "--no-html",
22
- "--text-coverage",
23
- "--profile",
24
- "--exclude /gems/,/Library/,spec"]}
25
- config.graph_engine = :bluff
26
- end
27
-
28
- namespace :metrics do
29
- TEST_PATHS_FOR_RCOV = ['test/*_test.rb']
30
- end
31
-