Skip to content

Instantly share code, notes, and snippets.

@jdpace
Created April 22, 2011 13:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdpace/936618 to your computer and use it in GitHub Desktop.
Save jdpace/936618 to your computer and use it in GitHub Desktop.
Collector API Example
class AbstractActivityCollector
def run
activities.each do |activity|
persist_activity(activity)
end
end
# To be implemented by subclasses
#
# Returns an array pending activities.
def activities
raise NotImplementedError
end
# To be implemented by subclass
#
# Returns the HTML for displaying the
# activity.
def view_for(activity)
raise NotImplementedError
end
# Define where the activity originates from
def self.source(src = nil)
@source = src unless src.nil?
@source
end
protected
def persist_activity(activity)
# Since we run the collectors frequently, it is very common to encounter
# objects that we have already imported. If this activity is a duplicate
# of an existing object, then we skip importing this activity.
return if activity.duplicate?
unless activity.save
Rails.logger.error("Failed to persist activity from raw data: #{raw_activity}.\nValidation errors: #{activity.errors}")
end
end
end
class TwitterCollector < AbstractActivityCollector
source "Twitter"
attr_reader :username
def initialize(username)
@username = username
end
def activities
@activities ||= fetch_activities
end
def view_for(activity)
activity.data[:text].gsub(/@\w+\b/) do |username|
username_without_at_sign = username.delete('@')
username_url = "http://twitter.com/#{username_without_at_sign}"
"<a href=\"#{username_url}\">#{username}</a>"
end
end
private
def fetch_activities
tweets = Twitter.user_timeline(username)
tweets.map {|tweet| build_activity_from_tweet(tweet) }
end
def build_activity_from_tweet(tweet)
Activity.new do |activity|
activity.collector = self
activity.fingerprint = tweet.id
activity.created_at = tweet.created_at
activity.data = {
:status_id => tweet.id,
:username => tweet.user.screen_name,
:text => tweet.text
}
end
end
end
class Activity
include Mongoid::Document
include Mongoid::Paranoia
field :collector_name, :type => String
field :fingerprint, :type => String
field :data, :type => Hash
field :created_at, :type => DateTime
validates_presence_of :created_at
def collector=(collector)
self.collector_name = collector.class.name
end
def collector
return unless collector_name
collector_name.constantize
end
def source
collector.source
end
def created_on
return nil unless created_at
created_at.to_date
end
def duplicate?
duplicate_activities = self.class.where(:collector_name => self.collector_name, :fingerprint => self.fingerprint)
duplicate_activities.exists? || duplicate_activities.deleted.exists?
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment