# == Schema Information # # Table name: services # # id :integer(4) not null, primary key # uri :string(2083) default("") # name :string(1000) default("") # api_uri :string(2083) default("") # uri_template :string(2083) default("") # icon :string(2083) default("rss.gif") # sort :integer(4) # requires_password :boolean(1) # use_for :string(255) # service_category_id :integer(4) # active :boolean(1) default(TRUE) # prompt :string(255) # template :string(255) # class Service < ActiveRecord::Base belongs_to :service_category named_scope :sorted_id, :order => "id ASC" named_scope :sorted, :order => "sort ASC" named_scope :identity_services, :conditions => ['use_for = ?', 'identity'] named_scope :tag_services, :conditions => ['use_for = ?', 'tags'] named_scope :photo_services, :conditions => ["service_categories.id = services.service_category_id AND service_categories.name = 'Photos'"], :include => ['service_category'] # Indicates whether feed is primarily a photo feed ie from flick, picasa, etc def photo? Service.get_photo_services.include?(self) end # Indicates whether feed is primarily a video feed ie from youtube, etc def video? Service.get_video_services.include?(self) end # Indicates whether feed is primarily a bookmark feed ie from delicious, etc def bookmark? Service.get_bookmark_services.include?(self) end # Indicates whether feed is primarily a music feed def music? Service.get_music_services.include?(self) end def general? Service.get_general_services.include?(self) end def human_uri(tag) generate_tag_template_uri(tag, self.uri_template) end # Generate a uri for the current service def generate_tag_uri(tag) generate_tag_template_uri(tag, self.uri_data_template) end def generate_tag_template_uri(tag, uri_template) if self.name == 'Flickr' uri_template.sub("{tag}", tag.gsub('+',',')) # flickr wants a comma deliminated list of tags else uri_template.sub("{tag}", tag) end end def generate_uris(username = '', password = '', uri = '') if self.name == 'Facebook' # Facebook can't just use feeds like everyone else. params = {} pairs = uri.split('?')[1].split('&') pairs.each do |pair| p = pair.split('=') params[p[0].to_sym] = p[1] end uris = [] uris << OpenStruct.new(:url => "http://www.facebook.com/feeds/notifications.php?id=#{params[:id]}&viewer=#{params[:id]}&key=#{params[:key]}&format=rss20", :title => I18n.t('muck.raker.facebook_notifications')) uris << OpenStruct.new(:url => "http://www.facebook.com/feeds/share_posts.php?id=#{params[:id]}&viewer=#{params[:id]}&key=#{params[:key]}&format=rss20", :title => I18n.t('muck.raker.facebook_shares')) uris << OpenStruct.new(:url => "http://www.facebook.com/feeds/notes.php?id=#{params[:id]}&viewer=#{params[:id]}&key=#{params[:key]}&format=rss20", :title => I18n.t('muck.raker.facebook_notes')) uris elsif self.name == 'Amazon' return [] if username.blank? # Have to build and sign Amazon wishlist rss feeds am = AmazonRequest.new(GlobalConfig.amazon_access_key_id, GlobalConfig.amazon_secret_access_key, GlobalConfig.amazon_associate_tag) results = am.get_amazon_feeds(username) # username needs to be the user's Amazon email results.collect { |result| OpenStruct.new(:url => result, :title => 'Amazon Wishlist') } elsif !self.uri_data_template.blank? && !username.blank? return [] if username.blank? uri = self.uri_data_template.sub("{username}", username) Feed.discover_feeds(uri) elsif !uri.blank? return [] if uri.blank? Feed.discover_feeds(uri) end end # Generates uris for 'tag' using all services where 'use_for' is 'tags' def self.generate_tag_uris(terms, selected_service_ids = nil) split_terms(terms).collect { |tag| get_services(selected_service_ids).collect { |service| service.generate_tag_uri(tag) } }.flatten! end # creates a feed for a service with a username and optional password def self.create_feeds_for_service(service, uri, username, password, contributor) uris = service.generate_uris(username, password, uri) uris.collect{ |u| Feed.find_or_create(u.url, u.title, username, password, service.id, contributor) } if uris end def self.build_photo_feeds(terms, user, service_ids = nil) if service_ids.nil? service_ids = get_photo_services.map(&:id) else service_ids = make_int_array(service_ids) & get_photo_services.map(&:id) end build_feeds(terms, user, service_ids) end def self.build_video_feeds(terms, user, service_ids = nil) if service_ids.nil? service_ids = get_video_services.map(&:id) else service_ids = make_int_array(service_ids) & get_video_services.map(&:id) end build_feeds(terms, user, service_ids) end def self.build_bookmark_feeds(terms, user, service_ids = nil) if service_ids.nil? service_ids = get_bookmark_services.map(&:id) else service_ids = make_int_array(service_ids) & get_bookmark_services.map(&:id) end build_feeds(terms, user, service_ids) end def self.build_music_feeds(terms, user, service_ids = nil) if service_ids.nil? service_ids = get_music_services.map(&:id) else service_ids = make_int_array(service_ids) & get_music_services.map(&:id) end build_feeds(terms, user, service_ids) end def self.build_general_feeds(terms, user, service_ids = nil) if service_ids.nil? service_ids = get_general_services.map(&:id) else service_ids = make_int_array(service_ids) & get_general_services.map(&:id) end build_feeds(terms, user, service_ids) end def self.get_photo_services @photo_services ||= get_services.find_all{|service| service.service_category.name == 'Photos' } end def self.get_video_services @video_services ||= get_services.find_all{|service| service.service_category.name == 'Videos' } end def self.get_bookmark_services @bookmark_services ||= get_services.find_all{|service| service.service_category.name == 'Bookmarks' } end def self.get_music_services @music_services ||= get_services.find_all{|service| service.service_category.name == 'Music' } end def self.get_general_services @general_services ||= get_services.find_all{|service| !['Photos', 'Videos', 'Bookmarks', 'Music'].include?(service.service_category.name) } end # Builds feeds (does not save them to the db) for the given term def self.build_feeds(terms, user, selected_service_ids = nil) split_terms(terms).collect { |tag| get_services(selected_service_ids).collect { |service| Feed.new(:uri => service.generate_tag_uri(tag), :display_uri => service.human_uri(tag), :title => I18n.t('muck.raker.service_feed_name', :term => CGI.unescape(tag).humanize, :service => service.name), :service_id => service.id, :contributor_id => user) } }.flatten! end # Builds feeds (does not save them to the db) for the given term. Note that this # method calls each feed created and so it can take a while to run. def self.build_live_feeds(terms, user, selected_service_ids = nil) uris = generate_tag_uris(terms, selected_service_ids) feed_uris = uris.collect { |uri| Feed.discover_feeds(uri)} feed_uris.collect { |feed| Feed.new(:uri => feed.url, :title => feed.title, :service_id => service.id, :contributor_id => user) } end # Create feeds for the given terms def self.create_feeds(terms, user = nil, selected_service_ids = nil) split_terms(terms).collect { |tag| get_services(selected_service_ids).collect { |service| Feed.find_or_create(service.generate_tag_uri(tag), tag, '', '', service.id, user, service.human_uri(tag)) } }.flatten! end def self.split_terms(terms) return '' if terms.blank? terms = terms.split(',') unless terms.is_a?(Array) terms.collect { |tag| CGI.escape(tag.strip) } end def self.get_services(selected_service_ids = nil) if selected_service_ids selected_service_ids.collect! { |service_id| service_id.to_i } # make sure the ids are ints Service.tag_services.find_all { |service| selected_service_ids.include?(service.id) } else @services ||= Service.tag_services end end # attempts to find a service using a uri # uri: Uri to search for. This method will attempt to all services for any part of the provided uri. # refresh_services: Forces a refresh of the services. By default the services are cached for the duration of the request. def self.find_service_by_uri(uri, refresh_services = false) if refresh_services @services = Service.all else @services ||= Service.all end service = @services.detect { |service| service.uri && service.uri.length > 0 && (uri.include?(service.uri) || service.uri.include?(uri)) } service ||= default_service service end def self.make_int_array(a) a.collect{|i| i.to_i} end def self.default_service Service.find_by_name('rss') # this will return the default rss service end end