columbus 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 John Nunemaker
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,18 @@
1
+ = columbus
2
+
3
+ Autodiscovers feeds from urls.
4
+
5
+ = examples
6
+
7
+ See examples directory. Short example below.
8
+
9
+ require 'pp'
10
+ pp Columbus.new('http://www.railstips.org').primary
11
+
12
+ #<struct Columbus::Feed
13
+ url="http://feeds2.feedburner.com/railstips",
14
+ title="Railstips Articles">
15
+
16
+ == Copyright
17
+
18
+ Copyright (c) 2009 John Nunemaker. See LICENSE for details.
@@ -0,0 +1,4 @@
1
+ ---
2
+ :minor: 1
3
+ :patch: 2
4
+ :major: 0
@@ -0,0 +1,47 @@
1
+ require 'logger'
2
+ require 'net/http'
3
+ require 'uri'
4
+ require 'rubygems'
5
+ require 'hpricot'
6
+
7
+ require File.dirname(__FILE__) + '/columbus/feed'
8
+ require File.dirname(__FILE__) + '/columbus/link'
9
+ require File.dirname(__FILE__) + '/columbus/redirect_follower'
10
+
11
+ class Columbus
12
+ attr_reader :url
13
+
14
+ def initialize(url)
15
+ @url = url
16
+ end
17
+
18
+ def primary
19
+ @primary ||= begin
20
+ response = RedirectFollower.new(url).resolve
21
+ @url = response.url
22
+ if hpricot_link = parse_links(response.body)[0]
23
+ link_to_feed(hpricot_link)
24
+ end
25
+ end
26
+ end
27
+
28
+ def all
29
+ @all ||= begin
30
+ response = RedirectFollower.new(url).resolve
31
+ @url = response.url
32
+ parse_links(response.body).map { |hpricot_link| link_to_feed(hpricot_link) }
33
+ end
34
+ end
35
+
36
+ private
37
+ def link_to_feed(element)
38
+ link = Link.new(url, element.attributes['href'], element.attributes['title'])
39
+ Feed.new(link.absolute_url, link.clean_title)
40
+ end
41
+
42
+ def parse_links(html)
43
+ Hpricot(html).search('link').select do |link|
44
+ link.attributes['type'] =~ /application\/(rss|atom)\+xml/i
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,17 @@
1
+ class Columbus
2
+ class Feed < Struct.new(:url, :title)
3
+ attr_accessor :body
4
+
5
+ def initialize(*args)
6
+ super(*args)
7
+ determine_feed_endpoint
8
+ end
9
+
10
+ def determine_feed_endpoint
11
+ response = RedirectFollower.new(url).resolve
12
+ self.url = response.url
13
+ self.body = response.body
14
+ self
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ class Columbus
2
+ class Link < Struct.new(:url, :href, :title)
3
+ def clean_title
4
+ title.nil? ? nil : title.strip
5
+ end
6
+
7
+ def absolute_url
8
+ if relative?
9
+ "#{url}#{href}"
10
+ else
11
+ "#{href}"
12
+ end
13
+ end
14
+
15
+ def relative?
16
+ href =~ /^\//
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,46 @@
1
+ class Columbus
2
+ class RedirectFollower
3
+ class TooManyRedirects < StandardError; end
4
+
5
+ attr_accessor :url, :body, :redirect_limit, :response
6
+
7
+ def initialize(url, options={})
8
+ @url = url
9
+ @redirect_limit = options.delete(:limit) || 5
10
+ logger.level = options.delete(:level) || Logger::WARN
11
+ end
12
+
13
+ def logger
14
+ @logger ||= Logger.new(STDOUT)
15
+ end
16
+
17
+ def resolve
18
+ raise TooManyRedirects if redirect_limit < 0
19
+
20
+ self.response = Net::HTTP.get_response(URI.parse(url))
21
+
22
+ logger.info "redirect limit: #{redirect_limit}"
23
+ logger.info "response code: #{response.code}"
24
+ logger.debug "response body: #{response.body}"
25
+
26
+ if response.kind_of?(Net::HTTPRedirection)
27
+ self.url = redirect_url
28
+ self.redirect_limit -= 1
29
+
30
+ logger.info "redirect found, headed to #{url}"
31
+ resolve
32
+ end
33
+
34
+ self.body = response.body
35
+ self
36
+ end
37
+
38
+ def redirect_url
39
+ if response['location'].nil?
40
+ response.body.match(/<a href=\"([^>]+)\">/i)[1]
41
+ else
42
+ response['location']
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,36 @@
1
+ require 'test_helper'
2
+
3
+ class ColumbusTest < Test::Unit::TestCase
4
+ context "Initialization" do
5
+ should "accept a url" do
6
+ Columbus.new('http://foobar.com').url.should == 'http://foobar.com'
7
+ end
8
+ end
9
+
10
+ should "be able to get primary feed" do
11
+ FakeWeb.register_uri(:get, "http://railstips.org/", :string => fixture_file('railstips.html'))
12
+ FakeWeb.register_uri(:get, "http://feeds.feedburner.com/railstips", :string => fixture_file('railstips_feedburner.html'))
13
+ expected = Columbus::Feed.new('http://feeds.feedburner.com/railstips', 'Railstips Articles')
14
+ Columbus.new('http://railstips.org').primary.should == expected
15
+ end
16
+
17
+ should "be able to get all feeds" do
18
+ FakeWeb.register_uri(:get, "http://railstips.org/", :string => fixture_file('railstips.html'))
19
+ FakeWeb.register_uri(:get, "http://feeds.feedburner.com/railstips", :string => fixture_file('railstips_feedburner.html'))
20
+ FakeWeb.register_uri(:get, "http://feeds.feedburner.com/railsquicktips", :string => fixture_file('railsquicktips.html'))
21
+ Columbus.new('http://railstips.org').all.should == [
22
+ Columbus::Feed.new('http://feeds.feedburner.com/railstips', 'Railstips Articles'),
23
+ Columbus::Feed.new('http://feeds.feedburner.com/railsquicktips', 'Rails Quick Tips (links)')
24
+ ]
25
+ end
26
+
27
+ should "follow redirects" do
28
+ FakeWeb.register_uri(:get, "http://railstips.org/", :string => fixture_file('railstips.html'))
29
+ FakeWeb.register_uri(:get, "http://feeds.feedburner.com/railstips", :response => fixture_file('railstips_redirect'))
30
+ FakeWeb.register_uri(:get, "http://feeds2.feedburner.com/railstips", :string => fixture_file('railstips_feedburner.html'))
31
+ primary = Columbus.new('http://railstips.org').primary
32
+ primary.url.should == 'http://feeds2.feedburner.com/railstips'
33
+ primary.title.should == 'Railstips Articles'
34
+ end
35
+
36
+ end
@@ -0,0 +1,23 @@
1
+ require 'test_helper'
2
+
3
+ class FeedTest < Test::Unit::TestCase
4
+ context "Initialization" do
5
+ setup do
6
+ @body = fixture_file('railstips.html')
7
+ FakeWeb.register_uri(:get, "http://feeds.feedburner.com/railstips", :string => @body)
8
+ @feed = Columbus::Feed.new('http://feeds.feedburner.com/railstips', 'Railstips')
9
+ end
10
+
11
+ should "accept a url" do
12
+ @feed.url.should == 'http://feeds.feedburner.com/railstips'
13
+ end
14
+
15
+ should "accept a title" do
16
+ @feed.title = 'Railstips'
17
+ end
18
+
19
+ should "set body to feed endpoint response body" do
20
+ @feed.body.should == @body
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,295 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss1full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds2.feedburner.com/~d/styles/itemcontent.css"?><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
3
+ <channel rdf:about="http://feeds.delicious.com">
4
+ <title>Rails Quick Tips</title>
5
+ <link>http://delicious.com/jnunemaker/railstips</link>
6
+ <description>These are quick tips for anyone interested in Ruby on Rails.</description>
7
+ <items>
8
+ <rdf:Seq>
9
+ <rdf:li rdf:resource="http://github.com/jchupp/is_paranoid/tree/master" />
10
+ <rdf:li rdf:resource="http://voloko.ru/sdoc/rails/" />
11
+ <rdf:li rdf:resource="http://garrettdimon.com/archives/2009/3/11/independent_software_development/" />
12
+ <rdf:li rdf:resource="http://wonderfullyflawed.com/2009/02/17/rails-forms-microformat/" />
13
+ <rdf:li rdf:resource="http://github.com/benschwarz/passenger-stack/tree/master" />
14
+ <rdf:li rdf:resource="http://nextupdate.com/blog/archives/2009/03/implementing-search/" />
15
+ <rdf:li rdf:resource="http://hackd.thrivesmarthq.com/how-to-setup-a-linux-server-for-ruby-on-rails-with-github-and-phusion-passenger" />
16
+ <rdf:li rdf:resource="http://github.com/Fingertips/nap/tree/master" />
17
+ <rdf:li rdf:resource="http://onrails.org/articles/2009/03/06/integrating-ftp-with-rails" />
18
+ <rdf:li rdf:resource="http://opensource.plurk.com/LightCloud" />
19
+ <rdf:li rdf:resource="http://buddingrubyist.com/2009/02/14/how-to-speed-up-gem-installs-10x/" />
20
+ <rdf:li rdf:resource="http://push.cx/2008/deploying-crontab-with-your-rails-app" />
21
+ <rdf:li rdf:resource="http://www.coffeepowered.net/2009/02/15/graceful-degredation-using-gravatar-as-a-fallback-avatar-with-paperclip/" />
22
+ <rdf:li rdf:resource="http://code.google.com/apis/gdata/articles/gdata_on_rails.html" />
23
+ <rdf:li rdf:resource="http://getsprockets.org/" />
24
+ </rdf:Seq>
25
+ </items>
26
+ <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds2.feedburner.com/railsquicktips" type="application/rss+xml" /></channel>
27
+ <item rdf:about="http://github.com/jchupp/is_paranoid/tree/master">
28
+ <title>jchupp's is_paranoid</title>
29
+ <dc:date>2009-03-24T14:44:41Z</dc:date>
30
+ <link>http://feedproxy.google.com/~r/railsquicktips/~3/lQKkLtTYCgE/master</link>
31
+ <dc:creator>jnunemaker</dc:creator>
32
+ <description>&amp;quot;ActiveRecord 2.3 compatible gem &amp;#039;allowing you to hide and restore records without actually deleting them.&amp;#039; Yes, like acts_as_paranoid, only with less code and less complexity.&amp;quot; Basically a version of acts as paranoid that takes advantage of new rails 2.3 features.&lt;div class="feedflare"&gt;
33
+ &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=lQKkLtTYCgE:8hjap7hTqEM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=lQKkLtTYCgE:8hjap7hTqEM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
34
+ &lt;/div&gt;&lt;img src="http://feeds2.feedburner.com/~r/railsquicktips/~4/lQKkLtTYCgE" height="1" width="1"/&gt;</description>
35
+ <dc:subject>rails railstips plugins</dc:subject>
36
+ <taxo:topics>
37
+ <rdf:Bag>
38
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/rails" />
39
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/railstips" />
40
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/plugins" />
41
+ </rdf:Bag>
42
+ </taxo:topics>
43
+ <feedburner:origLink>http://github.com/jchupp/is_paranoid/tree/master</feedburner:origLink></item>
44
+ <item rdf:about="http://voloko.ru/sdoc/rails/">
45
+ <title>Rails Searchable API Doc</title>
46
+ <dc:date>2009-03-17T20:48:46Z</dc:date>
47
+ <link>http://feedproxy.google.com/~r/railsquicktips/~3/08a9HcDjuN4/</link>
48
+ <dc:creator>jnunemaker</dc:creator>
49
+ <description>Looks like a cool downloadable version of the rails rdoc. Handy.&lt;div class="feedflare"&gt;
50
+ &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=08a9HcDjuN4:WS2WriGDDkY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=08a9HcDjuN4:WS2WriGDDkY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
51
+ &lt;/div&gt;&lt;img src="http://feeds2.feedburner.com/~r/railsquicktips/~4/08a9HcDjuN4" height="1" width="1"/&gt;</description>
52
+ <dc:subject>railstips documentation</dc:subject>
53
+ <taxo:topics>
54
+ <rdf:Bag>
55
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/railstips" />
56
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/documentation" />
57
+ </rdf:Bag>
58
+ </taxo:topics>
59
+ <feedburner:origLink>http://voloko.ru/sdoc/rails/</feedburner:origLink></item>
60
+ <item rdf:about="http://garrettdimon.com/archives/2009/3/11/independent_software_development/">
61
+ <title>Independent Software Development</title>
62
+ <dc:date>2009-03-12T20:28:25Z</dc:date>
63
+ <link>http://feedproxy.google.com/~r/railsquicktips/~3/PlGLlfD9onQ/</link>
64
+ <dc:creator>jnunemaker</dc:creator>
65
+ <description>&amp;quot;It was a little over a year ago that I set out to try and turn a few mockups into a full-fledged revenue-generating piece of software. For the most part, it&amp;#039;s been a pretty smooth ride, but there have definitely been some lessons learned.&amp;quot;
66
+
67
+ I totally agree with almost all of Garrett&amp;#039;s sentiments, though I often work from cafes and the like. Great read. I&amp;#039;m always impressed with Garrett&amp;#039;s writing.&lt;div class="feedflare"&gt;
68
+ &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=PlGLlfD9onQ:Kf6CoVnu9UE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=PlGLlfD9onQ:Kf6CoVnu9UE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
69
+ &lt;/div&gt;&lt;img src="http://feeds2.feedburner.com/~r/railsquicktips/~4/PlGLlfD9onQ" height="1" width="1"/&gt;</description>
70
+ <dc:subject>programming freelancing business railstips</dc:subject>
71
+ <taxo:topics>
72
+ <rdf:Bag>
73
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/programming" />
74
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/freelancing" />
75
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/business" />
76
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/railstips" />
77
+ </rdf:Bag>
78
+ </taxo:topics>
79
+ <feedburner:origLink>http://garrettdimon.com/archives/2009/3/11/independent_software_development/</feedburner:origLink></item>
80
+ <item rdf:about="http://wonderfullyflawed.com/2009/02/17/rails-forms-microformat/">
81
+ <title>Rails Forms microformat</title>
82
+ <dc:date>2009-03-12T19:41:34Z</dc:date>
83
+ <link>http://feedproxy.google.com/~r/railsquicktips/~3/crZyLixU-dA/</link>
84
+ <dc:creator>jnunemaker</dc:creator>
85
+ <description>One of the most comprehensive articles on rails forms. Includes the newly added nested attributes stuff.&lt;div class="feedflare"&gt;
86
+ &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=crZyLixU-dA:jEU-aMMZvu8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=crZyLixU-dA:jEU-aMMZvu8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
87
+ &lt;/div&gt;&lt;img src="http://feeds2.feedburner.com/~r/railsquicktips/~4/crZyLixU-dA" height="1" width="1"/&gt;</description>
88
+ <dc:subject>rails forms railstips</dc:subject>
89
+ <taxo:topics>
90
+ <rdf:Bag>
91
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/rails" />
92
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/forms" />
93
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/railstips" />
94
+ </rdf:Bag>
95
+ </taxo:topics>
96
+ <feedburner:origLink>http://wonderfullyflawed.com/2009/02/17/rails-forms-microformat/</feedburner:origLink></item>
97
+ <item rdf:about="http://github.com/benschwarz/passenger-stack/tree/master">
98
+ <title>benschwarz's passenger-stack</title>
99
+ <dc:date>2009-03-12T19:33:19Z</dc:date>
100
+ <link>http://feedproxy.google.com/~r/railsquicktips/~3/OcSB78dmmng/master</link>
101
+ <dc:creator>jnunemaker</dc:creator>
102
+ <description>&amp;quot;Sprinkles for Apache, Passenger, Memcached, Git, Mysql or Postgres.&amp;quot; Looks like a super quick way to install a full rails stack. Looking forward to trying this out.&lt;div class="feedflare"&gt;
103
+ &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=OcSB78dmmng:f1iqlW8ZAZc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=OcSB78dmmng:f1iqlW8ZAZc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
104
+ &lt;/div&gt;&lt;img src="http://feeds2.feedburner.com/~r/railsquicktips/~4/OcSB78dmmng" height="1" width="1"/&gt;</description>
105
+ <dc:subject>rails sprinkle apache railstips deployment</dc:subject>
106
+ <taxo:topics>
107
+ <rdf:Bag>
108
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/rails" />
109
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/sprinkle" />
110
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/apache" />
111
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/railstips" />
112
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/deployment" />
113
+ </rdf:Bag>
114
+ </taxo:topics>
115
+ <feedburner:origLink>http://github.com/benschwarz/passenger-stack/tree/master</feedburner:origLink></item>
116
+ <item rdf:about="http://nextupdate.com/blog/archives/2009/03/implementing-search/">
117
+ <title>Implementing Search</title>
118
+ <dc:date>2009-03-12T06:48:11Z</dc:date>
119
+ <link>http://feedproxy.google.com/~r/railsquicktips/~3/z25JVsvibAo/</link>
120
+ <dc:creator>jnunemaker</dc:creator>
121
+ <description>Great post by Garrett Dimon on how he implemented search for Sifter using Sphynx. Very detailed, including illustrations.&lt;div class="feedflare"&gt;
122
+ &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=z25JVsvibAo:5Yk7opiDS4o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=z25JVsvibAo:5Yk7opiDS4o:7Q72WNTAKBA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
123
+ &lt;/div&gt;&lt;img src="http://feeds2.feedburner.com/~r/railsquicktips/~4/z25JVsvibAo" height="1" width="1"/&gt;</description>
124
+ <dc:subject>railstips search sphynx</dc:subject>
125
+ <taxo:topics>
126
+ <rdf:Bag>
127
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/railstips" />
128
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/search" />
129
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/sphynx" />
130
+ </rdf:Bag>
131
+ </taxo:topics>
132
+ <feedburner:origLink>http://nextupdate.com/blog/archives/2009/03/implementing-search/</feedburner:origLink></item>
133
+ <item rdf:about="http://hackd.thrivesmarthq.com/how-to-setup-a-linux-server-for-ruby-on-rails-with-github-and-phusion-passenger">
134
+ <title>How-To Setup a Linux Server for Ruby on Rails - with Phusion Passenger and GitHub</title>
135
+ <dc:date>2009-03-12T06:42:11Z</dc:date>
136
+ <link>http://feedproxy.google.com/~r/railsquicktips/~3/5g3pjEJaDa8/how-to-setup-a-linux-server-for-ruby-on-rails-with-github-and-phusion-passenger</link>
137
+ <dc:creator>jnunemaker</dc:creator>
138
+ <description>&amp;quot;This document serves as a comprehensive how-to to setup and deploy your typical Ruby on Rails application on a blank new *nix (Unix, Linux, etc.) server.&amp;quot;&lt;div class="feedflare"&gt;
139
+ &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=5g3pjEJaDa8:1vd7NOzvhCY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=5g3pjEJaDa8:1vd7NOzvhCY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
140
+ &lt;/div&gt;&lt;img src="http://feeds2.feedburner.com/~r/railsquicktips/~4/5g3pjEJaDa8" height="1" width="1"/&gt;</description>
141
+ <dc:subject>github rails unix deployment railstips</dc:subject>
142
+ <taxo:topics>
143
+ <rdf:Bag>
144
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/github" />
145
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/rails" />
146
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/unix" />
147
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/deployment" />
148
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/railstips" />
149
+ </rdf:Bag>
150
+ </taxo:topics>
151
+ <feedburner:origLink>http://hackd.thrivesmarthq.com/how-to-setup-a-linux-server-for-ruby-on-rails-with-github-and-phusion-passenger</feedburner:origLink></item>
152
+ <item rdf:about="http://github.com/Fingertips/nap/tree/master">
153
+ <title>Fingertips's nap</title>
154
+ <dc:date>2009-03-12T06:41:09Z</dc:date>
155
+ <link>http://feedproxy.google.com/~r/railsquicktips/~3/Ght4-4SIUZM/master</link>
156
+ <dc:creator>jnunemaker</dc:creator>
157
+ <description>&amp;quot;Nap is a really simple REST API.&amp;quot; Basically a sane API for net/http. Like HTTParty, but missing the converting of xml and json responses into ruby hashes.&lt;div class="feedflare"&gt;
158
+ &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=Ght4-4SIUZM:mdqRwxkEk-U:yIl2AUoC8zA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=Ght4-4SIUZM:mdqRwxkEk-U:7Q72WNTAKBA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
159
+ &lt;/div&gt;&lt;img src="http://feeds2.feedburner.com/~r/railsquicktips/~4/Ght4-4SIUZM" height="1" width="1"/&gt;</description>
160
+ <dc:subject>rest ruby net http railstips</dc:subject>
161
+ <taxo:topics>
162
+ <rdf:Bag>
163
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/rest" />
164
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/ruby" />
165
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/net" />
166
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/http" />
167
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/railstips" />
168
+ </rdf:Bag>
169
+ </taxo:topics>
170
+ <feedburner:origLink>http://github.com/Fingertips/nap/tree/master</feedburner:origLink></item>
171
+ <item rdf:about="http://onrails.org/articles/2009/03/06/integrating-ftp-with-rails">
172
+ <title>Integrating FTP with Rails</title>
173
+ <dc:date>2009-03-10T18:09:49Z</dc:date>
174
+ <link>http://feedproxy.google.com/~r/railsquicktips/~3/IlVp6VGN5mM/integrating-ftp-with-rails</link>
175
+ <dc:creator>jnunemaker</dc:creator>
176
+ <description>Pretty interesting article on how to integrate ftp with your rails app. I would maybe swap out a few things but very nifty.&lt;div class="feedflare"&gt;
177
+ &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=IlVp6VGN5mM:DdojK1iPKK4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=IlVp6VGN5mM:DdojK1iPKK4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
178
+ &lt;/div&gt;&lt;img src="http://feeds2.feedburner.com/~r/railsquicktips/~4/IlVp6VGN5mM" height="1" width="1"/&gt;</description>
179
+ <dc:subject>ftp rails railstips pureftpd</dc:subject>
180
+ <taxo:topics>
181
+ <rdf:Bag>
182
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/ftp" />
183
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/rails" />
184
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/railstips" />
185
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/pureftpd" />
186
+ </rdf:Bag>
187
+ </taxo:topics>
188
+ <feedburner:origLink>http://onrails.org/articles/2009/03/06/integrating-ftp-with-rails</feedburner:origLink></item>
189
+ <item rdf:about="http://opensource.plurk.com/LightCloud">
190
+ <title>LightCloud</title>
191
+ <dc:date>2009-03-05T01:26:11Z</dc:date>
192
+ <link>http://feedproxy.google.com/~r/railsquicktips/~3/qtktAlFSiMg/LightCloud</link>
193
+ <dc:creator>jnunemaker</dc:creator>
194
+ <description>&amp;quot;Distributed and persistent key-value database.&amp;quot; Lightcloud is &amp;quot;not a replacement for memcached or MySQL - it&amp;#039;s a complement that can be used in situations where your data does not fit that well into the relational model.&amp;quot;&lt;div class="feedflare"&gt;
195
+ &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=qtktAlFSiMg:rzQJSVEUcsw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=qtktAlFSiMg:rzQJSVEUcsw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
196
+ &lt;/div&gt;&lt;img src="http://feeds2.feedburner.com/~r/railsquicktips/~4/qtktAlFSiMg" height="1" width="1"/&gt;</description>
197
+ <dc:subject>lightcloud key-value tokyotyrant plurk databases railstips</dc:subject>
198
+ <taxo:topics>
199
+ <rdf:Bag>
200
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/lightcloud" />
201
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/key-value" />
202
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/tokyotyrant" />
203
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/plurk" />
204
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/databases" />
205
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/railstips" />
206
+ </rdf:Bag>
207
+ </taxo:topics>
208
+ <feedburner:origLink>http://opensource.plurk.com/LightCloud</feedburner:origLink></item>
209
+ <item rdf:about="http://buddingrubyist.com/2009/02/14/how-to-speed-up-gem-installs-10x/">
210
+ <title>How to speed up gem installs 10x</title>
211
+ <dc:date>2009-02-28T04:56:17Z</dc:date>
212
+ <link>http://feedproxy.google.com/~r/railsquicktips/~3/cd343GhTpzg/</link>
213
+ <dc:creator>jnunemaker</dc:creator>
214
+ <description>Lovely tip on how to setup gem install to use --no-rdoc and --no-ri by default. Sweet.&lt;div class="feedflare"&gt;
215
+ &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=cd343GhTpzg:wWsV3iP6QK8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds2.feedburner.com/~ff/railsquicktips?a=cd343GhTpzg:wWsV3iP6QK8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds2.feedburner.com/~ff/railsquicktips?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
216
+ &lt;/div&gt;&lt;img src="http://feeds2.feedburner.com/~r/railsquicktips/~4/cd343GhTpzg" height="1" width="1"/&gt;</description>
217
+ <dc:subject>ruby gems installation railstips</dc:subject>
218
+ <taxo:topics>
219
+ <rdf:Bag>
220
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/ruby" />
221
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/gems" />
222
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/installation" />
223
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/railstips" />
224
+ </rdf:Bag>
225
+ </taxo:topics>
226
+ <feedburner:origLink>http://buddingrubyist.com/2009/02/14/how-to-speed-up-gem-installs-10x/</feedburner:origLink></item>
227
+ <item rdf:about="http://push.cx/2008/deploying-crontab-with-your-rails-app">
228
+ <title>Deploying Crontab With Your Rails App</title>
229
+ <dc:date>2009-02-24T21:24:16Z</dc:date>
230
+ <link>http://feedproxy.google.com/~r/railsquicktips/~3/ipIieD_KEnc/deploying-crontab-with-your-rails-app</link>
231
+ <dc:creator>jnunemaker</dc:creator>
232
+ <description>Pretty cool idea of installing a crontab with each deploy of your app.&lt;div class="feedflare"&gt;
233
+ &lt;a href="http://feeds2.feedburner.com/~f/railsquicktips?a=mii32c5H"&gt;&lt;img src="http://feeds2.feedburner.com/~f/railsquicktips?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds2.feedburner.com/~f/railsquicktips?a=UwSVtb3b"&gt;&lt;img src="http://feeds2.feedburner.com/~f/railsquicktips?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
234
+ &lt;/div&gt;&lt;img src="http://feeds2.feedburner.com/~r/railsquicktips/~4/ipIieD_KEnc" height="1" width="1"/&gt;</description>
235
+ <dc:subject>railstips cron capistrano deployment</dc:subject>
236
+ <taxo:topics>
237
+ <rdf:Bag>
238
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/railstips" />
239
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/cron" />
240
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/capistrano" />
241
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/deployment" />
242
+ </rdf:Bag>
243
+ </taxo:topics>
244
+ <feedburner:origLink>http://push.cx/2008/deploying-crontab-with-your-rails-app</feedburner:origLink></item>
245
+ <item rdf:about="http://www.coffeepowered.net/2009/02/15/graceful-degredation-using-gravatar-as-a-fallback-avatar-with-paperclip/">
246
+ <title>Using Gravatar as a fallback avatar with Paperclip</title>
247
+ <dc:date>2009-02-24T21:22:49Z</dc:date>
248
+ <link>http://feedproxy.google.com/~r/railsquicktips/~3/a64avpCNh4k/</link>
249
+ <dc:creator>jnunemaker</dc:creator>
250
+ <description>How to use paperclip for avatars and fall back to gravatar. I would say just pick one or the other but still interesting.&lt;div class="feedflare"&gt;
251
+ &lt;a href="http://feeds2.feedburner.com/~f/railsquicktips?a=WHKu1Khh"&gt;&lt;img src="http://feeds2.feedburner.com/~f/railsquicktips?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds2.feedburner.com/~f/railsquicktips?a=Ehun8PRd"&gt;&lt;img src="http://feeds2.feedburner.com/~f/railsquicktips?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
252
+ &lt;/div&gt;&lt;img src="http://feeds2.feedburner.com/~r/railsquicktips/~4/a64avpCNh4k" height="1" width="1"/&gt;</description>
253
+ <dc:subject>railstips</dc:subject>
254
+ <taxo:topics>
255
+ <rdf:Bag>
256
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/railstips" />
257
+ </rdf:Bag>
258
+ </taxo:topics>
259
+ <feedburner:origLink>http://www.coffeepowered.net/2009/02/15/graceful-degredation-using-gravatar-as-a-fallback-avatar-with-paperclip/</feedburner:origLink></item>
260
+ <item rdf:about="http://code.google.com/apis/gdata/articles/gdata_on_rails.html">
261
+ <title>Google Data on Rails</title>
262
+ <dc:date>2009-02-24T20:42:26Z</dc:date>
263
+ <link>http://feedproxy.google.com/~r/railsquicktips/~3/Bv8sdF19W7E/gdata_on_rails.html</link>
264
+ <dc:creator>jnunemaker</dc:creator>
265
+ <description>&amp;quot;Motivated by the ferocious appetite of our developers and the enduring popularity of Ruby on Rails (RoR), my colleague Jeff Fisher has forged a Ruby utility library from the fiery depths of Mount Doom.&amp;quot; Hahaha. We Ruby developers are passionate and annoying, aren&amp;#039;t we?&lt;div class="feedflare"&gt;
266
+ &lt;a href="http://feeds2.feedburner.com/~f/railsquicktips?a=EPY2Ix2U"&gt;&lt;img src="http://feeds2.feedburner.com/~f/railsquicktips?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds2.feedburner.com/~f/railsquicktips?a=9G8WJ8OL"&gt;&lt;img src="http://feeds2.feedburner.com/~f/railsquicktips?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
267
+ &lt;/div&gt;&lt;img src="http://feeds2.feedburner.com/~r/railsquicktips/~4/Bv8sdF19W7E" height="1" width="1"/&gt;</description>
268
+ <dc:subject>google railstips ruby rails</dc:subject>
269
+ <taxo:topics>
270
+ <rdf:Bag>
271
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/google" />
272
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/railstips" />
273
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/ruby" />
274
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/rails" />
275
+ </rdf:Bag>
276
+ </taxo:topics>
277
+ <feedburner:origLink>http://code.google.com/apis/gdata/articles/gdata_on_rails.html</feedburner:origLink></item>
278
+ <item rdf:about="http://getsprockets.org/">
279
+ <title>JavaScript dependency management and concatenation: Sprockets</title>
280
+ <dc:date>2009-02-20T01:46:51Z</dc:date>
281
+ <link>http://feedproxy.google.com/~r/railsquicktips/~3/FHyFVzxLToE/</link>
282
+ <dc:creator>jnunemaker</dc:creator>
283
+ <description>&amp;quot;Sprockets is a Ruby library that preprocesses and concatenates JavaScript source files.&amp;quot; New from Sam Stephenson.&lt;div class="feedflare"&gt;
284
+ &lt;a href="http://feeds2.feedburner.com/~f/railsquicktips?a=7ZFMClQx"&gt;&lt;img src="http://feeds2.feedburner.com/~f/railsquicktips?d=41" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds2.feedburner.com/~f/railsquicktips?a=RorJX9SL"&gt;&lt;img src="http://feeds2.feedburner.com/~f/railsquicktips?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
285
+ &lt;/div&gt;&lt;img src="http://feeds2.feedburner.com/~r/railsquicktips/~4/FHyFVzxLToE" height="1" width="1"/&gt;</description>
286
+ <dc:subject>javascript ruby railstips</dc:subject>
287
+ <taxo:topics>
288
+ <rdf:Bag>
289
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/javascript" />
290
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/ruby" />
291
+ <rdf:li rdf:resource="http://delicious.com/jnunemaker/railstips" />
292
+ </rdf:Bag>
293
+ </taxo:topics>
294
+ <feedburner:origLink>http://getsprockets.org/</feedburner:origLink></item>
295
+ </rdf:RDF>