ruby-picasa 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +11 -0
 - data/Rakefile +3 -0
 - data/lib/ruby_picasa.rb +124 -30
 - data/lib/ruby_picasa/types.rb +143 -31
 - data/spec/ruby_picasa/types_spec.rb +82 -8
 - data/spec/ruby_picasa_spec.rb +33 -9
 - metadata +3 -3
 
    
        data/History.txt
    CHANGED
    
    | 
         @@ -1,3 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            === 0.2.1 / 2009-03-05
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            * Now fully documented.
         
     | 
| 
      
 4 
     | 
    
         
            +
            * Full spec suite with 100% coverage.
         
     | 
| 
      
 5 
     | 
    
         
            +
            * Even easier to use the api.
         
     | 
| 
      
 6 
     | 
    
         
            +
            * Move thumbnail and url to Base so it can be used for Photos and Albums. 
         
     | 
| 
      
 7 
     | 
    
         
            +
            * Enable url to optionally return width and height for image_tag.
         
     | 
| 
      
 8 
     | 
    
         
            +
            * Use the numeric gphoto:id as id and rename tho standard atom feed id to feed_id
         
     | 
| 
      
 9 
     | 
    
         
            +
            * Fixed handling of cropped thumbnails and automatically query for valid thumbnail sizes.
         
     | 
| 
      
 10 
     | 
    
         
            +
            * Stopped using the wrong url to #load albums. Renamed method to #feed.
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
       1 
12 
     | 
    
         
             
            === 0.2.0 / 2009-02-25
         
     | 
| 
       2 
13 
     | 
    
         | 
| 
       3 
14 
     | 
    
         
             
            * First public release.
         
     | 
    
        data/Rakefile
    CHANGED
    
    
    
        data/lib/ruby_picasa.rb
    CHANGED
    
    | 
         @@ -6,7 +6,7 @@ require 'net/https' 
     | 
|
| 
       6 
6 
     | 
    
         
             
            require File.join(File.dirname(__FILE__), 'ruby_picasa/types')
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
            module RubyPicasa
         
     | 
| 
       9 
     | 
    
         
            -
              VERSION = '0.2. 
     | 
| 
      
 9 
     | 
    
         
            +
              VERSION = '0.2.1'
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
              class PicasaError < StandardError
         
     | 
| 
       12 
12 
     | 
    
         
             
              end
         
     | 
| 
         @@ -15,20 +15,53 @@ module RubyPicasa 
     | 
|
| 
       15 
15 
     | 
    
         
             
              end
         
     | 
| 
       16 
16 
     | 
    
         
             
            end
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
      
 18 
     | 
    
         
            +
            # == Authorization
         
     | 
| 
      
 19 
     | 
    
         
            +
            #
         
     | 
| 
      
 20 
     | 
    
         
            +
            # RubyPicasa makes authorizing a Rails app easy. It is a two step process: 
         
     | 
| 
      
 21 
     | 
    
         
            +
            #
         
     | 
| 
      
 22 
     | 
    
         
            +
            # First redirect the user to the authorization url, if the user authorizes your
         
     | 
| 
      
 23 
     | 
    
         
            +
            # application, Picasa will redirect the user back to the url you specify (in
         
     | 
| 
      
 24 
     | 
    
         
            +
            # this case authorize_picasa_url). 
         
     | 
| 
      
 25 
     | 
    
         
            +
            #
         
     | 
| 
      
 26 
     | 
    
         
            +
            # Next, pass the Rails request object to the authorize_token method which will
         
     | 
| 
      
 27 
     | 
    
         
            +
            # make the api call to upgrade the token and if successful return an initialized
         
     | 
| 
      
 28 
     | 
    
         
            +
            # Picasa session object ready to use. The token object can be retrieved from the
         
     | 
| 
      
 29 
     | 
    
         
            +
            # token attribute.
         
     | 
| 
      
 30 
     | 
    
         
            +
            #
         
     | 
| 
      
 31 
     | 
    
         
            +
            #   class PicasaController < ApplicationController
         
     | 
| 
      
 32 
     | 
    
         
            +
            #     def request_authorization
         
     | 
| 
      
 33 
     | 
    
         
            +
            #       redirect_to Picasa.authorization_url(authorize_picasa_url)
         
     | 
| 
      
 34 
     | 
    
         
            +
            #     end
         
     | 
| 
      
 35 
     | 
    
         
            +
            #
         
     | 
| 
      
 36 
     | 
    
         
            +
            #     def authorize
         
     | 
| 
      
 37 
     | 
    
         
            +
            #       if Picasa.token_in_request?(request)
         
     | 
| 
      
 38 
     | 
    
         
            +
            #         begin
         
     | 
| 
      
 39 
     | 
    
         
            +
            #           picasa = Picasa.authorize_request(request)
         
     | 
| 
      
 40 
     | 
    
         
            +
            #           current_user.picasa_token = picasa.token
         
     | 
| 
      
 41 
     | 
    
         
            +
            #           current_user.save
         
     | 
| 
      
 42 
     | 
    
         
            +
            #           flash[:notice] = 'Picasa authorization complete'
         
     | 
| 
      
 43 
     | 
    
         
            +
            #           redirect_to picasa_path
         
     | 
| 
      
 44 
     | 
    
         
            +
            #         rescue PicasaTokenError => e
         
     | 
| 
      
 45 
     | 
    
         
            +
            #           # 
         
     | 
| 
      
 46 
     | 
    
         
            +
            #           @error = e.message
         
     | 
| 
      
 47 
     | 
    
         
            +
            #           render
         
     | 
| 
      
 48 
     | 
    
         
            +
            #         end
         
     | 
| 
      
 49 
     | 
    
         
            +
            #       end
         
     | 
| 
      
 50 
     | 
    
         
            +
            #     end
         
     | 
| 
      
 51 
     | 
    
         
            +
            #   end
         
     | 
| 
      
 52 
     | 
    
         
            +
            #
         
     | 
| 
       18 
53 
     | 
    
         
             
            class Picasa
         
     | 
| 
       19 
     | 
    
         
            -
              include RubyPicasa
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
54 
     | 
    
         
             
              class << self
         
     | 
| 
       22 
55 
     | 
    
         
             
                # The user must be redirected to this address to authorize the application
         
     | 
| 
       23 
56 
     | 
    
         
             
                # to access their Picasa account. The token_from_request and
         
     | 
| 
       24 
57 
     | 
    
         
             
                # authorize_request methods can be used to handle the resulting redirect
         
     | 
| 
       25 
58 
     | 
    
         
             
                # from Picasa.
         
     | 
| 
       26 
     | 
    
         
            -
                def authorization_url(return_to_url, request_session = true, secure = false)
         
     | 
| 
      
 59 
     | 
    
         
            +
                def authorization_url(return_to_url, request_session = true, secure = false, authsub_url = nil)
         
     | 
| 
       27 
60 
     | 
    
         
             
                  session = request_session ? '1' : '0'
         
     | 
| 
       28 
61 
     | 
    
         
             
                  secure = secure ? '1' : '0'
         
     | 
| 
       29 
62 
     | 
    
         
             
                  return_to_url = CGI.escape(return_to_url)
         
     | 
| 
       30 
     | 
    
         
            -
                  url = 'http://www.google.com/accounts/AuthSubRequest'
         
     | 
| 
       31 
     | 
    
         
            -
                  "#{ url }?scope=http%3A%2F% 
     | 
| 
      
 63 
     | 
    
         
            +
                  url = authsub_url || 'http://www.google.com/accounts/AuthSubRequest'
         
     | 
| 
      
 64 
     | 
    
         
            +
                  "#{ url }?scope=http%3A%2F%2F#{ host }%2Fdata%2F&session=#{ session }&secure=#{ secure }&next=#{ return_to_url }"
         
     | 
| 
       32 
65 
     | 
    
         
             
                end
         
     | 
| 
       33 
66 
     | 
    
         | 
| 
       34 
67 
     | 
    
         
             
                # Takes a Rails request object and extracts the token from it. This would
         
     | 
| 
         @@ -38,10 +71,14 @@ class Picasa 
     | 
|
| 
       38 
71 
     | 
    
         
             
                  if token = request.params['token']
         
     | 
| 
       39 
72 
     | 
    
         
             
                    return token
         
     | 
| 
       40 
73 
     | 
    
         
             
                  else
         
     | 
| 
       41 
     | 
    
         
            -
                    raise PicasaTokenError, 'No Picasa authorization token was found.'
         
     | 
| 
      
 74 
     | 
    
         
            +
                    raise RubyPicasa::PicasaTokenError, 'No Picasa authorization token was found.'
         
     | 
| 
       42 
75 
     | 
    
         
             
                  end
         
     | 
| 
       43 
76 
     | 
    
         
             
                end
         
     | 
| 
       44 
77 
     | 
    
         | 
| 
      
 78 
     | 
    
         
            +
                def token_in_request?(request)
         
     | 
| 
      
 79 
     | 
    
         
            +
                  request.params['token']
         
     | 
| 
      
 80 
     | 
    
         
            +
                end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
       45 
82 
     | 
    
         
             
                # Takes a Rails request object as in token_from_request, then makes the
         
     | 
| 
       46 
83 
     | 
    
         
             
                # token authorization request to produce the permanent token. This will
         
     | 
| 
       47 
84 
     | 
    
         
             
                # only work if request_session was true when you created the
         
     | 
| 
         @@ -52,10 +89,20 @@ class Picasa 
     | 
|
| 
       52 
89 
     | 
    
         
             
                  p
         
     | 
| 
       53 
90 
     | 
    
         
             
                end
         
     | 
| 
       54 
91 
     | 
    
         | 
| 
      
 92 
     | 
    
         
            +
                # The url to make requests to without the protocol or path.
         
     | 
| 
       55 
93 
     | 
    
         
             
                def host
         
     | 
