columbus 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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>