Skip to content

Instantly share code, notes, and snippets.

@cmoore
Created November 2, 2011 22:38
Show Gist options
  • Save cmoore/1335167 to your computer and use it in GitHub Desktop.
Save cmoore/1335167 to your computer and use it in GitHub Desktop.
class TimelineController < ApplicationController
def index
@messages = Message.order("status_id DESC")
@newest_id = newest_id
end
# Just do a simple update to the timeline for the latest
# greatest messages.
#
# 1. Pull 100 messages
# 2. Convert the 'created_at' fields of the first and last message to an epoch integer.
# 3. Store that pair of integers somewhere.
# 4. Render a view with 200 or so tweets.
#
def update
lxt = Twitter::Client.new
lxt.home_timeline( { :since_id => newest_id,
:include_entities => 1,
:count => 200 } ).map {|x| maker x }
respond_to do |f|
f.html { redirect_to timeline_index_path }
end
end
#
# Update the lower end of the timeline
# so that you can see all of the tweets you missed.
#
#
# So, apparently, you can't get a list of the status_ids
# for a given timeline, so we're going to have to make our
# own little... erm, pager, thingy using the twitter api's
# pagination support.
#
# Taking a page out of Haskell's book, we'll mentally map this
# like we might do types - that is, a "bundle" is 100 tweets
# fetched from the api using the 'page' parameter to 'home_timeline'.
#
# Once a bundle is fetched, it will be marked as correct not by the
# 'status_ids' it returns, but rather the date range between the
# newest and oldest timestamps. We'll turn these timestamps into
# epoch seconds, and mark the amount of time between the two as
# 'complete'. That is, we have the complete set of tweets for
# that duration.
#
# Then, to flesh out the timeline below, we will scan the database
# looking for gaps in time, grab the OLDEST tweet from that range, and call
# 'home_timeline' again using the 'since_id' parameter and actually
# flesh out the timeline from the bottom up. This might be a little weird,
# but, given the tools we have, that seems 1) the most
# straightforward approach from a KISS standpoint, and
# 2) the most efficient given the requests-per-minute limitation
# of the api.
#
#
# No one in their right mind would expose this to the world, of course.
def update_timeline
# first of all, are there more than 100 tweets in the database?
if Message.limit(101).length == 101 then
# ok, we at least have some tweets in the database.
#
# # This was set up in initializers.
# lxt = Twitter::Client.new
# lxt.home_timeline( { :include_entities => 1,
# :max_id => first_id,
# :count => 200
# } ).map {|x| maker x}
end
respond_to do |f|
f.html { redirect_to timeline_index_path }
end
end
#
# I'll have to find a place to put this - definitely not in a handler.
#
# This will scan the database for holes in the durations and flesh out
# the timeline using the approach in the comments for 'update_timeline'
#
# It should also merge durations that it completes so that subsequent
# iterations are simply a single database call before it sees that it
# has no work to do.
#
def worker
end
private
def get_id(a)
Message.order(a).first.status_id
end
def oldest_id
get_id("status_id")
end
def newest_id
get_id("status_id DESC")
end
def maker(x)
if (!Message.find_by_status_id(x[:id]))
Message.new(
:irpt_name => x[:in_reply_to_screen_name],
:sent_date => x[:created_at],
:irpt_status_id => x[:in_reply_to_status_id],
:source => x[:source],
:favorited => x[:favorited],
:status_id => x[:id],
:screen_name => x.user.screen_name,
:followers_count => x.user.follers_count,
:user_image => x.user.profile_image_url,
:status_text => x[:text]).save
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment