require 'ostruct' module MephistoFlickr class RecentFlickrPhotos < Liquid::Block Syntax = /((#{Liquid::TagAttributes}\s?,?\s?)*)as\s(#{Liquid::VariableSegment}+)/ def initialize(markup, tokens) super if markup =~ Syntax @options = parse_options($1) @as = $5 @flickr = Flickr.new(@options[:api_key]) else raise Liquid::SyntaxError.new("Syntax Error in tag 'recentflickrphotos' - Valid syntax: recentflickrphotos [ opt : 'val', opt : 'val' ] as [name]") end end def render(context) # get the photo list from flickr as an xml-simple hash, they come in order of most recently added photos = @flickr.request("people.getPublicPhotos", :user_id => @options[:user_id], :extras => 'tags')['photos']['photo'] # filter out photos without specified tag photos = photos.find_all { |photo| photo['tags'].include? @options[:tag] } if @options[:tag] # have to do one request per photo to get complete description # we also merge the tags from the orginal response as the tags from photos.getInfo is too much information photos = photos.map { |p| @flickr.request("photos.getInfo", :photo_id => p['id'])['photo'].merge('tags' => p['tags']) } # convert that hash into something for liquid photos = photos.map do |photo| base_url = "http://static.flickr.com/#{photo['server']}/#{photo['id']}_#{photo['secret']}" photo.merge( 'medium_thumb' => "#{base_url}_m.jpg", 'link' => "http://www.flickr.com/photos/oddfresh/#{photo['id']}", 'tags' => photo['tags'].split(' '), # for some reason a blank description is an empty hash instead of empty string 'description' => photo['description'].blank? ? '' : photo['description'] ) end # returning result = [] do |result| # photos.each_with_index do |item, index| # context.stack do # context['recentflickrphotos'] = { 'index' => index + 1 } # context[@as] = item # result << render_all(@nodelist, context) # end # end # end result = [] photos.each_with_index do |item, index| context.stack do context['recentflickrphotos'] = { 'index' => index + 1 } context[@as] = item result << render_all(@nodelist, context) end end result end private def parse_options(opt_string) pairs, opts = opt_string.split(','), {} pairs.each do |pair| opt, value = pair.split(':') opt, value = opt.strip, value.strip opts[opt.to_sym] = value end return opts end def evaluate(options, context) evaluated = {} options.each { |opt, value| evaluated[opt] = context[value] } return evaluated end end end