bruce / frth

frth

This URL has Read+Write access

frth / front-row.rb
100644 176 lines (146 sloc) 4.647 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
$:.unshift "sinatra/lib"
 
require 'rubygems'
 
require 'digest/md5'
require 'sinatra'
require 'active_support'
require 'json'
require 'open-uri'
 
TWITTER_WAIT_TIMEOUT = 6 unless Object.const_defined?("TWITTER_WAIT_TIMEOUT")
 
before do
  # set UTF-8
  header "Content-Type" => "text/html; charset=utf-8"
 
  # set css body id
  @body_id = "home"
  
  EMAILS = {
    'wbruce' => 'bruce@codefluency.com',
    'damon' => 'scales@pobox.com'
  }
  
  # set up a cache object
  CACHE = MemCache.new 'localhost:11211', :namespace => 'front_row' unless Object.const_defined?("CACHE")
end
 
get "/" do
  @title = "Tweet Row to History"
  erb :index, :views_directory => 'views'
end
 
get "/tweets" do
  tweets = CACHE["tweets"]
  if params["since_id"]
    tweets.reject! {|tweet| tweet["id"] <= params["since_id"].to_i }
  end
  tweets.to_json
end
 
get '/reformat' do
  CACHE["tweets"] = (CACHE['tweets'] || []).map do |tweet|
    format_tweet(tweet)
  end
  redirect '/'
end
 
get "/fetch" do
  if CACHE["last_fetch"] && (Time.now - CACHE["last_fetch"]) < TWITTER_WAIT_TIMEOUT
    age = Time.now - CACHE["last_fetch"]
    puts "Retrieving existing tweets (cached #{age}s ago)"
  else
    previous = CACHE["last_fetch"]
    CACHE["last_fetch"] = Time.now
    begin
      raw_tweets = (get_tweets.map { |tweet| format_tweet(tweet) }).reverse
      puts "Found #{raw_tweets.size} tweets to cache"
      CACHE["tweets"] = raw_tweets
      puts "Cached #{CACHE["tweets"].size} tweet(s)"
    rescue Exception => e
      puts "Exception while retrieving tweets: #{e} #{e.backtrace[0,10].join(' | ')}"
      CACHE["last_fetch"] = previous
    end
  end
  redirect "/tweets"
end
 
def tweeters
  %w|wbruce damon|
end
 
def email_for(name)
end
 
def tweet_terms
ENV['TERMS'] ? ENV['TERMS'].split(/\s+/) : %w|#frth|
end
 
def get_tweets
begin
tweets = tweeters.collect do |tweeter|
get_tweets_for(tweeter)
end.flatten
puts "Sorting #{tweets.size} tweets"
sort_tweets(tweets)
# rescue
# CACHE["tweets"] || {}
end
end
 
def format_tweet(tweet)
tweet['formatted'] = gravatar_for_tweet(tweet) << date_link(tweet) << format_content(tweet['text'])
tweet
end
 
def date_link(tweet)
%(<p class='date'>%s</p>) % tweet['created_at']
end
 
def format_content(text)
result = text.dup
# Make sure we have them small-to-big
urls = URI.extract(text).uniq.sort
urls.each do |raw_url|
begin
case URI.parse(raw_url).host
when 'snaptweet.com'
result.gsub!(raw_url, %(<div class='snaptweet'><a href='#{raw_url}'><img src='#{raw_url}.thumb' alt=''/></a></div>))
else
result.gsub!(raw_url, %(<a href='#{raw_url}'>#{raw_url}</a>))
end
rescue => boom
end
end
result.gsub!('#frth', '')
result.gsub!(/(^|\s)@([[:alnum:]_]+)/) do
"#{$1}<a href='http://twitter.com/#{$2}' title='See twitter profile for #{$2}'>@#{$2}</a>"
end
'<p>%s</p>' % result
end
 
def sort_tweets(tweets)
tweets.sort { |a, b| Integer(a["id"]) <=> Integer(b["id"]) }
end
 
def get_tweets_for(user)
json = json_for_url(CGI.escape("from:#{user} #{tweet_terms.join(" ")}"))
puts "Got result: #{json}"
JSON.parse(json)["results"].map do |tweet|
tweet["formatted"] = format_content(tweet["text"])
tweet
end
end
 
def json_for_url(terms)
puts "Contacting: #{url % [terms, 0]}"
open(url % [terms, 0]).read
end
 
def url; "http://search.twitter.com/search.json?q=%s&since_id=%s"; end
 
def gravatar_for_tweet(tweet)
if (email = EMAILS[tweet['from_user']])
%(<a class='gravatar' href='http://twitter.com/#{tweet['from_user']}/statuses/#{tweet['id']}'><img src='#{gravatar_url(email, :size => '80px')}' alt='#{tweet['from']}'/></a>)
else
puts "Could not find email for #{tweet['from_user']}"
''
end
end
 
def gravatar_url(email, gravatar_options={})
 
# Default highest rating.
# Rating can be one of G, PG, R X.
# If set to nil, the Gravatar default of X will be used.
gravatar_options[:rating] ||= nil
 
# Default size of the image.
# If set to nil, the Gravatar default size of 80px will be used.
gravatar_options[:size] ||= '40px'
 
# Default image url to be used when no gravatar is found
# or when an image exceeds the rating parameter.
gravatar_options[:default] ||= nil
 
  # Build the Gravatar url.
  grav_url = 'http://www.gravatar.com/avatar.php?'
  grav_url << "gravatar_id=#{Digest::MD5.new.update(email)}"
  grav_url << "&rating=#{gravatar_options[:rating]}" if gravatar_options[:rating]
  grav_url << "&size=#{gravatar_options[:size]}" if gravatar_options[:size]
  grav_url << "&default=#{gravatar_options[:default]}" if gravatar_options[:default]
  grav_url
end