smile 0.3.1 → 0.4.0

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/.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
-