class Flickr::Photos < Flickr::Base attr_accessor :extras def initialize(flickr) @flickr = flickr self.extras ||= { # flickr => flickr_fu :license => :license_id, :date_upload => :date_upload, :datetaken => :taken_at, :ownername => :owner_name, :icon_server => :icon_server, :originalformat => :original_format, :lastupdate => :updated_at, :machine_tags => :machine_tags, :geo => :geo, :tags => :tags, :o_dims => :o_dims, :views => :views, :media => :media, :url_o => :original_url } end # Return a list of photos matching some criteria. Only photos visible to the calling user will be returned. To return private or semi-private photos, # the caller must be authenticated with 'read' permissions (by passing :auth_token), and have permission to view the photos. Unauthenticated calls will only return public photos. # # == Authentication # This method does not require authentication. # # == Options # * user_id (Optional) # The NSID of the user who's photo to search. If this parameter isn't passed then everybody's public photos will be searched. A value of "me" will # search against the calling user's photos for authenticated calls. # * tags (Optional) # A comma-delimited list of tags. Photos with one or more of the tags listed will be returned. # * tag_mode (Optional) # Either 'any' for an OR combination of tags, or 'all' for an AND combination. Defaults to 'any' if not specified. # * text (Optional) # A free text search. Photos who's title, description or tags contain the text will be returned. # * min_upload_date (Optional) # Minimum upload date. Photos with an upload date greater than or equal to this value will be returned. The date should be in the form of a unix timestamp. # * max_upload_date (Optional) # Maximum upload date. Photos with an upload date less than or equal to this value will be returned. The date should be in the form of a unix timestamp. # * min_taken_date (Optional) # Minimum taken date. Photos with an taken date greater than or equal to this value will be returned. The date should be in the form of a mysql datetime. # * max_taken_date (Optional) # Maximum taken date. Photos with an taken date less than or equal to this value will be returned. The date should be in the form of a mysql datetime. # * license (Optional) # The license id for photos (for possible values see the flickr.photos.licenses.getInfo method). Multiple licenses may be comma-separated. # * sort (Optional) # The order in which to sort returned photos. Deafults to date-posted-desc. The possible values are: date-posted-asc, date-posted-desc, date-taken-asc, # date-taken-desc, interestingness-desc, interestingness-asc, and relevance. # * privacy_filter (Optional) # Return photos only matching a certain privacy level. This only applies when making an authenticated call to view photos you own. Valid values are: # 1 public photos # 2 private photos visible to friends # 3 private photos visible to family # 4 private photos visible to friends & family # 5 completely private photos # * bbox (Optional) # A comma-delimited list of 4 values defining the Bounding Box of the area that will be searched. # # The 4 values represent the bottom-left corner of the box and the top-right corner, minimum_longitude, minimum_latitude, maximum_longitude, maximum_latitude. # # Longitude has a range of -180 to 180 , latitude of -90 to 90. Defaults to -180, -90, 180, 90 if not specified. # # Unlike standard photo queries, geo (or bounding box) queries will only return 250 results per page. # # Geo queries require some sort of limiting agent in order to prevent the database from crying. This is basically like the check against "parameterless searches" # for queries without a geo component. # # A tag, for instance, is considered a limiting agent as are user defined min_date_taken and min_date_upload parameters — If no limiting factor is passed we # return only photos added in the last 12 hours (though we may extend the limit in the future). # * accuracy (Optional) # Recorded accuracy level of the location information. Current range is 1-16 : # World level is 1 # Country is ~3 # Region is ~6 # City is ~11 # Street is ~16 # Defaults to maximum value if not specified. # * safe_search (Optional) # Safe search setting: # 1 for safe. # 2 for moderate. # 3 for restricted. # (Please note: Un-authed calls can only see Safe content.) # * content_type (Optional) # Content Type setting: # 1 for photos only. # 2 for screenshots only. # 3 for 'other' only. # 4 for photos and screenshots. # 5 for screenshots and 'other'. # 6 for photos and 'other'. # 7 for photos, screenshots, and 'other' (all). # * machine_tags (Optional) # Aside from passing in a fully formed machine tag, there is a special syntax for searching on specific properties : # Find photos using the 'dc' namespace : "machine_tags" => "dc:" # Find photos with a title in the 'dc' namespace : "machine_tags" => "dc:title=" # Find photos titled "mr. camera" in the 'dc' namespace : "machine_tags" => "dc:title=\"mr. camera\" # Find photos whose value is "mr. camera" : "machine_tags" => "*:*=\"mr. camera\"" # Find photos that have a title, in any namespace : "machine_tags" => "*:title=" # Find photos that have a title, in any namespace, whose value is "mr. camera" : "machine_tags" => "*:title=\"mr. camera\"" # Find photos, in the 'dc' namespace whose value is "mr. camera" : "machine_tags" => "dc:*=\"mr. camera\"" # Multiple machine tags may be queried by passing a comma-separated list. The number of machine tags you can pass in a single query depends on # the tag mode (AND or OR) that you are querying with. "AND" queries are limited to (16) machine tags. "OR" queries are limited to (8). # * machine_tag_mode (Required) # Either 'any' for an OR combination of tags, or 'all' for an AND combination. Defaults to 'any' if not specified. # * group_id (Optional) # The id of a group who's pool to search. If specified, only matching photos posted to the group's pool will be returned. # * woe_id (Optional) # A 32-bit identifier that uniquely represents spatial entities. (not used if bbox argument is present). Experimental. # # Geo queries require some sort of limiting agent in order to prevent the database from crying. This is basically like the check against "parameterless searches" # for queries without a geo component. # # A tag, for instance, is considered a limiting agent as are user defined min_date_taken and min_date_upload parameters &emdash; If no limiting factor is passed # we return only photos added in the last 12 hours (though we may extend the limit in the future). # * place_id (Optional) # A Flickr place id. (not used if bbox argument is present). Experimental. # # Geo queries require some sort of limiting agent in order to prevent the database from crying. This is basically like the check against "parameterless searches" # for queries without a geo component. # # A tag, for instance, is considered a limiting agent as are user defined min_date_taken and min_date_upload parameters &emdash; If no limiting factor is passed # we return only photos added in the last 12 hours (though we may extend the limit in the future). # * per_page (Optional) # Number of photos to return per page. If this argument is omitted, it defaults to 100. The maximum allowed value is 500. # * page (Optional) # The page of results to return. If this argument is omitted, it defaults to 1. # * media (Optional) # The type of media to search for. 'photo', 'video', or 'both' are allowed arguments, with 'both' being the default. # * extras (Optional) # Any extra fields of information you want. The default extra fields are defined # in Flickr::Photos.extras and can be overwritten # def search(options) options[:extras] ||= self.extras.keys.join(',') rsp = @flickr.send_request('flickr.photos.search', options) returning PhotoResponse.new(:page => rsp.photos[:page].to_i, :pages => rsp.photos[:pages].to_i, :per_page => rsp.photos[:perpage].to_i, :total => rsp.photos[:total].to_i, :photos => [], :api => self, :method => 'search', :options => options) do |photos| rsp.photos.photo.each do |photo| attributes = create_attributes(photo) photos << Photo.new(@flickr, attributes) end if rsp.photos.photo end end # Returns a list of the latest public photos uploaded to flickr. # # == Authentication # This method does not require authentication. # # == Options # * per_page (Optional) # Number of photos to return per page. If this argument is omitted, it defaults to 100. The maximum allowed value is 500. # * page (Optional) # The page of results to return. If this argument is omitted, it defaults to 1. # * media (Optional) # The type of media to search for. 'photo', 'video', or 'both' are allowed arguments, with 'both' being the default. # def get_recent(options = {}) options[:extras] ||= self.extras.keys.join(',') rsp = @flickr.send_request('flickr.photos.getRecent', options) returning PhotoResponse.new(:page => rsp.photos[:page].to_i, :pages => rsp.photos[:pages].to_i, :per_page => rsp.photos[:perpage].to_i, :total => rsp.photos[:total].to_i, :photos => [], :api => self, :method => 'flickr.photos.getRecent', :options => options) do |photos| rsp.photos.photo.each do |photo| attributes = create_attributes(photo) photos << Photo.new(@flickr, attributes) end if rsp.photos.photo end end def interesting(options) options[:extras] ||= self.extras.keys.join(',') rsp = @flickr.send_request('flickr.interestingness.getList', options) returning PhotoResponse.new(:page => rsp.photos[:page].to_i, :pages => rsp.photos[:pages].to_i, :per_page => rsp.photos[:perpage].to_i, :total => rsp.photos[:total].to_i, :photos => [], :api => self, :method => 'flickr.interestingness.getList', :options => options) do |photos| rsp.photos.photo.each do |photo| attributes = create_attributes(photo) photos << Photo.new(@flickr, attributes) end if rsp.photos.photo end end def licenses @licenses ||= begin rsp = @flickr.send_request('flickr.photos.licenses.getInfo') returning Hash.new do |licenses| rsp.licenses.license.each do |license| licenses[license[:id].to_i] = Flickr::Photos::License.new(:id => license[:id].to_i, :name => license[:name], :url => license[:url]) end end end end # creates and/or returns the Flickr::Photos::Geo object def geo @geo ||= Flickr::Photos::Geo.new(@flickr) end # Returns a Flickr::Photos::Photo object of the given id. # Raises an error if photo not found def find_by_id(photo_id) rsp = @flickr.send_request('flickr.photos.getInfo', :photo_id => photo_id) Photo.new(@flickr, :id => rsp.photo[:id].to_i, :owner => rsp.photo.owner, :secret => rsp.photo[:secret], :server => rsp.photo[:server].to_i, :farm => rsp.photo[:farm], :title => rsp.photo.title, :is_public => rsp.photo.visibility[:public], :is_friend => rsp.photo.visibility[:is_friend], :is_family => rsp.photo.visibility[:is_family]) end protected def create_attributes(photo) attributes = {} # map all attributes from flickr to `attributes` { # flickr -> flickr_fu :id => :id, :owner => :owner, :secret => :secret, :server => :server, :farm => :farm, :title => :title, :ispublic => :is_public, :isfriend => :is_friend, :isfamily => :is_family }.merge(self.extras).each do |flickr_key, photo_key| attributes[photo_key] = photo[flickr_key] end # and a few conversions attributes.merge({ :license_id => photo[:license].to_i, :uploaded_at => (Time.at(photo[:dateupload].to_i) rescue nil), :taken_at => (Time.parse(photo[:datetaken]) rescue nil), :updated_at => (Time.at(photo[:lastupdate].to_i) rescue nil), :views => photo[:views].to_i }) end end