| 
       56 
     | 
    
         
            -
                  'picasaweb.google.com'
         
     | 
| 
      
 94 
     | 
    
         
            +
                  @host ||= 'picasaweb.google.com'
         
     | 
| 
      
 95 
     | 
    
         
            +
                end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                # In the unlikely event that you need to access this api on a different url,
         
     | 
| 
      
 98 
     | 
    
         
            +
                # you can set it here. It defaults to picasaweb.google.com
         
     | 
| 
      
 99 
     | 
    
         
            +
                def host=(h)
         
     | 
| 
      
 100 
     | 
    
         
            +
                  @host = h
         
     | 
| 
       57 
101 
     | 
    
         
             
                end
         
     | 
| 
       58 
102 
     | 
    
         | 
| 
      
 103 
     | 
    
         
            +
                # A simple test used to determine if a given resource id is it's full
         
     | 
| 
      
 104 
     | 
    
         
            +
                # identifier url. This is not intended to be a general purpose method as the
         
     | 
| 
      
 105 
     | 
    
         
            +
                # test is just a check for the http/https protocol prefix.
         
     | 
| 
       59 
106 
     | 
    
         
             
                def is_url?(path)
         
     | 
| 
       60 
107 
     | 
    
         
             
                  path.to_s =~ %r{\Ahttps?://}
         
     | 
| 
       61 
108 
     | 
    
         
             
                end
         
     | 
| 
         @@ -99,6 +146,12 @@ class Picasa 
     | 
|
| 
       99 
146 
     | 
    
         
             
                    path = path.join('/')
         
     | 
| 
       100 
147 
     | 
    
         
             
                  end
         
     | 
| 
       101 
148 
     | 
    
         
             
                  options['kind'] = 'photo' if args[:recent_photos] or args[:album_id]
         
     | 
| 
      
 149 
     | 
    
         
            +
                  if args[:thumbsize] and not args[:thumbsize].split(/,/).all? { |s| RubyPicasa::Photo::VALID.include?(s) }
         
     | 
| 
      
 150 
     | 
    
         
            +
                    raise RubyPicasa::PicasaError, 'Invalid thumbsize.'
         
     | 
| 
      
 151 
     | 
    
         
            +
                  end
         
     | 
| 
      
 152 
     | 
    
         
            +
                  if args[:imgmax] and not RubyPicasa::Photo::VALID.include?(args[:imgmax])
         
     | 
| 
      
 153 
     | 
    
         
            +
                    raise RubyPicasa::PicasaError, 'Invalid imgmax.'
         
     | 
| 
      
 154 
     | 
    
         
            +
                  end
         
     | 
| 
       102 
155 
     | 
    
         
             
                  [:max_results, :start_index, :tag, :q, :kind,
         
     | 
| 
       103 
156 
     | 
    
         
             
                   :access, :thumbsize, :imgmax, :bbox, :l].each do |arg|
         
     | 
| 
       104 
157 
     | 
    
         
             
                    options[arg.to_s.dasherize] = args[arg] if args[arg]
         
     | 
| 
         @@ -112,6 +165,8 @@ class Picasa 
     | 
|
| 
       112 
165 
     | 
    
         | 
| 
       113 
166 
     | 
    
         
             
                private
         
     | 
| 
       114 
167 
     | 
    
         | 
| 
      
 168 
     | 
    
         
            +
                # Extract the path and a hash of key/value pairs from a given url with
         
     | 
| 
      
 169 
     | 
    
         
            +
                # optional query string.
         
     | 
| 
       115 
170 
     | 
    
         
             
                def parse_url(args)
         
     | 
| 
       116 
171 
     | 
    
         
             
                  url = args[:url]
         
     | 
| 
       117 
172 
     | 
    
         
             
                  url ||= args[:user_id] if is_url?(args[:user_id]) 
         
     | 
| 
         @@ -133,6 +188,7 @@ class Picasa 
     | 
|
| 
       133 
188 
     | 
    
         
             
                end
         
     | 
| 
       134 
189 
     | 
    
         
             
              end
         
     | 
| 
       135 
190 
     | 
    
         | 
| 
      
 191 
     | 
    
         
            +
              # The AuthSub token currently in use.
         
     | 
| 
       136 
192 
     | 
    
         
             
              attr_reader :token
         
     | 
| 
       137 
193 
     | 
    
         | 
| 
       138 
194 
     | 
    
         
             
              def initialize(token)
         
     | 
| 
         @@ -140,6 +196,8 @@ class Picasa 
     | 
|
| 
       140 
196 
     | 
    
         
             
                @request_cache = {}
         
     | 
| 
       141 
197 
     | 
    
         
             
              end
         
     | 
| 
       142 
198 
     | 
    
         | 
| 
      
 199 
     | 
    
         
            +
              # Attempt to upgrade the current AuthSub token to a permanent one. This only
         
     | 
| 
      
 200 
     | 
    
         
            +
              # works if the Picasa session is initialized with a single use token.
         
     | 
| 
       143 
201 
     | 
    
         
             
              def authorize_token!
         
     | 
| 
       144 
202 
     | 
    
         
             
                http = Net::HTTP.new("www.google.com", 443)
         
     | 
| 
       145 
203 
     | 
    
         
             
                http.use_ssl = true
         
     | 
| 
         @@ -153,15 +211,22 @@ class Picasa 
     | 
|
| 
       153 
211 
     | 
    
         
             
                @token
         
     | 
| 
       154 
212 
     | 
    
         
             
              end
         
     | 
| 
       155 
213 
     | 
    
         | 
| 
       156 
     | 
    
         
            -
               
     | 
| 
       157 
     | 
    
         
            -
             
     | 
| 
      
 214 
     | 
    
         
            +
              # Retrieve a RubyPicasa::User record including all user albums.
         
     | 
| 
      
 215 
     | 
    
         
            +
              def user(user_id_or_url = nil, options = {})
         
     | 
| 
      
 216 
     | 
    
         
            +
                options = make_options(:user_id, user_id_or_url, options)
         
     | 
| 
      
 217 
     | 
    
         
            +
                get(options)
         
     | 
| 
       158 
218 
     | 
    
         
             
              end
         
     | 
| 
       159 
219 
     | 
    
         | 
| 
      
 220 
     | 
    
         
            +
              # Retrieve a RubyPicasa::Album record. If you pass an id or a feed url it will
         
     | 
| 
      
 221 
     | 
    
         
            +
              # include all photos. If you pass an entry url, it will not include photos.
         
     | 
| 
       160 
222 
     | 
    
         
             
              def album(album_id_or_url, options = {})
         
     | 
| 
       161 
     | 
    
         
            -
                 
     | 
| 
      
 223 
     | 
    
         
            +
                options = make_options(:album_id, album_id_or_url, options)
         
     | 
| 
      
 224 
     | 
    
         
            +
                get(options)
         
     | 
| 
       162 
225 
     | 
    
         
             
              end
         
     | 
| 
       163 
226 
     | 
    
         | 
| 
       164 
     | 
    
         
            -
              # This request does not require authentication.
         
     | 
| 
      
 227 
     | 
    
         
            +
              # This request does not require authentication. Returns a RubyPicasa::Search
         
     | 
| 
      
 228 
     | 
    
         
            +
              # object containing the first 10 matches. You can call #next and #previous to
         
     | 
| 
      
 229 
     | 
    
         
            +
              # navigate the paginated results on the Search object.
         
     | 
| 
       165 
230 
     | 
    
         
             
              def search(q, options = {})
         
     | 
| 
       166 
231 
     | 
    
         
             
                h = {}
         
     | 
| 
       167 
232 
     | 
    
         
             
                h[:max_results] = 10
         
     | 
| 
         @@ -171,27 +236,32 @@ class Picasa 
     | 
|
| 
       171 
236 
     | 
    
         
             
                get(h.merge(options).merge(:q => q))
         
     | 
| 
       172 
237 
     | 
    
         
             
              end
         
     | 
| 
       173 
238 
     | 
    
         | 
| 
      
 239 
     | 
    
         
            +
              # Retrieve a RubyPicasa object determined by the type of xml results returned
         
     | 
| 
      
 240 
     | 
    
         
            +
              # by Picasa. Any supported type of RubyPicasa resource can be requested with
         
     | 
| 
      
 241 
     | 
    
         
            +
              # this method.
         
     | 
| 
       174 
242 
     | 
    
         
             
              def get_url(url, options = {})
         
     | 
| 
       175 
     | 
    
         
            -
                 
     | 
| 
      
 243 
     | 
    
         
            +
                options = make_options(:url, url, options)
         
     | 
| 
      
 244 
     | 
    
         
            +
                get(options)
         
     | 
| 
       176 
245 
     | 
    
         
             
              end
         
     | 
| 
       177 
246 
     | 
    
         | 
| 
       178 
     | 
    
         
            -
               
     | 
| 
       179 
     | 
    
         
            -
             
     | 
| 
       180 
     | 
    
         
            -
             
     | 
| 
       181 
     | 
    
         
            -
             
     | 
| 
       182 
     | 
    
         
            -
                 
     | 
| 
       183 
     | 
    
         
            -
                 
     | 
| 
       184 
     | 
    
         
            -
                h[:user_id] = user_id_or_url
         
     | 
| 
       185 
     | 
    
         
            -
                h[:recent_photos] = true
         
     | 
| 
       186 
     | 
    
         
            -
                get(options.merge(h))
         
     | 
| 
      
 247 
     | 
    
         
            +
              # Retrieve a RubyPicasa::RecentPhotos object, essentially a User object which
         
     | 
| 
      
 248 
     | 
    
         
            +
              # contains photos instead of albums.
         
     | 
| 
      
 249 
     | 
    
         
            +
              def recent_photos(user_id_or_url, options = {})
         
     | 
| 
      
 250 
     | 
    
         
            +
                options = make_options(:user_id, user_id_or_url, options)
         
     | 
| 
      
 251 
     | 
    
         
            +
                options[:recent_photos] = true
         
     | 
| 
      
 252 
     | 
    
         
            +
                get(options)
         
     | 
| 
       187 
253 
     | 
    
         
             
              end
         
     | 
| 
       188 
254 
     | 
    
         | 
| 
      
 255 
     | 
    
         
            +
              # Retrieves the user's albums and finds the first one with a matching title.
         
     | 
| 
      
 256 
     | 
    
         
            +
              # Returns a RubyPicasa::Album object.
         
     | 
| 
       189 
257 
     | 
    
         
             
              def album_by_title(title, options = {})
         
     | 
| 
       190 
258 
     | 
    
         
             
                if a = user.albums.find { |a| title === a.title }
         
     | 
| 
       191 
259 
     | 
    
         
             
                  a.load options
         
     | 
| 
       192 
260 
     | 
    
         
             
                end
         
     | 
| 
       193 
261 
     | 
    
         
             
              end
         
     | 
| 
       194 
262 
     | 
    
         | 
| 
      
 263 
     | 
    
         
            +
              # Returns the raw xml from Picasa. See the Picasa.path method for valid
         
     | 
| 
      
 264 
     | 
    
         
            +
              # options.
         
     | 
| 
       195 
265 
     | 
    
         
             
              def xml(options = {})
         
     | 
| 
       196 
266 
     | 
    
         
             
                http = Net::HTTP.new(Picasa.host, 80)
         
     | 
| 
       197 
267 
     | 
    
         
             
                path = Picasa.path(options)
         
     | 
| 
         @@ -201,14 +271,31 @@ class Picasa 
     | 
|
| 
       201 
271 
     | 
    
         
             
                end
         
     | 
| 
       202 
272 
     | 
    
         
             
              end
         
     | 
| 
       203 
273 
     | 
    
         | 
| 
      
 274 
     | 
    
         
            +
              private
         
     | 
| 
      
 275 
     | 
    
         
            +
             
     | 
| 
      
 276 
     | 
    
         
            +
              # If the value parameter is a hash, treat it as the options hash, otherwise
         
     | 
| 
      
 277 
     | 
    
         
            +
              # insert the value into the hash with the key specified.
         
     | 
| 
      
 278 
     | 
    
         
            +
              #
         
     | 
| 
      
 279 
     | 
    
         
            +
              # Uses merge to ensure that a new hash object is returned to prevent caller's
         
     | 
| 
      
 280 
     | 
    
         
            +
              # has from accidentally being modified.
         
     | 
| 
      
 281 
     | 
    
         
            +
              def make_options(key, value, options)
         
     | 
| 
      
 282 
     | 
    
         
            +
                if value.is_a? Hash
         
     | 
| 
      
 283 
     | 
    
         
            +
                  {}.merge value
         
     | 
| 
      
 284 
     | 
    
         
            +
                else
         
     | 
| 
      
 285 
     | 
    
         
            +
                  options ||= {}
         
     | 
| 
      
 286 
     | 
    
         
            +
                  options.merge(key => value)
         
     | 
| 
      
 287 
     | 
    
         
            +
                end
         
     | 
| 
      
 288 
     | 
    
         
            +
              end
         
     | 
| 
      
 289 
     | 
    
         
            +
             
     | 
| 
      
 290 
     | 
    
         
            +
              # Combines the cached xml request with the class_from_xml factory. See the
         
     | 
| 
      
 291 
     | 
    
         
            +
              # Picasa.path method for valid options.
         
     | 
| 
       204 
292 
     | 
    
         
             
              def get(options = {})
         
     | 
| 
       205 
293 
     | 
    
         
             
                with_cache(options) do |xml|
         
     | 
| 
       206 
294 
     | 
    
         
             
                  class_from_xml(xml)
         
     | 
| 
       207 
295 
     | 
    
         
             
                end
         
     | 
| 
       208 
296 
     | 
    
         
             
              end
         
     | 
| 
       209 
297 
     | 
    
         | 
| 
       210 
     | 
    
         
            -
               
     | 
| 
       211 
     | 
    
         
            -
             
     | 
| 
      
 298 
     | 
    
         
            +
              # Returns the header data needed to make AuthSub requests.
         
     | 
| 
       212 
299 
     | 
    
         
             
              def auth_header
         
     | 
| 
       213 
300 
     | 
    
         
             
                if token
         
     | 
| 
       214 
301 
     | 
    
         
             
                  { "Authorization" => %{AuthSub token="#{ token }"} }
         
     | 
| 
         @@ -217,6 +304,7 @@ class Picasa 
     | 
|
| 
       217 
304 
     | 
    
         
             
                end
         
     | 
| 
       218 
305 
     | 
    
         
             
              end
         
     | 
| 
       219 
306 
     | 
    
         | 
| 
      
 307 
     | 
    
         
            +
              # Caches the raw xml returned from the API. Keyed on request url.
         
     | 
| 
       220 
308 
     | 
    
         
             
              def with_cache(options)
         
     | 
| 
       221 
309 
     | 
    
         
             
                path = Picasa.path(options)
         
     | 
| 
       222 
310 
     | 
    
         
             
                @request_cache.delete(path) if options[:reload]
         
     | 
| 
         @@ -231,6 +319,10 @@ class Picasa 
     | 
|
| 
       231 
319 
     | 
    
         
             
                end
         
     | 
| 
       232 
320 
     | 
    
         
             
              end
         
     | 
| 
       233 
321 
     | 
    
         | 
| 
      
 322 
     | 
    
         
            +
              # Returns the first xml element in the document (see
         
     | 
| 
      
 323 
     | 
    
         
            +
              # Objectify::Xml.first_element) with the xml data types of the feed and first entry
         
     | 
| 
      
 324 
     | 
    
         
            +
              # element in the document, used to determine which RubyPicasa object should
         
     | 
| 
      
 325 
     | 
    
         
            +
              # be initialized to handle the data.
         
     | 
| 
       234 
326 
     | 
    
         
             
              def xml_data(xml)
         
     | 
| 
       235 
327 
     | 
    
         
             
                if xml = Objectify::Xml.first_element(xml)
         
     | 
| 
       236 
328 
     | 
    
         
             
                  # There is something wrong with Nokogiri xpath/css search with
         
     | 
| 
         @@ -244,6 +336,8 @@ class Picasa 
     | 
|
| 
       244 
336 
     | 
    
         
             
                end
         
     | 
| 
       245 
337 
     | 
    
         
             
              end
         
     | 
| 
       246 
338 
     | 
    
         | 
| 
      
 339 
     | 
    
         
            +
              # Initialize the correct RubyPicasa object depending on the type of feed and
         
     | 
| 
      
 340 
     | 
    
         
            +
              # entries in the document.
         
     | 
| 
       247 
341 
     | 
    
         
             
              def class_from_xml(xml)
         
     | 
| 
       248 
342 
     | 
    
         
             
                xml, feed_scheme, entry_scheme = xml_data(xml)
         
     | 
| 
       249 
343 
     | 
    
         
             
                if xml
         
     | 
| 
         @@ -251,28 +345,28 @@ class Picasa 
     | 
|
| 
       251 
345 
     | 
    
         
             
                  when /#user$/
         
     | 
| 
       252 
346 
     | 
    
         
             
                    case entry_scheme
         
     | 
| 
       253 
347 
     | 
    
         
             
                    when /#album$/
         
     | 
| 
       254 
     | 
    
         
            -
                      User.new(xml, self)
         
     | 
| 
      
 348 
     | 
    
         
            +
                      RubyPicasa::User.new(xml, self)
         
     | 
| 
       255 
349 
     | 
    
         
             
                    when /#photo$/
         
     | 
| 
       256 
     | 
    
         
            -
                      RecentPhotos.new(xml, self)
         
     | 
| 
      
 350 
     | 
    
         
            +
                      RubyPicasa::RecentPhotos.new(xml, self)
         
     | 
| 
       257 
351 
     | 
    
         
             
                    end
         
     | 
| 
       258 
352 
     | 
    
         
             
                  when /#album$/
         
     | 
| 
       259 
353 
     | 
    
         
             
                    case entry_scheme
         
     | 
| 
       260 
354 
     | 
    
         
             
                    when nil, /#photo$/
         
     | 
| 
       261 
     | 
    
         
            -
                      Album.new(xml, self)
         
     | 
| 
      
 355 
     | 
    
         
            +
                      RubyPicasa::Album.new(xml, self)
         
     | 
| 
       262 
356 
     | 
    
         
             
                    end
         
     | 
| 
       263 
357 
     | 
    
         
             
                  when /#photo$/
         
     | 
| 
       264 
358 
     | 
    
         
             
                    case entry_scheme
         
     | 
| 
       265 
359 
     | 
    
         
             
                    when /#photo$/
         
     | 
| 
       266 
     | 
    
         
            -
                      Search.new(xml, self)
         
     | 
| 
      
 360 
     | 
    
         
            +
                      RubyPicasa::Search.new(xml, self)
         
     | 
| 
       267 
361 
     | 
    
         
             
                    when nil
         
     | 
| 
       268 
     | 
    
         
            -
                      Photo.new(xml, self)
         
     | 
| 
      
 362 
     | 
    
         
            +
                      RubyPicasa::Photo.new(xml, self)
         
     | 
| 
       269 
363 
     | 
    
         
             
                    end
         
     | 
| 
       270 
364 
     | 
    
         
             
                  end
         
     | 
| 
       271 
365 
     | 
    
         
             
                  if r
         
     | 
| 
       272 
366 
     | 
    
         
             
                    r.session = self
         
     | 
| 
       273 
367 
     | 
    
         
             
                    r
         
     | 
| 
       274 
368 
     | 
    
         
             
                  else
         
     | 
| 
       275 
     | 
    
         
            -
                    raise PicasaError, "Unknown feed type\n feed:  #{ feed_scheme }\n entry: #{ entry_scheme }"
         
     | 
| 
      
 369 
     | 
    
         
            +
                    raise RubyPicasa::PicasaError, "Unknown feed type\n feed:  #{ feed_scheme }\n entry: #{ entry_scheme }"
         
     | 
| 
       276 
370 
     | 
    
         
             
                  end
         
     | 
| 
       277 
371 
     | 
    
         
             
                end
         
     | 
| 
       278 
372 
     | 
    
         
             
              end
         
     | 
    
        data/lib/ruby_picasa/types.rb
    CHANGED
    
    | 
         @@ -2,34 +2,43 @@ 
     | 
|
| 
       2 
2 
     | 
    
         
             
            # about. If you care about them, please feel free to add support for them,
         
     | 
| 
       3 
3 
     | 
    
         
             
            # which should not be difficult.
         
     | 
| 
       4 
4 
     | 
    
         
             
            #
         
     | 
| 
       5 
     | 
    
         
            -
            #  
     | 
| 
       6 
     | 
    
         
            -
            # in the xml document is already plural. (Convention seems to be to label
         
     | 
| 
       7 
     | 
    
         
            -
            # repeating elements in the singular.)
         
     | 
| 
       8 
     | 
    
         
            -
            #
         
     | 
| 
       9 
     | 
    
         
            -
            # If an attribute should be a non-trivial datatype, define the mapping from
         
     | 
| 
       10 
     | 
    
         
            -
            # the fully namespaced attribute name to the class you wish to use in the
         
     | 
| 
       11 
     | 
    
         
            -
            # class method #types.
         
     | 
| 
       12 
     | 
    
         
            -
            #
         
     | 
| 
       13 
     | 
    
         
            -
            # Define which namespaces you support in the class method #namespaces. Any
         
     | 
| 
      
 5 
     | 
    
         
            +
            # Declare which namespaces are supported with the namespaces method. Any
         
     | 
| 
       14 
6 
     | 
    
         
             
            # elements defined in other namespaces are automatically ignored.
         
     | 
| 
       15 
7 
     | 
    
         
             
            module RubyPicasa
         
     | 
| 
      
 8 
     | 
    
         
            +
              # attributes :url, :height, :width
         
     | 
| 
       16 
9 
     | 
    
         
             
              class PhotoUrl < Objectify::ElementParser
         
     | 
| 
       17 
10 
     | 
    
         
             
                attributes :url, :height, :width
         
     | 
| 
       18 
11 
     | 
    
         
             
              end
         
     | 
| 
       19 
12 
     | 
    
         | 
| 
       20 
13 
     | 
    
         | 
| 
       21 
14 
     | 
    
         
             
              class ThumbnailUrl < PhotoUrl
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                # The name of the current thumbnail. For possible names, see Photo#url
         
     | 
| 
       22 
17 
     | 
    
         
             
                def thumb_name
         
     | 
| 
       23 
     | 
    
         
            -
                  url.scan(%r{/([^/]+)/[^/]+$}).flatten.compact.first
         
     | 
| 
      
 18 
     | 
    
         
            +
                  name = url.scan(%r{/s([^/]+)/[^/]+$}).flatten.compact.first
         
     | 
| 
      
 19 
     | 
    
         
            +
                  if name
         
     | 
| 
      
 20 
     | 
    
         
            +
                    name.sub(/-/, '')
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
       24 
22 
     | 
    
         
             
                end
         
     | 
| 
       25 
23 
     | 
    
         
             
              end
         
     | 
| 
       26 
24 
     | 
    
         | 
| 
       27 
25 
     | 
    
         | 
| 
      
 26 
     | 
    
         
            +
              # Base class for User, Photo and Album types, not used independently.
         
     | 
| 
      
 27 
     | 
    
         
            +
              #
         
     | 
| 
      
 28 
     | 
    
         
            +
              #   attribute :id, 'gphoto:id'
         
     | 
| 
      
 29 
     | 
    
         
            +
              #   attribute :feed_id, 'id'
         
     | 
| 
      
 30 
     | 
    
         
            +
              #   attributes :updated, :title
         
     | 
| 
      
 31 
     | 
    
         
            +
              #   
         
     | 
| 
      
 32 
     | 
    
         
            +
              #   has_many :links, Objectify::Atom::Link, 'link'
         
     | 
| 
      
 33 
     | 
    
         
            +
              #   has_one :content, PhotoUrl, 'media:content'
         
     | 
| 
      
 34 
     | 
    
         
            +
              #   has_many :thumbnails, ThumbnailUrl, 'media:thumbnail'
         
     | 
| 
      
 35 
     | 
    
         
            +
              #   has_one :author, Objectify::Atom::Author, 'author'
         
     | 
| 
       28 
36 
     | 
    
         
             
              class Base < Objectify::DocumentParser
         
     | 
| 
       29 
37 
     | 
    
         
             
                namespaces :openSearch, :gphoto, :media
         
     | 
| 
       30 
38 
     | 
    
         
             
                flatten 'media:group'
         
     | 
| 
       31 
39 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
                attribute :id, 'id'
         
     | 
| 
      
 40 
     | 
    
         
            +
                attribute :id, 'gphoto:id'
         
     | 
| 
      
 41 
     | 
    
         
            +
                attribute :feed_id, 'id'
         
     | 
| 
       33 
42 
     | 
    
         
             
                attributes :updated, :title
         
     | 
| 
       34 
43 
     | 
    
         | 
| 
       35 
44 
     | 
    
         
             
                has_many :links, Objectify::Atom::Link, 'link'
         
     | 
| 
         @@ -37,14 +46,16 @@ module RubyPicasa 
     | 
|
| 
       37 
46 
     | 
    
         
             
                has_many :thumbnails, ThumbnailUrl, 'media:thumbnail'
         
     | 
| 
       38 
47 
     | 
    
         
             
                has_one :author, Objectify::Atom::Author, 'author'
         
     | 
| 
       39 
48 
     | 
    
         | 
| 
      
 49 
     | 
    
         
            +
                # Return the link object with the specified rel attribute value.
         
     | 
| 
       40 
50 
     | 
    
         
             
                def link(rel)
         
     | 
| 
       41 
     | 
    
         
            -
                  links.find { |l|  
     | 
| 
      
 51 
     | 
    
         
            +
                  links.find { |l| rel === l.rel }
         
     | 
| 
       42 
52 
     | 
    
         
             
                end
         
     | 
| 
       43 
53 
     | 
    
         | 
| 
       44 
54 
     | 
    
         
             
                def session=(session)
         
     | 
| 
       45 
55 
     | 
    
         
             
                  @session = session
         
     | 
| 
       46 
56 
     | 
    
         
             
                end
         
     | 
| 
       47 
57 
     | 
    
         | 
| 
      
 58 
     | 
    
         
            +
                # Should return the Picasa instance that retrieved this data.
         
     | 
| 
       48 
59 
     | 
    
         
             
                def session
         
     | 
| 
       49 
60 
     | 
    
         
             
                  if @session
         
     | 
| 
       50 
61 
     | 
    
         
             
                    @session
         
     | 
| 
         @@ -53,24 +64,93 @@ module RubyPicasa 
     | 
|
| 
       53 
64 
     | 
    
         
             
                  end
         
     | 
| 
       54 
65 
     | 
    
         
             
                end
         
     | 
| 
       55 
66 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
                 
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
      
 67 
     | 
    
         
            +
                # Retrieves the data feed at the url of the current record.
         
     | 
| 
      
 68 
     | 
    
         
            +
                def feed(options = {})
         
     | 
| 
      
 69 
     | 
    
         
            +
                  session.get_url(link('http://schemas.google.com/g/2005#feed').href, options)
         
     | 
| 
       58 
70 
     | 
    
         
             
                end
         
     | 
| 
       59 
71 
     | 
    
         | 
| 
      
 72 
     | 
    
         
            +
                # If the results are paginated, retrieve the next page.
         
     | 
| 
       60 
73 
     | 
    
         
             
                def next
         
     | 
| 
       61 
74 
     | 
    
         
             
                  if link = link('next')
         
     | 
| 
       62 
75 
     | 
    
         
             
                    session.get_url(link.href)
         
     | 
| 
       63 
76 
     | 
    
         
             
                  end
         
     | 
| 
       64 
77 
     | 
    
         
             
                end
         
     | 
| 
       65 
78 
     | 
    
         | 
| 
      
 79 
     | 
    
         
            +
                # If the results are paginated, retrieve the previous page.
         
     | 
| 
       66 
80 
     | 
    
         
             
                def previous
         
     | 
| 
       67 
81 
     | 
    
         
             
                  if link = link('previous')
         
     | 
| 
       68 
82 
     | 
    
         
             
                    session.get_url(link.href)
         
     | 
| 
       69 
83 
     | 
    
         
             
                  end
         
     | 
| 
       70 
84 
     | 
    
         
             
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                # Thumbnail names are by image width in pixels. Sizes up to 160 may be
         
     | 
| 
      
 87 
     | 
    
         
            +
                # either cropped (square) or uncropped:
         
     | 
| 
      
 88 
     | 
    
         
            +
                #
         
     | 
| 
      
 89 
     | 
    
         
            +
                #   cropped:        32c, 48c, 64c, 72c, 144c, 160c
         
     | 
| 
      
 90 
     | 
    
         
            +
                #   uncropped:      32u, 48u, 64u, 72u, 144u, 160u
         
     | 
| 
      
 91 
     | 
    
         
            +
                #
         
     | 
| 
      
 92 
     | 
    
         
            +
                # The rest of the image sizes should be specified by the desired width
         
     | 
| 
      
 93 
     | 
    
         
            +
                # alone. Widths up to 800px may be embedded on a webpage:
         
     | 
| 
      
 94 
     | 
    
         
            +
                # 
         
     | 
| 
      
 95 
     | 
    
         
            +
                #   embeddable:     200, 288, 320, 400, 512, 576, 640, 720, 800
         
     | 
| 
      
 96 
     | 
    
         
            +
                #   not embeddable: 912, 1024, 1152, 1280, 1440, 1600
         
     | 
| 
      
 97 
     | 
    
         
            +
                #
         
     | 
| 
      
 98 
     | 
    
         
            +
                # if a options is set to true or a hash is given, the width and height of
         
     | 
| 
      
 99 
     | 
    
         
            +
                # the image will be added to the hash and returned. Useful for passing to
         
     | 
| 
      
 100 
     | 
    
         
            +
                # the rails image_tag helper as follows:
         
     | 
| 
      
 101 
     | 
    
         
            +
                #
         
     | 
| 
      
 102 
     | 
    
         
            +
                #   image_tag(*image.url('72c', { :class => 'thumb' }))
         
     | 
| 
      
 103 
     | 
    
         
            +
                #   
         
     | 
| 
      
 104 
     | 
    
         
            +
                # which results in:
         
     | 
| 
      
 105 
     | 
    
         
            +
                #
         
     | 
| 
      
 106 
     | 
    
         
            +
                #   <img href="..." class="thumb" width="72" height="72">
         
     | 
| 
      
 107 
     | 
    
         
            +
                #
         
     | 
| 
      
 108 
     | 
    
         
            +
                def url(thumb_name = nil, options = nil)
         
     | 
| 
      
 109 
     | 
    
         
            +
                  url = nil
         
     | 
| 
      
 110 
     | 
    
         
            +
                  if thumb_name.is_a? Hash
         
     | 
| 
      
 111 
     | 
    
         
            +
                    options = thumb_name
         
     | 
| 
      
 112 
     | 
    
         
            +
                    thumb_name = nil
         
     | 
| 
      
 113 
     | 
    
         
            +
                  end
         
     | 
| 
      
 114 
     | 
    
         
            +
                  options = {} if options and not options.is_a? Hash
         
     | 
| 
      
 115 
     | 
    
         
            +
                  if thumb_name
         
     | 
| 
      
 116 
     | 
    
         
            +
                    if thumb = thumbnail(thumb_name)
         
     | 
| 
      
 117 
     | 
    
         
            +
                      url = thumb.url
         
     | 
| 
      
 118 
     | 
    
         
            +
                      options = { :width => thumb.width, :height => thumb.height }.merge(options) if options
         
     | 
| 
      
 119 
     | 
    
         
            +
                    end
         
     | 
| 
      
 120 
     | 
    
         
            +
                  else
         
     | 
| 
      
 121 
     | 
    
         
            +
                    url = content.url
         
     | 
| 
      
 122 
     | 
    
         
            +
                    options = { :width => content.width, :height => content.height }.merge(options) if options
         
     | 
| 
      
 123 
     | 
    
         
            +
                  end
         
     | 
| 
      
 124 
     | 
    
         
            +
                  if options
         
     | 
| 
      
 125 
     | 
    
         
            +
                    [url, options]
         
     | 
| 
      
 126 
     | 
    
         
            +
                  else
         
     | 
| 
      
 127 
     | 
    
         
            +
                    url
         
     | 
| 
      
 128 
     | 
    
         
            +
                  end
         
     | 
| 
      
 129 
     | 
    
         
            +
                end
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
                # See +url+ for possible image sizes
         
     | 
| 
      
 132 
     | 
    
         
            +
                def thumbnail(thumb_name)
         
     | 
| 
      
 133 
     | 
    
         
            +
                  raise PicasaError, 'Invalid thumbnail size' unless Photo::VALID.include?(thumb_name.to_s)
         
     | 
| 
      
 134 
     | 
    
         
            +
                  thumb = thumbnails.find { |t| t.thumb_name == thumb_name }
         
     | 
| 
      
 135 
     | 
    
         
            +
                  if thumb
         
     | 
| 
      
 136 
     | 
    
         
            +
                    thumb
         
     | 
| 
      
 137 
     | 
    
         
            +
                  elsif session
         
     | 
| 
      
 138 
     | 
    
         
            +
                    f = feed(:thumbsize => thumb_name)
         
     | 
| 
      
 139 
     | 
    
         
            +
                    if f
         
     | 
| 
      
 140 
     | 
    
         
            +
                      f.thumbnails.first
         
     | 
| 
      
 141 
     | 
    
         
            +
                    end
         
     | 
| 
      
 142 
     | 
    
         
            +
                  end
         
     | 
| 
      
 143 
     | 
    
         
            +
                end
         
     | 
| 
       71 
144 
     | 
    
         
             
              end
         
     | 
| 
       72 
145 
     | 
    
         | 
| 
       73 
146 
     | 
    
         | 
| 
      
 147 
     | 
    
         
            +
              # Includes attributes and associations defined on Base, plus:
         
     | 
| 
      
 148 
     | 
    
         
            +
              #
         
     | 
| 
      
 149 
     | 
    
         
            +
              #   attributes :total_results, # represents total number of albums
         
     | 
| 
      
 150 
     | 
    
         
            +
              #     :start_index,
         
     | 
| 
      
 151 
     | 
    
         
            +
              #     :items_per_page,
         
     | 
| 
      
 152 
     | 
    
         
            +
              #     :thumbnail
         
     | 
| 
      
 153 
     | 
    
         
            +
              #   has_many :entries, :Album, 'entry'
         
     | 
| 
       74 
154 
     | 
    
         
             
              class User < Base
         
     | 
| 
       75 
155 
     | 
    
         
             
                attributes :total_results, # represents total number of albums
         
     | 
| 
       76 
156 
     | 
    
         
             
                  :start_index,
         
     | 
| 
         @@ -78,15 +158,20 @@ module RubyPicasa 
     | 
|
| 
       78 
158 
     | 
    
         
             
                  :thumbnail
         
     | 
| 
       79 
159 
     | 
    
         
             
                has_many :entries, :Album, 'entry'
         
     | 
| 
       80 
160 
     | 
    
         | 
| 
      
 161 
     | 
    
         
            +
                # The current page of albums associated to the user.
         
     | 
| 
       81 
162 
     | 
    
         
             
                def albums
         
     | 
| 
       82 
163 
     | 
    
         
             
                  entries
         
     | 
| 
       83 
164 
     | 
    
         
             
                end
         
     | 
| 
       84 
165 
     | 
    
         
             
              end
         
     | 
| 
       85 
166 
     | 
    
         | 
| 
       86 
167 
     | 
    
         | 
| 
      
 168 
     | 
    
         
            +
              # Includes attributes and associations defined on Base and User, plus:
         
     | 
| 
      
 169 
     | 
    
         
            +
              #
         
     | 
| 
      
 170 
     | 
    
         
            +
              #   has_many :entries, :Photo, 'entry'
         
     | 
| 
       87 
171 
     | 
    
         
             
              class RecentPhotos < User
         
     | 
| 
       88 
172 
     | 
    
         
             
                has_many :entries, :Photo, 'entry'
         
     | 
| 
       89 
173 
     | 
    
         | 
| 
      
 174 
     | 
    
         
            +
                # The current page of recently updated photos associated to the user.
         
     | 
| 
       90 
175 
     | 
    
         
             
                def photos
         
     | 
| 
       91 
176 
     | 
    
         
             
                  entries
         
     | 
| 
       92 
177 
     | 
    
         
             
                end
         
     | 
| 
         @@ -95,11 +180,23 @@ module RubyPicasa 
     | 
|
| 
       95 
180 
     | 
    
         
             
              end
         
     | 
| 
       96 
181 
     | 
    
         | 
| 
       97 
182 
     | 
    
         | 
| 
      
 183 
     | 
    
         
            +
              # Includes attributes and associations defined on Base, plus:
         
     | 
| 
      
 184 
     | 
    
         
            +
              #
         
     | 
| 
      
 185 
     | 
    
         
            +
              #   attributes :published,
         
     | 
| 
      
 186 
     | 
    
         
            +
              #     :summary,
         
     | 
| 
      
 187 
     | 
    
         
            +
              #     :rights,
         
     | 
| 
      
 188 
     | 
    
         
            +
              #     :name,
         
     | 
| 
      
 189 
     | 
    
         
            +
              #     :access,
         
     | 
| 
      
 190 
     | 
    
         
            +
              #     :numphotos, # number of pictures in this album
         
     | 
| 
      
 191 
     | 
    
         
            +
              #     :total_results, # number of pictures matching this 'search'
         
     | 
| 
      
 192 
     | 
    
         
            +
              #     :start_index,
         
     | 
| 
      
 193 
     | 
    
         
            +
              #     :items_per_page,
         
     | 
| 
      
 194 
     | 
    
         
            +
              #     :allow_downloads
         
     | 
| 
      
 195 
     | 
    
         
            +
              #   has_many :entries, :Photo, 'entry'
         
     | 
| 
       98 
196 
     | 
    
         
             
              class Album < Base
         
     | 
| 
       99 
197 
     | 
    
         
             
                attributes :published,
         
     | 
| 
       100 
198 
     | 
    
         
             
                  :summary,
         
     | 
| 
       101 
199 
     | 
    
         
             
                  :rights,
         
     | 
| 
       102 
     | 
    
         
            -
                  :gphoto_id,
         
     | 
| 
       103 
200 
     | 
    
         
             
                  :name,
         
     | 
| 
       104 
201 
     | 
    
         
             
                  :access,
         
     | 
| 
       105 
202 
     | 
    
         
             
                  :numphotos, # number of pictures in this album
         
     | 
| 
         @@ -109,19 +206,25 @@ module RubyPicasa 
     | 
|
| 
       109 
206 
     | 
    
         
             
                  :allow_downloads
         
     | 
| 
       110 
207 
     | 
    
         
             
                has_many :entries, :Photo, 'entry'
         
     | 
| 
       111 
208 
     | 
    
         | 
| 
      
 209 
     | 
    
         
            +
                # True if this album's rights are set to public
         
     | 
| 
       112 
210 
     | 
    
         
             
                def public?
         
     | 
| 
       113 
211 
     | 
    
         
             
                  rights == 'public'
         
     | 
| 
       114 
212 
     | 
    
         
             
                end
         
     | 
| 
       115 
213 
     | 
    
         | 
| 
      
 214 
     | 
    
         
            +
                # True if this album's rights are set to private
         
     | 
| 
       116 
215 
     | 
    
         
             
                def private?
         
     | 
| 
       117 
216 
     | 
    
         
             
                  rights == 'private'
         
     | 
| 
       118 
217 
     | 
    
         
             
                end
         
     | 
| 
       119 
218 
     | 
    
         | 
| 
      
 219 
     | 
    
         
            +
                # The current page of photos in the album.
         
     | 
| 
       120 
220 
     | 
    
         
             
                def photos(options = {})
         
     | 
| 
       121 
221 
     | 
    
         
             
                  if entries.blank? and !@photos_requested
         
     | 
| 
       122 
222 
     | 
    
         
             
                    @photos_requested = true
         
     | 
| 
       123 
     | 
    
         
            -
                     
     | 
| 
       124 
     | 
    
         
            -
             
     | 
| 
      
 223 
     | 
    
         
            +
                    if session and data = feed
         
     | 
| 
      
 224 
     | 
    
         
            +
                      self.entries = data.entries 
         
     | 
| 
      
 225 
     | 
    
         
            +
                    else
         
     | 
| 
      
 226 
     | 
    
         
            +
                      []
         
     | 
| 
      
 227 
     | 
    
         
            +
                    end
         
     | 
| 
       125 
228 
     | 
    
         
             
                  else
         
     | 
| 
       126 
229 
     | 
    
         
             
                    entries
         
     | 
| 
       127 
230 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -130,13 +233,35 @@ module RubyPicasa 
     | 
|
| 
       130 
233 
     | 
    
         | 
| 
       131 
234 
     | 
    
         | 
| 
       132 
235 
     | 
    
         
             
              class Search < Album
         
     | 
| 
      
 236 
     | 
    
         
            +
                # The current page of photos matching the search.
         
     | 
| 
      
 237 
     | 
    
         
            +
                def photos(options = {})
         
     | 
| 
      
 238 
     | 
    
         
            +
                  super
         
     | 
| 
      
 239 
     | 
    
         
            +
                end
         
     | 
| 
       133 
240 
     | 
    
         
             
              end
         
     | 
| 
       134 
241 
     | 
    
         | 
| 
       135 
242 
     | 
    
         | 
| 
      
 243 
     | 
    
         
            +
              # Includes attributes and associations defined on Base, plus:
         
     | 
| 
      
 244 
     | 
    
         
            +
              #
         
     | 
| 
      
 245 
     | 
    
         
            +
              #   attributes :published,
         
     | 
| 
      
 246 
     | 
    
         
            +
              #     :summary,
         
     | 
| 
      
 247 
     | 
    
         
            +
              #     :version, # can use to determine if need to update...
         
     | 
| 
      
 248 
     | 
    
         
            +
              #     :position,
         
     | 
| 
      
 249 
     | 
    
         
            +
              #     :albumid, # useful from the recently updated feed for instance.
         
     | 
| 
      
 250 
     | 
    
         
            +
              #     :width,
         
     | 
| 
      
 251 
     | 
    
         
            +
              #     :height,
         
     | 
| 
      
 252 
     | 
    
         
            +
              #     :description,
         
     | 
| 
      
 253 
     | 
    
         
            +
              #     :keywords,
         
     | 
| 
      
 254 
     | 
    
         
            +
              #     :credit
         
     | 
| 
      
 255 
     | 
    
         
            +
              #   has_one :author, Objectify::Atom::Author, 'author'
         
     | 
| 
       136 
256 
     | 
    
         
             
              class Photo < Base
         
     | 
| 
      
 257 
     | 
    
         
            +
                CROPPED = %w[ 32c 48c 64c 72c 144c 160c ]
         
     | 
| 
      
 258 
     | 
    
         
            +
                UNCROPPED = %w[ 32u 48u 64u 72u 144u 160u 32 48 64 72 144 160 ]
         
     | 
| 
      
 259 
     | 
    
         
            +
                MEDIUM = %w[ 200 288 320 400 512 576 640 720 800 ]
         
     | 
| 
      
 260 
     | 
    
         
            +
                LARGE = %w[ 912 1024 1152 1280 1440 1600 ]
         
     | 
| 
      
 261 
     | 
    
         
            +
                VALID = CROPPED + UNCROPPED + MEDIUM + LARGE
         
     | 
| 
      
 262 
     | 
    
         
            +
             
     | 
| 
       137 
263 
     | 
    
         
             
                attributes :published,
         
     | 
| 
       138 
264 
     | 
    
         
             
                  :summary,
         
     | 
| 
       139 
     | 
    
         
            -
                  :gphoto_id,
         
     | 
| 
       140 
265 
     | 
    
         
             
                  :version, # can use to determine if need to update...
         
     | 
| 
       141 
266 
     | 
    
         
             
                  :position,
         
     | 
| 
       142 
267 
     | 
    
         
             
                  :albumid, # useful from the recently updated feed for instance.
         
     | 
| 
         @@ -147,19 +272,6 @@ module RubyPicasa 
     | 
|
| 
       147 
272 
     | 
    
         
             
                  :credit
         
     | 
| 
       148 
273 
     | 
    
         
             
                has_one :author, Objectify::Atom::Author, 'author'
         
     | 
| 
       149 
274 
     | 
    
         | 
| 
       150 
     | 
    
         
            -
                def url(thumb_name = nil)
         
     | 
| 
       151 
     | 
    
         
            -
                  if thumb_name
         
     | 
| 
       152 
     | 
    
         
            -
                    if thumb = thumbnail(thumb_name)
         
     | 
| 
       153 
     | 
    
         
            -
                      thumb.url
         
     | 
| 
       154 
     | 
    
         
            -
                    end
         
     | 
| 
       155 
     | 
    
         
            -
                  else
         
     | 
| 
       156 
     | 
    
         
            -
                    content.url
         
     | 
| 
       157 
     | 
    
         
            -
                  end
         
     | 
| 
       158 
     | 
    
         
            -
                end
         
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
     | 
    
         
            -
                def thumbnail(thumb_name)
         
     | 
| 
       161 
     | 
    
         
            -
                  thumbnails.find { |t| t.thumb_name == thumb_name }
         
     | 
| 
       162 
     | 
    
         
            -
                end
         
     | 
| 
       163 
275 
     | 
    
         
             
              end
         
     | 
| 
       164 
276 
     | 
    
         
             
            end
         
     | 
| 
       165 
277 
     | 
    
         | 
| 
         @@ -3,8 +3,8 @@ require File.join(File.dirname(__FILE__), '../spec_helper') 
     | 
|
| 
       3 
3 
     | 
    
         
             
            include RubyPicasa
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            describe 'a RubyPicasa document', :shared => true do
         
     | 
| 
       6 
     | 
    
         
            -
              it 'should have  
     | 
| 
       7 
     | 
    
         
            -
                @object. 
     | 
| 
      
 6 
     | 
    
         
            +
              it 'should have a feed_id' do
         
     | 
| 
      
 7 
     | 
    
         
            +
                @object.feed_id.should_not be_nil
         
     | 
| 
       8 
8 
     | 
    
         
             
              end
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
              it 'should have an author' do
         
     | 
| 
         @@ -25,9 +25,11 @@ describe 'a RubyPicasa document', :shared => true do 
     | 
|
| 
       25 
25 
     | 
    
         
             
                @object.next.should be_nil if @object.link('next').nil?
         
     | 
| 
       26 
26 
     | 
    
         
             
              end
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
              it 'should  
     | 
| 
       29 
     | 
    
         
            -
                @object.session.expects(:get_url).with(@object. 
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
      
 28 
     | 
    
         
            +
              it 'should get the feed' do
         
     | 
| 
      
 29 
     | 
    
         
            +
                @object.session.expects(:get_url).with(@object.feed_id.
         
     | 
| 
      
 30 
     | 
    
         
            +
                                                        gsub(/entry/, 'feed').
         
     | 
| 
      
 31 
     | 
    
         
            +
                                                        gsub(/default/, 'liz'), {})
         
     | 
| 
      
 32 
     | 
    
         
            +
                @object.feed
         
     | 
| 
       31 
33 
     | 
    
         
             
              end
         
     | 
| 
       32 
34 
     | 
    
         | 
| 
       33 
35 
     | 
    
         
             
              it 'should have links' do
         
     | 
| 
         @@ -119,6 +121,11 @@ describe Album do 
     | 
|
| 
       119 
121 
     | 
    
         
             
                @album.session = mock('session')
         
     | 
| 
       120 
122 
     | 
    
         
             
              end
         
     | 
| 
       121 
123 
     | 
    
         | 
| 
      
 124 
     | 
    
         
            +
              it 'should have a numeric id' do
         
     | 
| 
      
 125 
     | 
    
         
            +
                @object.id.should_not be_nil
         
     | 
| 
      
 126 
     | 
    
         
            +
                @object.id.to_s.should match(/\A\d+\Z/)
         
     | 
| 
      
 127 
     | 
    
         
            +
              end
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
       122 
129 
     | 
    
         
             
              it 'should have 1 entry' do
         
     | 
| 
       123 
130 
     | 
    
         
             
                @album.entries.length.should == 1
         
     | 
| 
       124 
131 
     | 
    
         
             
              end
         
     | 
| 
         @@ -137,9 +144,24 @@ describe Album do 
     | 
|
| 
       137 
144 
     | 
    
         
             
                it 'should request photos if needed' do
         
     | 
| 
       138 
145 
     | 
    
         
             
                  @album.entries = []
         
     | 
| 
       139 
146 
     | 
    
         
             
                  new_album = mock('album', :entries => [:photo])
         
     | 
| 
       140 
     | 
    
         
            -
                  @album.session.expects(: 
     | 
| 
      
 147 
     | 
    
         
            +
                  @album.session.expects(:get_url).with(@album.link(/feed/).href, {}).returns(new_album)
         
     | 
| 
       141 
148 
     | 
    
         
             
                  @album.photos.should == [:photo]
         
     | 
| 
       142 
149 
     | 
    
         
             
                end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                it 'should not request photos twice if there are none' do
         
     | 
| 
      
 152 
     | 
    
         
            +
                  @album.entries = []
         
     | 
| 
      
 153 
     | 
    
         
            +
                  new_album = mock('album', :entries => [])
         
     | 
| 
      
 154 
     | 
    
         
            +
                  @album.session.expects(:get_url).with(@album.link(/feed/).href, {}).times(1).returns(new_album)
         
     | 
| 
      
 155 
     | 
    
         
            +
                  @album.photos.should == []
         
     | 
| 
      
 156 
     | 
    
         
            +
                  # note that mocks are set to accept only one get_url request
         
     | 
| 
      
 157 
     | 
    
         
            +
                  @album.photos.should == []
         
     | 
| 
      
 158 
     | 
    
         
            +
                end
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                it 'should not request photos if there is no session' do
         
     | 
| 
      
 161 
     | 
    
         
            +
                  @album.entries = []
         
     | 
| 
      
 162 
     | 
    
         
            +
                  @album.expects(:session).returns(nil)
         
     | 
| 
      
 163 
     | 
    
         
            +
                  @album.photos.should == []
         
     | 
| 
      
 164 
     | 
    
         
            +
                end
         
     | 
| 
       143 
165 
     | 
    
         
             
              end
         
     | 
| 
       144 
166 
     | 
    
         | 
| 
       145 
167 
     | 
    
         
             
              it 'should be public' do
         
     | 
| 
         @@ -175,16 +197,64 @@ describe Album do 
     | 
|
| 
       175 
197 
     | 
    
         
             
                  end
         
     | 
| 
       176 
198 
     | 
    
         
             
                end
         
     | 
| 
       177 
199 
     | 
    
         | 
| 
      
 200 
     | 
    
         
            +
                it 'should have a numeric id' do
         
     | 
| 
      
 201 
     | 
    
         
            +
                  @object.id.should_not be_nil
         
     | 
| 
      
 202 
     | 
    
         
            +
                  @object.id.to_s.should match(/\A\d+\Z/)
         
     | 
| 
      
 203 
     | 
    
         
            +
                end
         
     | 
| 
      
 204 
     | 
    
         
            +
             
     | 
| 
       178 
205 
     | 
    
         
             
                it 'should have a default url' do
         
     | 
| 
       179 
206 
     | 
    
         
             
                  @photo.url.should == 'http://lh5.ggpht.com/liz/SKXR5BoXabI/AAAAAAAAAzs/tJQefyM4mFw/invisible_bike.jpg'
         
     | 
| 
       180 
207 
     | 
    
         
             
                end
         
     | 
| 
       181 
208 
     | 
    
         | 
| 
       182 
209 
     | 
    
         
             
                it 'should have thumbnail urls' do
         
     | 
| 
       183 
     | 
    
         
            -
                  @photo.url(' 
     | 
| 
      
 210 
     | 
    
         
            +
                  @photo.url('72').should == 'http://lh5.ggpht.com/liz/SKXR5BoXabI/AAAAAAAAAzs/tJQefyM4mFw/s72/invisible_bike.jpg'
         
     | 
| 
      
 211 
     | 
    
         
            +
                end
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
      
 213 
     | 
    
         
            +
                it 'should have a default url with options true' do
         
     | 
| 
      
 214 
     | 
    
         
            +
                  @photo.url(nil, true).should == [
         
     | 
| 
      
 215 
     | 
    
         
            +
                    'http://lh5.ggpht.com/liz/SKXR5BoXabI/AAAAAAAAAzs/tJQefyM4mFw/invisible_bike.jpg',
         
     | 
| 
      
 216 
     | 
    
         
            +
                    { :width => 410, :height => 295 }
         
     | 
| 
      
 217 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 218 
     | 
    
         
            +
                end
         
     | 
| 
      
 219 
     | 
    
         
            +
             
     | 
| 
      
 220 
     | 
    
         
            +
                it 'should have a default url with options' do
         
     | 
| 
      
 221 
     | 
    
         
            +
                  @photo.url(nil, :id => 'p').should == [
         
     | 
| 
      
 222 
     | 
    
         
            +
                    'http://lh5.ggpht.com/liz/SKXR5BoXabI/AAAAAAAAAzs/tJQefyM4mFw/invisible_bike.jpg',
         
     | 
| 
      
 223 
     | 
    
         
            +
                    { :width => 410, :height => 295, :id => 'p' }
         
     | 
| 
      
 224 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 225 
     | 
    
         
            +
                end
         
     | 
| 
      
 226 
     | 
    
         
            +
             
     | 
| 
      
 227 
     | 
    
         
            +
                it 'should have a default url with options first' do
         
     | 
| 
      
 228 
     | 
    
         
            +
                  @photo.url(:id => 'p').should == [
         
     | 
| 
      
 229 
     | 
    
         
            +
                    'http://lh5.ggpht.com/liz/SKXR5BoXabI/AAAAAAAAAzs/tJQefyM4mFw/invisible_bike.jpg',
         
     | 
| 
      
 230 
     | 
    
         
            +
                    { :width => 410, :height => 295, :id => 'p' }
         
     | 
| 
      
 231 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 232 
     | 
    
         
            +
                end
         
     | 
| 
      
 233 
     | 
    
         
            +
             
     | 
| 
      
 234 
     | 
    
         
            +
                it 'should have thumbnail urls with options' do
         
     | 
| 
      
 235 
     | 
    
         
            +
                  @photo.url('72', {:class => 'x'}).should == [
         
     | 
| 
      
 236 
     | 
    
         
            +
                    'http://lh5.ggpht.com/liz/SKXR5BoXabI/AAAAAAAAAzs/tJQefyM4mFw/s72/invisible_bike.jpg',
         
     | 
| 
      
 237 
     | 
    
         
            +
                    { :width => 72, :height => 52, :class => 'x' }
         
     | 
| 
      
 238 
     | 
    
         
            +
                  ]
         
     | 
| 
       184 
239 
     | 
    
         
             
                end
         
     | 
| 
       185 
240 
     | 
    
         | 
| 
       186 
241 
     | 
    
         
             
                it 'should have thumbnail info' do
         
     | 
| 
       187 
     | 
    
         
            -
                  @photo.thumbnail(' 
     | 
| 
      
 242 
     | 
    
         
            +
                  @photo.thumbnail('72').width.should == 72
         
     | 
| 
      
 243 
     | 
    
         
            +
                end
         
     | 
| 
      
 244 
     | 
    
         
            +
             
     | 
| 
      
 245 
     | 
    
         
            +
                it 'should retrieve valid thumbnail info' do
         
     | 
| 
      
 246 
     | 
    
         
            +
                  photo = mock('photo')
         
     | 
| 
      
 247 
     | 
    
         
            +
                  thumb = mock('thumb')
         
     | 
| 
      
 248 
     | 
    
         
            +
                  photo.expects(:thumbnails).returns([thumb])
         
     | 
| 
      
 249 
     | 
    
         
            +
                  @photo.session.expects(:get_url).with('http://picasaweb.google.com/data/feed/api/user/liz/albumid/5228155363249705041/photoid/5234820919508560306',
         
     | 
| 
      
 250 
     | 
    
         
            +
                                                  {:thumbsize => '32c'}).returns(photo)
         
     | 
| 
      
 251 
     | 
    
         
            +
                  @photo.thumbnail('32c').should == thumb
         
     | 
| 
      
 252 
     | 
    
         
            +
                end
         
     | 
| 
      
 253 
     | 
    
         
            +
             
     | 
| 
      
 254 
     | 
    
         
            +
                it 'should retrieve valid thumbnail info and handle not found' do
         
     | 
| 
      
 255 
     | 
    
         
            +
                  @photo.session.expects(:get_url).with('http://picasaweb.google.com/data/feed/api/user/liz/albumid/5228155363249705041/photoid/5234820919508560306',
         
     | 
| 
      
 256 
     | 
    
         
            +
                                                  {:thumbsize => '32c'}).returns(nil)
         
     | 
| 
      
 257 
     | 
    
         
            +
                  @photo.thumbnail('32c').should be_nil
         
     | 
| 
       188 
258 
     | 
    
         
             
                end
         
     | 
| 
       189 
259 
     | 
    
         
             
              end
         
     | 
| 
       190 
260 
     | 
    
         
             
            end
         
     | 
| 
         @@ -208,6 +278,10 @@ describe Search do 
     | 
|
| 
       208 
278 
     | 
    
         
             
                @search.entries.first.should be_an_instance_of(Photo)
         
     | 
| 
       209 
279 
     | 
    
         
             
              end
         
     | 
| 
       210 
280 
     | 
    
         | 
| 
      
 281 
     | 
    
         
            +
              it 'should alias entries to photos' do
         
     | 
| 
      
 282 
     | 
    
         
            +
                @search.photos.should == @search.entries
         
     | 
| 
      
 283 
     | 
    
         
            +
              end
         
     | 
| 
      
 284 
     | 
    
         
            +
             
     | 
| 
       211 
285 
     | 
    
         
             
              it 'should request next' do
         
     | 
| 
       212 
286 
     | 
    
         
             
                @search.session.expects(:get_url).with('http://picasaweb.google.com/data/feed/api/all?q=puppy&start-index=3&max-results=1').returns(:result)
         
     | 
| 
       213 
287 
     | 
    
         
             
                @search.next.should == :result
         
     | 
    
        data/spec/ruby_picasa_spec.rb
    CHANGED
    
    | 
         @@ -15,6 +15,18 @@ describe 'Picasa class methods' do 
     | 
|
| 
       15 
15 
     | 
    
         
             
                url.should match(/session=1/)
         
     | 
| 
       16 
16 
     | 
    
         
             
              end
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
      
 18 
     | 
    
         
            +
              describe 'token_in_request?' do
         
     | 
| 
      
 19 
     | 
    
         
            +
                it 'should be nil if no token' do
         
     | 
| 
      
 20 
     | 
    
         
            +
                  request = mock('request', :params => { })
         
     | 
| 
      
 21 
     | 
    
         
            +
                  Picasa.token_in_request?(request).should be_nil
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                it 'should not be nil if there is a token' do
         
     | 
| 
      
 25 
     | 
    
         
            +
                  request = mock('request', :params => { 'token' => 'abc' })
         
     | 
| 
      
 26 
     | 
    
         
            +
                  Picasa.token_in_request?(request).should_not be_nil
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
       18 
30 
     | 
    
         
             
              describe 'token_from_request' do
         
     | 
| 
       19 
31 
     | 
    
         
             
                it 'should pluck the token from the request' do
         
     | 
| 
       20 
32 
     | 
    
         
             
                  request = mock('request', :params => { 'token' => 'abc' })
         
     | 
| 
         @@ -42,10 +54,9 @@ describe 'Picasa class methods' do 
     | 
|
| 
       42 
54 
     | 
    
         
             
                Picasa.is_url?('12323412341').should_not be_true
         
     | 
| 
       43 
55 
     | 
    
         
             
              end
         
     | 
| 
       44 
56 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
              it 'should  
     | 
| 
       46 
     | 
    
         
            -
                 
     | 
| 
       47 
     | 
    
         
            -
                Picasa. 
     | 
| 
       48 
     | 
    
         
            -
                Picasa.is_url?('/else').should be_true
         
     | 
| 
      
 57 
     | 
    
         
            +
              it 'should allow host change' do
         
     | 
| 
      
 58 
     | 
    
         
            +
                Picasa.host = 'abc'
         
     | 
| 
      
 59 
     | 
    
         
            +
                Picasa.host.should == 'abc'
         
     | 
| 
       49 
60 
     | 
    
         
             
              end
         
     | 
| 
       50 
61 
     | 
    
         | 
| 
       51 
62 
     | 
    
         
             
              describe 'path' do
         
     | 
| 
         @@ -67,12 +78,25 @@ describe 'Picasa class methods' do 
     | 
|
| 
       67 
78 
     | 
    
         
             
                    "/data/feed/api/all"
         
     | 
| 
       68 
79 
     | 
    
         
             
                end
         
     | 
| 
       69 
80 
     | 
    
         
             
                [ :max_results, :start_index, :tag, :q, :kind,
         
     | 
| 
       70 
     | 
    
         
            -
                  :access, : 
     | 
| 
      
 81 
     | 
    
         
            +
                  :access, :bbox, :l].each do |arg|
         
     | 
| 
       71 
82 
     | 
    
         
             
                  it "should add #{ arg } to options" do
         
     | 
| 
       72 
83 
     | 
    
         
             
                    Picasa.path(:url => 'url', arg => '!value').should ==
         
     | 
| 
       73 
84 
     | 
    
         
             
                      "url?#{ arg.to_s.dasherize }=%21value"
         
     | 
| 
       74 
85 
     | 
    
         
             
                  end
         
     | 
| 
       75 
86 
     | 
    
         
             
                end
         
     | 
| 
      
 87 
     | 
    
         
            +
                [ :imgmax, :thumbsize ].each do |arg|
         
     | 
| 
      
 88 
     | 
    
         
            +
                  it "should raise PicasaError with invalid #{ arg } option" do
         
     | 
| 
      
 89 
     | 
    
         
            +
                    lambda do
         
     | 
| 
      
 90 
     | 
    
         
            +
                      Picasa.path(:url => 'url', arg => 'invalid')
         
     | 
| 
      
 91 
     | 
    
         
            +
                    end.should raise_error(RubyPicasa::PicasaError)
         
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
                end
         
     | 
| 
      
 94 
     | 
    
         
            +
                [ :imgmax, :thumbsize ].each do |arg|
         
     | 
| 
      
 95 
     | 
    
         
            +
                  it "should add #{ arg } to options" do
         
     | 
| 
      
 96 
     | 
    
         
            +
                    Picasa.path(:url => 'url', arg => '72').should ==
         
     | 
| 
      
 97 
     | 
    
         
            +
                      "url?#{ arg.to_s.dasherize }=72"
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
       76 
100 
     | 
    
         
             
                it 'should ignore unknown options' do
         
     | 
| 
       77 
101 
     | 
    
         
             
                  Picasa.path(:url => 'place', :eggs => 'over_easy').should == 'place'
         
     | 
| 
       78 
102 
     | 
    
         
             
                end
         
     | 
| 
         @@ -151,7 +175,7 @@ describe Picasa do 
     | 
|
| 
       151 
175 
     | 
    
         
             
              end
         
     | 
| 
       152 
176 
     | 
    
         | 
| 
       153 
177 
     | 
    
         
             
              it 'should get the user' do
         
     | 
| 
       154 
     | 
    
         
            -
                @p.expects(:get).with(:user_id =>  
     | 
| 
      
 178 
     | 
    
         
            +
                @p.expects(:get).with(:user_id => nil)
         
     | 
| 
       155 
179 
     | 
    
         
             
                @p.user
         
     | 
| 
       156 
180 
     | 
    
         
             
              end
         
     | 
| 
       157 
181 
     | 
    
         | 
| 
         @@ -177,7 +201,7 @@ describe Picasa do 
     | 
|
| 
       177 
201 
     | 
    
         
             
              end
         
     | 
| 
       178 
202 
     | 
    
         | 
| 
       179 
203 
     | 
    
         
             
              it 'should get recent photos' do
         
     | 
| 
       180 
     | 
    
         
            -
                @p.expects(:get).with(: 
     | 
| 
      
 204 
     | 
    
         
            +
                @p.expects(:get).with(:recent_photos => true, :max_results => 10)
         
     | 
| 
       181 
205 
     | 
    
         
             
                @p.recent_photos :max_results => 10
         
     | 
| 
       182 
206 
     | 
    
         
             
              end
         
     | 
| 
       183 
207 
     | 
    
         | 
| 
         @@ -223,13 +247,13 @@ describe Picasa do 
     | 
|
| 
       223 
247 
     | 
    
         
             
                it 'should call class_from_xml if with_cache yields' do
         
     | 
| 
       224 
248 
     | 
    
         
             
                  @p.expects(:with_cache).with({}).yields(:xml).returns(:result)
         
     | 
| 
       225 
249 
     | 
    
         
             
                  @p.expects(:class_from_xml).with(:xml)
         
     | 
| 
       226 
     | 
    
         
            -
                  @p.get.should == :result
         
     | 
| 
      
 250 
     | 
    
         
            +
                  @p.send(:get).should == :result
         
     | 
| 
       227 
251 
     | 
    
         
             
                end
         
     | 
| 
       228 
252 
     | 
    
         | 
| 
       229 
253 
     | 
    
         
             
                it 'should do nothing if with_cache does not yield' do
         
     | 
| 
       230 
254 
     | 
    
         
             
                  @p.expects(:with_cache).with({}) # doesn't yield
         
     | 
| 
       231 
255 
     | 
    
         
             
                  @p.expects(:class_from_xml).never
         
     | 
| 
       232 
     | 
    
         
            -
                  @p.get.should be_nil
         
     | 
| 
      
 256 
     | 
    
         
            +
                  @p.send(:get).should be_nil
         
     | 
| 
       233 
257 
     | 
    
         
             
                end
         
     | 
| 
       234 
258 
     | 
    
         
             
              end
         
     | 
| 
       235 
259 
     | 
    
         | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification 
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: ruby-picasa
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version 
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0.2. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.2.1
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors: 
         
     | 
| 
       7 
7 
     | 
    
         
             
            - pangloss
         
     | 
| 
         @@ -9,7 +9,7 @@ autorequire: 
     | 
|
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
            date: 2009-03- 
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2009-03-05 00:00:00 -05:00
         
     | 
| 
       13 
13 
     | 
    
         
             
            default_executable: 
         
     | 
| 
       14 
14 
     | 
    
         
             
            dependencies: 
         
     | 
| 
       15 
15 
     | 
    
         
             
            - !ruby/object:Gem::Dependency 
         
     | 
| 
         @@ -30,7 +30,7 @@ dependencies: 
     | 
|
| 
       30 
30 
     | 
    
         
             
                requirements: 
         
     | 
| 
       31 
31 
     | 
    
         
             
                - - ">="
         
     | 
| 
       32 
32 
     | 
    
         
             
                  - !ruby/object:Gem::Version 
         
     | 
| 
       33 
     | 
    
         
            -
                    version: 1. 
     | 
| 
      
 33 
     | 
    
         
            +
                    version: 1.9.0
         
     | 
| 
       34 
34 
     | 
    
         
             
                version: 
         
     | 
| 
       35 
35 
     | 
    
         
             
            description: Provides a super easy to use object layer for authenticating and accessing Picasa through their API.
         
     | 
| 
       36 
36 
     | 
    
         
             
            email: 
         
     |