Created
April 22, 2011 13:08
-
-
Save jdpace/936618 to your computer and use it in GitHub Desktop.
Collector API Example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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