Aug 022012
 

In this tutorial I Will show how you can post twitter feeds using rails, but not required to be rails as it’s just a simple ruby class. Mostly it’s about how to use the Twitter gem.

It will cache the feeds in memcached. It does not do any database hit for performance.
Only queries twitter once an hour, which you can set default_ttl on the class object.

This is based on a Rails 3.2.7 App with Dalli as memcached backend.

Added to Gemfile:

gem ‘twitter’
gem ‘dalli’

Then Create an initializer file containing your twitter credentials:

1
2
3
4
5
6
7
8
9
 
# config/initializers/twitter.rb
 
Twitter.configure do |config|
  config.consumer_key = ENV["TWITTER_CONSUMER_KEY"]
  config.consumer_secret = ENV["TWITTER_CONSUMER_SECRET"]
  config.oauth_token = ENV["TWITTER_OAUTH_TOKEN_SECRET"]
  config.oauth_token_secret = ENV["TWITTER_OAUTH_TOKEN_SECRET"]
end

This is the model that does all the work. It fetches the timeline then stores in memcached.

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
# app/models/twitter_status.rb
 
 
class TwitterStatus
  attr_accessor :default_ttl
  attr_accessor :user
 
  # if no user is initialized, then use own screen_name from Twitter
  def user
    @user || Twitter.user.screen_name
  end
 
  # refresh time
  def default_ttl
    @default_ttl || 1.hour
  end
 
  def timeline
    unless is_fresh?
      reload
    end
    read_timeline
  end
 
  # Re-fetch timeline from twitter and saves it to the cache again
  def reload
    set_timeline
    set_timestamp
  end
 
 
private
  def cache_key
    "twitter_timeline_#{user.to_s}"
  end
 
  def cache_timestamp
    "twitter_timestamp_#{user.to_s}"
  end
 
  def fetched_at
    Rails.cache.read(cache_key)
  end
 
  def read_timeline
    Rails.cache.read(cache_key)
  end
 
  def set_timestamp
    Rails.cache.write(cache_timestamp, Time.now, timeToLive: default_ttl)
  end
 
  def set_timeline
    Rails.cache.write(cache_key, Twitter.user_timeline(user, include_entities: true))
  rescue
    Rails.logger.info("Error: Cannot connect to twitter or network down")
    Rails.cache.write(cache_key, [])
  end
 
  def is_fresh?
    fetched_at && fetched_at.is_a?(Time) && ((fetched_at + default_ttl) > Time.now)
  end
 
end

How to use it:

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
# Initialize object
> my_timeline = TwitterStatus.new
 => #<TwitterStatus:0x007ff70dc50da8> 
 
# Default Time to store on memcached is 1 hour
> my_timeline.default_ttl
 => 3600 seconds
 
# Change the update interval to 10 minutes.
> my_timeline.default_ttl = 10.minutes
 => 600 seconds
 
# Get Array of recent tweets for Own Timeline
> my_timeline.timeline
 => [#<Twitter::Status:0x007ff70da00468 @attrs={. . . . 
 
# Get latest single tweet on your timeline:
> my_timeline.timeline.first.text
 => "Hello world http://t.co/123456" 
 
 
# Get timeline of another user
> user_timeline = TwitterStatus.new
 => #<TwitterStatus:0x007ff70dc98860>
> user_timeline.user = "fred_on_rails"
 => "fred_on_rails" 
 
# Get fred's last tweet from timeline
1.9.3-p194 :039 > user_timeline.timeline.first.text
 => "Rainwater Crimes: Man gets jail and fines for collecting on his own land http://t.co/Qzn5NWpS" 
 
# Force reload, it refetches from twitter and saves it to the cache again
> user_timeline.reload
 => true

In the views you could display like this:

1
2
3
4
5
6
7
# app/helpers/twitter_helper.rb
 
module TwitterHelper
  def url_for_twit(user,status_id)
    "https://twitter.com/#{user}/status/#{status_id}"
  end
end

In a controller action (example for a logged in user profile page)

1
2
3
  @twitter_status = TwitterStatus.new
  @twitter_status.user = current_user.twitter_screen_name
  @twitter_status.default_ttl = 30.minutes

Erb view:

1
2
3
4
5
6
7
8
9
10
11
<h3>Twitter Updates</h3>
<ul>
  <% @twitter_status.timeline[0..5].each do |status| %>
    <li>
      <%= link_to(status.text, url_for_twit(@twitter_status.user, status.id), target: 'blank') %>
      <span class="twitter-feed-date">
        <%= time_ago_in_words status.created_at %> ago
      </span>
    </li>
  <% end %>
</ul>

Mar 042012
 

# file: postgresql.conf
archive_mode = on
archive_command = ‘pg_compresslog %p – | lzma > /mnt/backup/postgresql/wal/%f’

# file: recovery.conf
restore_command = ‘lzma -d -c /mnt/backup/postgresql/wal/%f | pg_decompresslog – %p’

 Posted by at 6:29 pm
Dec 272011
 

I won’t say anything, just see the numbers:

all tests run 3-4 times:

Small EC2 EBS added 16GB volume $50-80/month
# dd bs=1M count=256 if=/dev/zero of=test oflag=dsync
256+0 records in
256+0 records out
268435456 bytes (268 MB) copied, 11.5874 s, 23.2 MB/s

Small EC2 Root FS EBS
# dd bs=1M count=256 if=/dev/zero of=test oflag=dsync
256+0 records in
256+0 records out
268435456 bytes (268 MB) copied, 32.8698 s, 8.2 MB/s

Linode 1.5GB $54-60/month
# dd bs=1M count=256 if=/dev/zero of=test oflag=dsync
256+0 records in
256+0 records out
268435456 bytes (268 MB) copied, 2.25564 s, 119 MB/s

Tilaa.nl 1GB $30/month
# dd bs=1M count=256 if=/dev/zero of=swapfile oflag=dsync
256+0 records in
256+0 records out
268435456 bytes (268 MB) copied, 4.66885 s, 57.5 MB/s

see dd benchmark information

Ec2 vs Linode vs Tilaa

Ec2 vs Linode vs Tilaa

 Posted by at 5:46 pm
Nov 152011
 

If you need to use the Rails API offline, you can download it here:

rails311.tar.bz2 1.4M Nov 15 08:04

The package contants multiple gems rdoc: railties-3.1.1 rails-3.1.1 actionmailer-3.1.1 activemodel-3.1.1 activeresource-3.1.1 actionpack-3.1.1 activerecord-3.1.1 activesupport-3.1.1 sass-3.1.10 coffee-rails-3.1.1 coffee-script-2.2.0

You can browse online if you wish so : /rails311/index.html

Generated by sdoc

 Posted by at 3:11 pm
Oct 122011
 

This is a ruby on Rails demo app using Address autocomplete with google places API.

I was experimenting with google places and I found it to be quite awesome.

In this app you can search for a geocode address or establishments, move the marker and get the the GPS coordinates, and also get the gps coordinates out the search results.

it’s also possible to restrain the autocomplete results by limiting it to bounds:

autocomplete.setBounds(defaultBounds);

here is the demo app: http://electric-sunrise-8410.heroku.com/
source: https://github.com/fred/google_places_autocomplete

 Posted by at 2:32 am

Switch to our mobile site