feedjira 2.0.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/.rubocop.yml +15 -0
- data/.travis.yml +31 -12
- data/CHANGELOG.md +34 -1
- data/Dangerfile +1 -0
- data/Gemfile +2 -1
- data/LICENSE +1 -1
- data/README.md +210 -7
- data/Rakefile +11 -1
- data/feedjira.gemspec +17 -14
- data/fixtures/vcr_cassettes/fetch_failure.yml +62 -0
- data/fixtures/vcr_cassettes/parse_error.yml +222 -0
- data/fixtures/vcr_cassettes/success.yml +281 -0
- data/lib/feedjira/configuration.rb +76 -0
- data/lib/feedjira/core_ext/date.rb +3 -1
- data/lib/feedjira/core_ext/string.rb +2 -1
- data/lib/feedjira/core_ext/time.rb +24 -17
- data/lib/feedjira/core_ext.rb +3 -3
- data/lib/feedjira/date_time_utilities/date_time_epoch_parser.rb +13 -0
- data/lib/feedjira/date_time_utilities/date_time_language_parser.rb +24 -0
- data/lib/feedjira/date_time_utilities/date_time_pattern_parser.rb +34 -0
- data/lib/feedjira/date_time_utilities.rb +32 -0
- data/lib/feedjira/feed.rb +89 -62
- data/lib/feedjira/feed_entry_utilities.rb +20 -19
- data/lib/feedjira/feed_utilities.rb +37 -22
- data/lib/feedjira/parser/atom.rb +10 -8
- data/lib/feedjira/parser/atom_entry.rb +11 -13
- data/lib/feedjira/parser/atom_feed_burner.rb +27 -10
- data/lib/feedjira/parser/atom_feed_burner_entry.rb +12 -14
- data/lib/feedjira/parser/atom_youtube.rb +21 -0
- data/lib/feedjira/parser/atom_youtube_entry.rb +30 -0
- data/lib/feedjira/parser/google_docs_atom.rb +8 -7
- data/lib/feedjira/parser/google_docs_atom_entry.rb +13 -11
- data/lib/feedjira/parser/itunes_rss.rb +41 -22
- data/lib/feedjira/parser/itunes_rss_category.rb +39 -0
- data/lib/feedjira/parser/itunes_rss_item.rb +32 -20
- data/lib/feedjira/parser/itunes_rss_owner.rb +4 -4
- data/lib/feedjira/parser/podlove_chapter.rb +22 -0
- data/lib/feedjira/parser/rss.rb +11 -8
- data/lib/feedjira/parser/rss_entry.rb +17 -21
- data/lib/feedjira/parser/rss_feed_burner.rb +5 -6
- data/lib/feedjira/parser/rss_feed_burner_entry.rb +24 -28
- data/lib/feedjira/parser/rss_image.rb +15 -0
- data/lib/feedjira/parser.rb +1 -1
- data/lib/feedjira/preprocessor.rb +4 -2
- data/lib/feedjira/version.rb +1 -1
- data/lib/feedjira.rb +15 -0
- data/spec/feedjira/configuration_spec.rb +25 -0
- data/spec/feedjira/date_time_utilities_spec.rb +47 -0
- data/spec/feedjira/feed_entry_utilities_spec.rb +23 -19
- data/spec/feedjira/feed_spec.rb +140 -75
- data/spec/feedjira/feed_utilities_spec.rb +83 -63
- data/spec/feedjira/parser/atom_entry_spec.rb +54 -34
- data/spec/feedjira/parser/atom_feed_burner_entry_spec.rb +27 -20
- data/spec/feedjira/parser/atom_feed_burner_spec.rb +87 -30
- data/spec/feedjira/parser/atom_spec.rb +50 -48
- data/spec/feedjira/parser/atom_youtube_entry_spec.rb +86 -0
- data/spec/feedjira/parser/atom_youtube_spec.rb +43 -0
- data/spec/feedjira/parser/google_docs_atom_entry_spec.rb +5 -4
- data/spec/feedjira/parser/google_docs_atom_spec.rb +6 -6
- data/spec/feedjira/parser/itunes_rss_item_spec.rb +49 -29
- data/spec/feedjira/parser/itunes_rss_owner_spec.rb +10 -9
- data/spec/feedjira/parser/itunes_rss_spec.rb +87 -30
- data/spec/feedjira/parser/podlove_chapter_spec.rb +37 -0
- data/spec/feedjira/parser/rss_entry_spec.rb +50 -33
- data/spec/feedjira/parser/rss_feed_burner_entry_spec.rb +55 -33
- data/spec/feedjira/parser/rss_feed_burner_spec.rb +31 -26
- data/spec/feedjira/parser/rss_spec.rb +56 -24
- data/spec/feedjira/preprocessor_spec.rb +11 -3
- data/spec/sample_feeds/AmazonWebServicesBlog.xml +797 -797
- data/spec/sample_feeds/AtomEscapedHTMLInPreTag.xml +13 -0
- data/spec/sample_feeds/CRE.xml +5849 -0
- data/spec/sample_feeds/FeedBurnerXHTML.xml +400 -400
- data/spec/sample_feeds/GiantRobotsSmashingIntoOtherGiantRobots.xml +682 -0
- data/spec/sample_feeds/ITunesWithSingleQuotedAttributes.xml +67 -0
- data/spec/sample_feeds/InvalidDateFormat.xml +20 -0
- data/spec/sample_feeds/PaulDixExplainsNothing.xml +175 -175
- data/spec/sample_feeds/PaulDixExplainsNothingAlternate.xml +175 -175
- data/spec/sample_feeds/PaulDixExplainsNothingFirstEntryContent.xml +16 -16
- data/spec/sample_feeds/PaulDixExplainsNothingWFW.xml +174 -174
- data/spec/sample_feeds/TenderLovemaking.xml +12 -2
- data/spec/sample_feeds/TrotterCashionHome.xml +611 -611
- data/spec/sample_feeds/TypePadNews.xml +368 -368
- data/spec/sample_feeds/itunes.xml +31 -2
- data/spec/sample_feeds/pet_atom.xml +229 -229
- data/spec/sample_feeds/youtube_atom.xml +395 -0
- data/spec/sample_feeds.rb +31 -21
- data/spec/spec_helper.rb +6 -0
- metadata +132 -25
@@ -0,0 +1,222 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://feedjira.com/
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
User-Agent:
|
11
|
+
- Faraday v0.9.2
|
12
|
+
response:
|
13
|
+
status:
|
14
|
+
code: 200
|
15
|
+
message:
|
16
|
+
headers:
|
17
|
+
date:
|
18
|
+
- Mon, 31 Oct 2016 02:29:13 GMT
|
19
|
+
server:
|
20
|
+
- Apache/2.4.18 (Ubuntu)
|
21
|
+
last-modified:
|
22
|
+
- Fri, 07 Oct 2016 14:50:31 GMT
|
23
|
+
etag:
|
24
|
+
- '"3678-53e47882c0305-gzip"'
|
25
|
+
accept-ranges:
|
26
|
+
- bytes
|
27
|
+
vary:
|
28
|
+
- Accept-Encoding
|
29
|
+
content-length:
|
30
|
+
- '3519'
|
31
|
+
connection:
|
32
|
+
- close
|
33
|
+
content-type:
|
34
|
+
- text/html
|
35
|
+
body:
|
36
|
+
encoding: ASCII-8BIT
|
37
|
+
string: |
|
38
|
+
<!DOCTYPE html>
|
39
|
+
<html>
|
40
|
+
<head>
|
41
|
+
<meta charset='utf-8'>
|
42
|
+
<meta content='IE=edge;chrome=1' http-equiv='X-UA-Compatible'>
|
43
|
+
<meta content='width=device-width, initial-scale=.7, maximum-scale=1' name='viewport'>
|
44
|
+
<title>Feedjira</title>
|
45
|
+
<link href="http://fonts.googleapis.com/css?family=Merriweather+Sans:400,300,400italic,700,700italic,300italic" rel="stylesheet" type="text/css" media="screen" />
|
46
|
+
<link href="/css/syntax.css" media="screen" rel="stylesheet" type="text/css" />
|
47
|
+
<link href="/css/style.css" media="screen" rel="stylesheet" type="text/css" />
|
48
|
+
<link rel="alternate" type="application/atom+xml" title="Atom Feed" href="/blog/feed.xml" />
|
49
|
+
</head>
|
50
|
+
<body>
|
51
|
+
<div id='content'>
|
52
|
+
<header>
|
53
|
+
<h1><a href="/">Feedjira</a></h1>
|
54
|
+
</header>
|
55
|
+
<nav>
|
56
|
+
<ul>
|
57
|
+
<li><a href="/">Home</a></li>
|
58
|
+
<li><a href="/blog/">Blog</a></li>
|
59
|
+
<li><a target="_blank" href="https://github.com/feedjira/feedjira">Source</a></li>
|
60
|
+
</ul>
|
61
|
+
</nav>
|
62
|
+
<section><h1>The Feedjira Ruby Gem</h1>
|
63
|
+
|
64
|
+
<p><a href="https://github.com/feedjira/feedjira">Feedjira</a> (formerly Feedzirra) is a Ruby gem for fetching and parsing
|
65
|
+
RSS feeds. Version 2.0 <a href="/blog/2015/06/05/feedjira-two-point-oh.html">was recently released</a>.</p>
|
66
|
+
|
67
|
+
<h2>Getting Started</h2>
|
68
|
+
|
69
|
+
<p>Feedjira is tested with Ruby version 1.9.3 and 2.x so like any Ruby gem, the
|
70
|
+
first step is to install the gem:</p>
|
71
|
+
<pre class="highlight text"><table><tbody><tr><td class="gutter gl"><div class="lineno">1</div></td><td class="code">$ gem install feedjira
|
72
|
+
</td></tr></tbody></table></pre>
|
73
|
+
<p>Or add it to your Gemfile:</p>
|
74
|
+
<pre class="highlight ruby"><table><tbody><tr><td class="gutter gl"><div class="lineno">1</div></td><td class="code"><span class="n">gem</span> <span class="s1">'feedjira'</span>
|
75
|
+
</td></tr></tbody></table></pre>
|
76
|
+
<h2>Fetching and Parsing</h2>
|
77
|
+
|
78
|
+
<p>For many users, the <code>fetch_and_parse</code> method is what they use Feedjira for. This
|
79
|
+
method takes a url and returns a Parser object:</p>
|
80
|
+
<pre class="highlight ruby"><table><tbody><tr><td class="gutter gl"><div class="lineno">1</div><div class="lineno">2</div><div class="lineno">3</div></td><td class="code"><span class="n">url</span> <span class="o">=</span> <span class="s2">"http://feedjira.com/blog/feed.xml"</span>
|
81
|
+
<span class="n">feed</span> <span class="o">=</span> <span class="no">Feedjira</span><span class="o">::</span><span class="no">Feed</span><span class="nf">.fetch_and_parse</span> <span class="n">url</span>
|
82
|
+
<span class="c1"># => #<Feedjira::Parser::Atom...></span>
|
83
|
+
</td></tr></tbody></table></pre>
|
84
|
+
<p>These feed objects have both the meta data for a feed and an <code>entries</code>
|
85
|
+
collection that contains all the entries that were found:</p>
|
86
|
+
<pre class="highlight ruby"><table><tbody><tr><td class="gutter gl"><div class="lineno">1</div><div class="lineno">2</div><div class="lineno">3</div><div class="lineno">4</div><div class="lineno">5</div><div class="lineno">6</div></td><td class="code"><span class="n">feed</span><span class="nf">.title</span>
|
87
|
+
<span class="c1"># => "Feedjira Blog"</span>
|
88
|
+
<span class="n">feed</span><span class="nf">.url</span>
|
89
|
+
<span class="c1"># => "http://feedjira.com/blog"</span>
|
90
|
+
<span class="n">feed</span><span class="nf">.entries</span> <span class="c1"># returns an array of Entry objects</span>
|
91
|
+
<span class="c1"># => [<Feedjira::Feed::Entry ...>, <Feedjira::Feed::Entry ...>, ...]</span>
|
92
|
+
</td></tr></tbody></table></pre>
|
93
|
+
<p>These entry objects contain the data parsed from the feed XML:</p>
|
94
|
+
<pre class="highlight ruby"><table><tbody><tr><td class="gutter gl"><div class="lineno">1</div><div class="lineno">2</div><div class="lineno">3</div><div class="lineno">4</div><div class="lineno">5</div></td><td class="code"><span class="n">entry</span> <span class="o">=</span> <span class="n">feed</span><span class="nf">.entries.first</span>
|
95
|
+
<span class="n">entry</span><span class="nf">.title</span>
|
96
|
+
<span class="c1"># => "Announcing verison 1.0"</span>
|
97
|
+
<span class="n">entry</span><span class="nf">.url</span>
|
98
|
+
<span class="c1"># => "http://feedjira.com/blog/2014-02-12-announcing-version-10.html"</span>
|
99
|
+
</td></tr></tbody></table></pre>
|
100
|
+
<h2>Just Parsing</h2>
|
101
|
+
|
102
|
+
<p>The parsing functionality of Feedjira has been exposed so that it can be used in
|
103
|
+
isolation:</p>
|
104
|
+
<pre class="highlight ruby"><table><tbody><tr><td class="gutter gl"><div class="lineno">1</div><div class="lineno">2</div><div class="lineno">3</div><div class="lineno">4</div></td><td class="code"><span class="n">xml</span> <span class="o">=</span> <span class="no">Faraday</span><span class="nf">.get</span><span class="p">(</span><span class="n">url</span><span class="p">)</span><span class="nf">.body</span>
|
105
|
+
<span class="n">feed</span> <span class="o">=</span> <span class="no">Feedjira</span><span class="o">::</span><span class="no">Feed</span><span class="nf">.parse</span> <span class="n">xml</span>
|
106
|
+
<span class="n">feed</span><span class="nf">.entries.first.title</span>
|
107
|
+
<span class="c1"># => "Announcing verison 1.0"</span>
|
108
|
+
</td></tr></tbody></table></pre>
|
109
|
+
<h2>Adding a feed parsing class</h2>
|
110
|
+
|
111
|
+
<p>When determining which parser to use for a given XML document, the following
|
112
|
+
list of parser classes is used:</p>
|
113
|
+
|
114
|
+
<ul>
|
115
|
+
<li><code>Feedjira::Parser::RSSFeedBurner</code></li>
|
116
|
+
<li><code>Feedjira::Parser::GoogleDocsAtom</code></li>
|
117
|
+
<li><code>Feedjira::Parser::AtomFeedBurner</code></li>
|
118
|
+
<li><code>Feedjira::Parser::Atom</code></li>
|
119
|
+
<li><code>Feedjira::Parser::ITunesRSS</code></li>
|
120
|
+
<li><code>Feedjira::Parser::RSS</code></li>
|
121
|
+
</ul>
|
122
|
+
|
123
|
+
<p>You can insert your own parser at the front of this stack by calling
|
124
|
+
<code>add_feed_class</code>, like this:</p>
|
125
|
+
<pre class="highlight ruby"><table><tbody><tr><td class="gutter gl"><div class="lineno">1</div></td><td class="code"><span class="no">Feedjira</span><span class="o">::</span><span class="no">Feed</span><span class="nf">.add_feed_class</span> <span class="no">MyAwesomeParser</span>
|
126
|
+
</td></tr></tbody></table></pre>
|
127
|
+
<p>Now when you <code>fetch_and_parse</code>, <code>MyAwesomeParser</code> will be the first one to get a
|
128
|
+
chance to parse the feed.</p>
|
129
|
+
|
130
|
+
<p>If you have the XML and just want to provide a parser class for one parse, you
|
131
|
+
can specify that using <code>parse_with</code>:</p>
|
132
|
+
<pre class="highlight ruby"><table><tbody><tr><td class="gutter gl"><div class="lineno">1</div></td><td class="code"><span class="no">Feedjira</span><span class="o">::</span><span class="no">Feed</span><span class="nf">.parse_with</span> <span class="no">MyAwesomeParser</span><span class="p">,</span> <span class="n">xml</span>
|
133
|
+
</td></tr></tbody></table></pre>
|
134
|
+
<h2>Adding attributes to all feeds types / all entries types</h2>
|
135
|
+
<pre class="highlight ruby"><table><tbody><tr><td class="gutter gl"><div class="lineno">1</div><div class="lineno">2</div><div class="lineno">3</div><div class="lineno">4</div><div class="lineno">5</div><div class="lineno">6</div><div class="lineno">7</div><div class="lineno">8</div><div class="lineno">9</div><div class="lineno">10</div></td><td class="code"><span class="c1"># Add the generator attribute to all feed types</span>
|
136
|
+
<span class="no">Feedjira</span><span class="o">::</span><span class="no">Feed</span><span class="nf">.add_common_feed_element</span><span class="p">(</span><span class="s1">'generator'</span><span class="p">)</span>
|
137
|
+
<span class="no">Feedjira</span><span class="o">::</span><span class="no">Feed</span><span class="nf">.fetch_and_parse</span><span class="p">(</span><span class="s2">"http://www.pauldix.net/atom.xml"</span><span class="p">)</span><span class="nf">.generator</span> <span class="c1"># => 'TypePad'</span>
|
138
|
+
|
139
|
+
<span class="c1"># Add some GeoRss information</span>
|
140
|
+
<span class="no">Feedjira</span><span class="o">::</span><span class="no">Feed</span><span class="nf">.add_common_feed_entry_element</span><span class="p">(</span><span class="s1">'geo:lat'</span><span class="p">,</span> <span class="ss">:as</span> <span class="o">=></span> <span class="ss">:lat</span><span class="p">)</span>
|
141
|
+
<span class="no">Feedjira</span><span class="o">::</span><span class="no">Feed</span><span class="nf">.fetch_and_parse</span><span class="p">(</span><span class="s2">"http://www.earthpublisher.com/georss.php"</span><span class="p">)</span><span class="nf">.entries.each</span> <span class="k">do</span> <span class="o">|</span><span class="n">e</span><span class="o">|</span>
|
142
|
+
<span class="nb">p</span> <span class="s2">"lat: #[e.lat}, long: </span><span class="si">#{</span><span class="n">e</span><span class="nf">.long</span><span class="o">]</span><span class="s2">"
|
143
|
+
end
|
144
|
+
</span></td></tr></tbody></table></pre>
|
145
|
+
<h2>Adding attributes to only one class</h2>
|
146
|
+
|
147
|
+
<p>If you want to add attributes for only one class you simply have to declare them
|
148
|
+
in the class</p>
|
149
|
+
<pre class="highlight ruby"><table><tbody><tr><td class="gutter gl"><div class="lineno">1</div><div class="lineno">2</div><div class="lineno">3</div><div class="lineno">4</div><div class="lineno">5</div><div class="lineno">6</div><div class="lineno">7</div><div class="lineno">8</div><div class="lineno">9</div><div class="lineno">10</div><div class="lineno">11</div><div class="lineno">12</div></td><td class="code"><span class="c1"># Add some GeoRss information</span>
|
150
|
+
<span class="nb">require</span> <span class="s1">'lib/feedzirra/parser/rss_entry'</span>
|
151
|
+
|
152
|
+
<span class="k">class </span><span class="nc">Feedjira</span><span class="o">::</span><span class="no">Parser</span><span class="o">::</span><span class="no">RSSEntry</span>
|
153
|
+
<span class="n">element</span> <span class="s1">'geo:lat'</span><span class="p">,</span> <span class="ss">:as</span> <span class="o">=></span> <span class="ss">:lat</span>
|
154
|
+
<span class="n">element</span> <span class="s1">'geo:long'</span><span class="p">,</span> <span class="ss">:as</span> <span class="o">=></span> <span class="ss">:long</span>
|
155
|
+
<span class="k">end</span>
|
156
|
+
|
157
|
+
<span class="c1"># Fetch a feed containing GeoRss info and print them</span>
|
158
|
+
<span class="no">Feedjira</span><span class="o">::</span><span class="no">Feed</span><span class="nf">.fetch_and_parse</span><span class="p">(</span><span class="s2">"http://www.earthpublisher.com/georss.php"</span><span class="p">)</span><span class="nf">.entries.each</span> <span class="k">do</span> <span class="o">|</span><span class="n">e</span><span class="o">|</span>
|
159
|
+
<span class="nb">p</span> <span class="s2">"lat: </span><span class="si">#{</span><span class="n">e</span><span class="nf">.lat</span><span class="si">}</span><span class="s2">, long: </span><span class="si">#{</span><span class="n">e</span><span class="nf">.long</span><span class="si">}</span><span class="s2">"</span>
|
160
|
+
<span class="k">end</span>
|
161
|
+
</td></tr></tbody></table></pre>
|
162
|
+
<h2>Testing</h2>
|
163
|
+
|
164
|
+
<p>Feedjira uses <a href="https://github.com/lostisland/faraday">faraday</a> to perform requests, so testing Feedjira is really
|
165
|
+
about <a href="https://github.com/lostisland/faraday#using-faraday-for-testing">stubbing out faraday requests</a>.</p>
|
166
|
+
|
167
|
+
<h2>Projects that use Feedjira</h2>
|
168
|
+
|
169
|
+
<p>Feedjira is used in some awesome projects around the web - from RSS readers to
|
170
|
+
add-ons and everything in between. Here are some of them:</p>
|
171
|
+
|
172
|
+
<ul>
|
173
|
+
<li><p><a href="https://feedbin.com/">Feedbin</a>: Feedbin bills itself as a fast, simple RSS reader that delivers a
|
174
|
+
great reading experience. It’s a paid RSS reader that integrates with mobile
|
175
|
+
apps and it even has a fully featured API!</p></li>
|
176
|
+
<li><p><a href="https://github.com/swanson/stringer">Stringer</a>: Stringer is a self-hosted, anti-social RSS reader. It’s an
|
177
|
+
open-source project that’s easy to deploy to any host, there’s even a
|
178
|
+
one-click button to deploy on Heroku.</p></li>
|
179
|
+
<li><p><a href="https://apps.shopify.com/blogfeeder">BlogFeeder</a>: BlogFeeder is a paid Shopify App that makes it easy for you to
|
180
|
+
import any external blog into your Shopify store. It helps improve your
|
181
|
+
store’s SEO and keeps your blogs in sync, plus a lot more.</p></li>
|
182
|
+
<li><p><a href="https://github.com/amatriain/feedbunch">Feedbunch</a>: Feedbunch is an open source feed reader built to fill the hole
|
183
|
+
left by Google Reader. It aims to support all features of Google Reader and
|
184
|
+
actually improve on others.</p></li>
|
185
|
+
<li><p><a href="http://theoldreader.com/">The Old Reader</a>: The Old Reader advertises as the ultimate social RSS
|
186
|
+
reader. It’s free to start and also has a paid premium version. There’s an API
|
187
|
+
and it integrates with many different mobile apps.</p></li>
|
188
|
+
<li><p><a href="https://solveforall.com/">Solve for All</a>: Solve for All combines search engine and feed parsing
|
189
|
+
while protecting your privacy. It’s even extendable by the community!</p></li>
|
190
|
+
</ul>
|
191
|
+
|
192
|
+
<p>Note: to get your project on this list, simply <a href="mailto:feedjira@gmail.com">send an email</a>
|
193
|
+
with your project’s details.</p>
|
194
|
+
</section>
|
195
|
+
</div>
|
196
|
+
<footer>
|
197
|
+
<div class='column'>
|
198
|
+
<ul>
|
199
|
+
<li><a href="/">Home</a></li>
|
200
|
+
<li><a href="/blog/">Blog</a></li>
|
201
|
+
<li><a href="/blog/feed.xml">Feed</a></li>
|
202
|
+
<li><a target="_blank" href="https://github.com/feedjira/feedjira">Source</a></li>
|
203
|
+
<li><a target="_blank" href="https://twitter.com/feedjira">@feedjira</a></li>
|
204
|
+
</ul>
|
205
|
+
<p>Maintained by <a href="http://jonallured.com">Jon Allured</a>, Created by <a href="http://www.pauldix.net">Paul Dix</a>, Site design by <a href="http://danielariza.com">Daniel Ariza</a></p>
|
206
|
+
</div>
|
207
|
+
</footer>
|
208
|
+
<script type="text/javascript">
|
209
|
+
var _gaq = _gaq || [];
|
210
|
+
_gaq.push(["_setAccount", "UA-3137727-7"]);
|
211
|
+
_gaq.push(["_trackPageview"]);
|
212
|
+
(function() {
|
213
|
+
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
214
|
+
ga.src = ('https:' == document.location.protocol ? '//ssl' : '//www') + '.google-analytics.com/ga.js';
|
215
|
+
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
216
|
+
})();
|
217
|
+
</script>
|
218
|
+
</body>
|
219
|
+
</html>
|
220
|
+
http_version:
|
221
|
+
recorded_at: Mon, 31 Oct 2016 02:29:13 GMT
|
222
|
+
recorded_with: VCR 3.0.3
|
@@ -0,0 +1,281 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://feedjira.com/blog/feed.xml
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
User-Agent:
|
11
|
+
- Faraday v0.9.2
|
12
|
+
response:
|
13
|
+
status:
|
14
|
+
code: 200
|
15
|
+
message:
|
16
|
+
headers:
|
17
|
+
date:
|
18
|
+
- Mon, 31 Oct 2016 02:29:13 GMT
|
19
|
+
server:
|
20
|
+
- Apache/2.4.18 (Ubuntu)
|
21
|
+
last-modified:
|
22
|
+
- Fri, 07 Oct 2016 14:37:00 GMT
|
23
|
+
etag:
|
24
|
+
- '"393e-53e4757c9db00-gzip"'
|
25
|
+
accept-ranges:
|
26
|
+
- bytes
|
27
|
+
vary:
|
28
|
+
- Accept-Encoding
|
29
|
+
content-length:
|
30
|
+
- '5051'
|
31
|
+
connection:
|
32
|
+
- close
|
33
|
+
content-type:
|
34
|
+
- application/xml
|
35
|
+
body:
|
36
|
+
encoding: ASCII-8BIT
|
37
|
+
string: |
|
38
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
39
|
+
<feed xmlns="http://www.w3.org/2005/Atom">
|
40
|
+
<title>Feedjira Blog</title>
|
41
|
+
<subtitle>A Blog for Feedjira</subtitle>
|
42
|
+
<id>http://feedjira.com/blog</id>
|
43
|
+
<link href="http://feedjira.com/blog"/>
|
44
|
+
<link href="http://feedjira.com/blog/feed.xml" rel="self"/>
|
45
|
+
<updated>2015-06-05T00:00:00Z</updated>
|
46
|
+
<author>
|
47
|
+
<name>Jon Allured</name>
|
48
|
+
</author>
|
49
|
+
<entry>
|
50
|
+
<title>Feedjira Two-Point-Oh</title>
|
51
|
+
<link rel="alternate" href="http://feedjira.com/blog/2015/06/05/feedjira-two-point-oh.html"/>
|
52
|
+
<id>http://feedjira.com/blog/2015/06/05/feedjira-two-point-oh.html</id>
|
53
|
+
<published>2015-06-05T00:00:00Z</published>
|
54
|
+
<updated>2015-04-17T16:16:07-05:00</updated>
|
55
|
+
<author>
|
56
|
+
<name>Jon Allured</name>
|
57
|
+
</author>
|
58
|
+
<content type="html"><p>About a year ago, I took Feedjira to <a href="http://feedjira.com/blog/2014/03/17/feedjira-goes-one-point-oh.html">version 1.0</a> and today I&rsquo;m releasing
|
59
|
+
version 2.0. Not much has changed actually - the biggest difference is that
|
60
|
+
<code>curb</code> has been replaced with <code>faraday</code>. For many users, upgrading to version
|
61
|
+
2.0 won&rsquo;t require anything more than a <code>bundle update feedjira</code>.</p>
|
62
|
+
|
63
|
+
<p>The other big change is that the <code>Feedjira#update</code> method was removed. It was
|
64
|
+
unreliable and mostly just caused issues. To read more about why this was
|
65
|
+
removed, check out <a href="https://github.com/feedjira/feedjira/issues/218#issuecomment-40282091">this comment</a> on a GitHub issue that was opened
|
66
|
+
about it not working as expected.</p>
|
67
|
+
|
68
|
+
<p>I&rsquo;ve also updated the site to reflect the changes in this version. I took the
|
69
|
+
opportunity to greatly simply things and got just about all the documentation to
|
70
|
+
fit on one page.</p>
|
71
|
+
|
72
|
+
<p>I hope you like version 2.0 - feel free to hit me up <a href="https://twitter.com/feedjira">on Twitter</a> or if
|
73
|
+
you have any trouble, open a <a href="https://github.com/feedjira/feedjira/issues">GitHub issue</a> and I&rsquo;ll give you a hand.</p>
|
74
|
+
|
75
|
+
<p>Finally, thanks to those that gave me feedback on either my thoughts on version
|
76
|
+
2.0 or the release candidate - I really appreciate it!</p>
|
77
|
+
</content>
|
78
|
+
</entry>
|
79
|
+
<entry>
|
80
|
+
<title>Thoughts on Version Two-Point-Oh</title>
|
81
|
+
<link rel="alternate" href="http://feedjira.com/blog/2014/04/14/thoughts-on-version-two-point-oh.html"/>
|
82
|
+
<id>http://feedjira.com/blog/2014/04/14/thoughts-on-version-two-point-oh.html</id>
|
83
|
+
<published>2014-04-14T00:00:00Z</published>
|
84
|
+
<updated>2014-09-05T12:15:28-05:00</updated>
|
85
|
+
<author>
|
86
|
+
<name>Jon Allured</name>
|
87
|
+
</author>
|
88
|
+
<content type="html"><p>TLDR: development of version 2.0 is being done on the <a href="https://github.com/feedjira/feedjira/tree/two-point-oh">two-point-oh branch</a>
|
89
|
+
and a <a href="https://github.com/feedjira/feedjira/issues/221">GitHub issue</a> is open for you to give feedback on its direction.</p>
|
90
|
+
|
91
|
+
<p>I&rsquo;ve starting work on a rewrite for Feedjira and I wanted to try using a <a href="https://github.com/feedjira/feedjira/issues/221">GitHub
|
92
|
+
issue</a> to discuss what I&rsquo;d like to see in the new version. I&rsquo;m very
|
93
|
+
interested in what users think, so please chime in!!</p>
|
94
|
+
|
95
|
+
<p>In no particular order, here are some design goals for the new version:</p>
|
96
|
+
|
97
|
+
<h2>Change HTTP Library</h2>
|
98
|
+
|
99
|
+
<p>This gem depends on <a href="https://github.com/taf2/curb">curb</a>, but I&rsquo;d like to switch that to something that will
|
100
|
+
allow me to support JRuby. I did some experimenting and really liked working
|
101
|
+
with <a href="https://github.com/lostisland/faraday">Faraday</a>, so that&rsquo;s what I&rsquo;m using at the moment.</p>
|
102
|
+
|
103
|
+
<h2>Forget Concurrency</h2>
|
104
|
+
|
105
|
+
<p>Throwing an array of feed urls at Feedjira and watching it concurrently fetch
|
106
|
+
and parse them extremely quickly is cool in READMEs and demos, but I don&rsquo;t think
|
107
|
+
it&rsquo;s reality. I think what&rsquo;s much more likely is a single url being passed and
|
108
|
+
concurrency being dealt with in the application, workers being the likely
|
109
|
+
approach.</p>
|
110
|
+
|
111
|
+
<h2>More Objects</h2>
|
112
|
+
|
113
|
+
<p>Feedjira has a dirty little secret and it&rsquo;s the <code>Feedjira::Feed</code> class. If you
|
114
|
+
open that sucker up, you&rsquo;ll see 19 class methods and 0 instance methods. These
|
115
|
+
class methods do everything from fetching and parsing to setting up curb and
|
116
|
+
unzipping raw xml. Not only is <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle">SRP</a> off in the corner crying, its a mess to
|
117
|
+
test. I&rsquo;d like to break this down into smaller objects that get instantiated and
|
118
|
+
passed around in normal OO fashion.</p>
|
119
|
+
|
120
|
+
<h2>Fewer Parsers</h2>
|
121
|
+
|
122
|
+
<p>One of the things I like best about Feedjira is the ability for a user to define
|
123
|
+
their own custom parsers and I think its under-used. What I&rsquo;d like to see is
|
124
|
+
Feedjira ship with a parser for Atom and a parser for RSS - the others are
|
125
|
+
really just custom parsers.</p>
|
126
|
+
|
127
|
+
<h2>Custom Parser Project</h2>
|
128
|
+
|
129
|
+
<p>With version 1.2, I was able to spin off the benchmarks into <a href="https://github.com/feedjira/feedjira-benchmarks">their own
|
130
|
+
project</a> and I was very happy with how it turned out - I&rsquo;d like to see a
|
131
|
+
similar thing happen with the custom parsers mentioned above. You should be able
|
132
|
+
to easily grab these parsers and throw them in your application. If you write a
|
133
|
+
particularly cool custom parser, then you could contribute it back and others
|
134
|
+
could benefit from it.</p>
|
135
|
+
|
136
|
+
<h2>Raise Exceptions Instead of Callbacks</h2>
|
137
|
+
|
138
|
+
<p>Feedjira almost never raises an exception and instead provides the ability to
|
139
|
+
register callbacks for success and failure situations, but this has proven
|
140
|
+
brittle and painful. With the new version, I want to see sensible exceptions
|
141
|
+
raised when something goes wrong and that pretty much removes the need for
|
142
|
+
callbacks, so those will be cut.</p>
|
143
|
+
|
144
|
+
<h2>Feed Updating is Business Logic</h2>
|
145
|
+
|
146
|
+
<p>The updating functionality of Feedjira leaves a lot to be desired - its
|
147
|
+
inconsistent and there are lots of edges. I tend to steer users away and
|
148
|
+
encourage them to write this kind of code in their application instead. See
|
149
|
+
<a href="https://github.com/feedjira/feedjira/issues/218">this discussion</a> for more, but needless to say, I&rsquo;d like to see this entire
|
150
|
+
feature set removed.</p>
|
151
|
+
|
152
|
+
<h2>Configuration</h2>
|
153
|
+
|
154
|
+
<p>I want configuration for Feedjira done in a proper config block like most gems.
|
155
|
+
If you want to change the default parsers, that should be a config option. If
|
156
|
+
you want to set the user agent, that should be a configuration option.</p>
|
157
|
+
|
158
|
+
<h2>Feedback Appreciated</h2>
|
159
|
+
|
160
|
+
<p>Do you have any other ideas to make Feedjira better? Please check out the
|
161
|
+
<a href="https://github.com/feedjira/feedjira/issues/221">GitHub issue</a> and share what you&rsquo;re thinking. I&rsquo;m open to any feedback, so
|
162
|
+
if I just threw your favorite feature on the chopping block, please tell me!</p>
|
163
|
+
</content>
|
164
|
+
</entry>
|
165
|
+
<entry>
|
166
|
+
<title>A Separate Project For Benchmarks</title>
|
167
|
+
<link rel="alternate" href="http://feedjira.com/blog/2014/04/11/a-separate-project-for-benchmarks.html"/>
|
168
|
+
<id>http://feedjira.com/blog/2014/04/11/a-separate-project-for-benchmarks.html</id>
|
169
|
+
<published>2014-04-11T00:00:00Z</published>
|
170
|
+
<updated>2014-09-05T12:15:28-05:00</updated>
|
171
|
+
<author>
|
172
|
+
<name>Jon Allured</name>
|
173
|
+
</author>
|
174
|
+
<content type="html"><p>With the release of version 1.2.0, the benchmarks for Feedjira have been moved
|
175
|
+
to a separate project: <a href="https://github.com/feedjira/feedjira-benchmarks">https://github.com/feedjira/feedjira-benchmarks</a>.</p>
|
176
|
+
|
177
|
+
<p>What&rsquo;s nice about this is that it keeps things much more organized and allowed
|
178
|
+
me to add a pretty neat new benchmark - more on that in a moment. I also rewrote
|
179
|
+
the <a href="/benchmarks.html">Benchmarks page</a> on this site so please check that out.</p>
|
180
|
+
|
181
|
+
<p>One benchmark that I didn&rsquo;t pull over to the new project is the fetching one. I
|
182
|
+
left it out because it relied on the consistency of your network connection and
|
183
|
+
that didn&rsquo;t feel like it was scientific enough.</p>
|
184
|
+
|
185
|
+
<p>In its place I&rsquo;ve added a benchmark for parsing speed that&rsquo;s run against each
|
186
|
+
version of the gem. Its pretty cool - when you clone down the
|
187
|
+
feedjira-benchmarks project, you also clone down feedjira itself and then the
|
188
|
+
script moves to each version tag in the git repo, runs the benchmark and records
|
189
|
+
the results. It was pretty fun to write and works like a charm.</p>
|
190
|
+
|
191
|
+
<p>For the charts, I ended up learning some <a href="http://www.r-project.org/">R</a> so that I could have a little
|
192
|
+
more control.</p>
|
193
|
+
|
194
|
+
<p>Benchmarks are really only valuable if they can be reproduced by others, so I&rsquo;ve
|
195
|
+
written up instructions in the README for setting things up and running them. If
|
196
|
+
you&rsquo;re interested, take a look and try running them yourself!</p>
|
197
|
+
|
198
|
+
<p>I&rsquo;ll continue to use the benchmarks to ensure Feedjira stays fast, so you wont
|
199
|
+
have to worry about your favorite Ruby feed library slowing down. If you have
|
200
|
+
any feedback for me on the benchmarks, feel free to hit me up on Twitter
|
201
|
+
(<a href="https://twitter.com/feedjira">@feedjira</a>) or <a href="https://github.com/feedjira/feedjira-benchmarks/issues">open an issue</a> on the project&rsquo;s repo.</p>
|
202
|
+
</content>
|
203
|
+
</entry>
|
204
|
+
<entry>
|
205
|
+
<title>Feedjira Goes One-Point-Oh</title>
|
206
|
+
<link rel="alternate" href="http://feedjira.com/blog/2014/03/17/feedjira-goes-one-point-oh.html"/>
|
207
|
+
<id>http://feedjira.com/blog/2014/03/17/feedjira-goes-one-point-oh.html</id>
|
208
|
+
<published>2014-03-17T00:00:00Z</published>
|
209
|
+
<updated>2014-09-05T12:15:28-05:00</updated>
|
210
|
+
<author>
|
211
|
+
<name>Jon Allured</name>
|
212
|
+
</author>
|
213
|
+
<content type="html"><p>Last fall, I asked <a href="http://www.pauldix.net">Paul Dix</a> if I could take over maintenance of his gem
|
214
|
+
Feedzirra. My request was totally out of the blue, so I was pretty pumped when
|
215
|
+
he got right back to me and said yes. He said that he didn&rsquo;t have time to work
|
216
|
+
on it anymore and so I should feel free to do whatever I thought was best.</p>
|
217
|
+
|
218
|
+
<p>Score!</p>
|
219
|
+
|
220
|
+
<p>My first order of business was to go through the many open issues and pull
|
221
|
+
requests on GitHub. When I started there were over 60, a number that I&rsquo;ve gotten
|
222
|
+
down to just a few. I thought it was important to ensure that users saw me treat
|
223
|
+
their issue as important and even if it was very old (which many were), I asked
|
224
|
+
if there was anything I could do to help.</p>
|
225
|
+
|
226
|
+
<p>I was pleasantly surprised by the nice way many people responded and we got to
|
227
|
+
work addressing their questions and issues.</p>
|
228
|
+
|
229
|
+
<p>As I was working through issues and pull requests, I kept <a href="http://semver.org">SemVer</a> in mind -
|
230
|
+
bug fixes in patch releases and backward-compatible changes in minor releases.
|
231
|
+
But I also realized that it was past time for this project to be at version 1.0.
|
232
|
+
In the SemVer FAQ, they talk about when to release version 1.0 and Feedzirra fit
|
233
|
+
the bill: it was being used in production, there was a stable API and I was
|
234
|
+
taking backwards compatibilty seriously.</p>
|
235
|
+
|
236
|
+
<p>So I treated it as a project at 1.0 and I did my best to release versions that
|
237
|
+
were backward compatible and added deprecations for what I wanted to do in 1.0.
|
238
|
+
I saw things that I wanted to completely rewrite, but I resisted the urge to
|
239
|
+
burn it all down and start again.</p>
|
240
|
+
|
241
|
+
<p>When I was close to being caught up on the backlog of issues and pull requests,
|
242
|
+
I started thinking about releasing version 1.0, and I knew I wanted to create a
|
243
|
+
website for the project. I worked with <a href="http://danielariza.com">Daniel Ariza</a> to make it happen. I
|
244
|
+
ripped apart the README and rewrote just about all the sections.</p>
|
245
|
+
|
246
|
+
<p>There was an open issue on the project about renaming the Gem and I knew that
|
247
|
+
launching the website and releasing 1.0 would be the perfect opportunity, so I
|
248
|
+
went for it. There was a suggestion to change the name to Feedzilla, but since
|
249
|
+
that is already a thing, I went with Feedjira. I bought the domain and setup an
|
250
|
+
organization by that name on GitHub.</p>
|
251
|
+
|
252
|
+
<p>With those things in place, I needed to actually update the code for these
|
253
|
+
changes. I wanted to make this transition as easy as possible and devised a
|
254
|
+
simple way to use <a href="/versions.html">three versions</a> to make the jump to 1.0.</p>
|
255
|
+
|
256
|
+
<p>For most users, upgrading to 1.0 should be a breeze, but I have an <a href="/upgrading.html">upgrade
|
257
|
+
page</a> to help with a couple details. If you have any trouble upgrading,
|
258
|
+
please let me know by <a href="https://github.com/feedjira/feedjira/issues">opening an issue</a>.</p>
|
259
|
+
|
260
|
+
<p>There are still lots of things I&rsquo;d like to do with this Gem. I mentioned seeing
|
261
|
+
things that I wanted to completely rewrite, so that&rsquo;ll be something that I work
|
262
|
+
on for a 2.0 release, but that&rsquo;s a ways off. I&rsquo;d like to officially support
|
263
|
+
JRuby. Many people use Feedjira with Rails, so a separate project that helps
|
264
|
+
those users get up and running quickly seems to have value.</p>
|
265
|
+
|
266
|
+
<p>The list goes on.</p>
|
267
|
+
|
268
|
+
<p>I do have a request before I finish this thing: I&rsquo;d like to hear from users that
|
269
|
+
have apps in production using Feedjira. If you&rsquo;re using Feedjira for a
|
270
|
+
commercial app, please <a href="feedjira@gmail.com">email me</a>!</p>
|
271
|
+
|
272
|
+
<p>Thanks to everyone who has helped me accomplish this, but especially <a href="http://www.pauldix.net">Paul
|
273
|
+
Dix</a> for creating such a fun project to work on, <a href="http://danielariza.com">Daniel Ariza</a> for a
|
274
|
+
badass website design and the many people who opened issues or sent pull
|
275
|
+
requests. Open source is fun to work on because of people like you!! &lt;3 &lt;3 &lt;3</p>
|
276
|
+
</content>
|
277
|
+
</entry>
|
278
|
+
</feed>
|
279
|
+
http_version:
|
280
|
+
recorded_at: Mon, 31 Oct 2016 02:29:13 GMT
|
281
|
+
recorded_with: VCR 3.0.3
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# Feedjira::Configuration
|
2
|
+
module Feedjira
|
3
|
+
# Provides global configuration options for Feedjira
|
4
|
+
#
|
5
|
+
# @example Set configuration options using a block
|
6
|
+
# Feedjira.configure do |config|
|
7
|
+
# config.strip_whitespace = true
|
8
|
+
# end
|
9
|
+
module Configuration
|
10
|
+
attr_accessor(
|
11
|
+
:follow_redirect_limit,
|
12
|
+
:logger,
|
13
|
+
:parsers,
|
14
|
+
:request_timeout,
|
15
|
+
:strip_whitespace,
|
16
|
+
:user_agent
|
17
|
+
)
|
18
|
+
|
19
|
+
# Modify Feedjira's current configuration
|
20
|
+
#
|
21
|
+
# @yieldparam [Feedjria] config current Feedjira config
|
22
|
+
# @example
|
23
|
+
# Feedjira.configure do |config|
|
24
|
+
# config.strip_whitespace = true
|
25
|
+
# end
|
26
|
+
def configure
|
27
|
+
yield self
|
28
|
+
end
|
29
|
+
|
30
|
+
# Reset Feedjira's configuration to defaults
|
31
|
+
#
|
32
|
+
# @example
|
33
|
+
# Feedjira.reset_configuration!
|
34
|
+
def reset_configuration!
|
35
|
+
set_default_configuration
|
36
|
+
end
|
37
|
+
|
38
|
+
# @private
|
39
|
+
def self.extended(base)
|
40
|
+
base.set_default_configuration
|
41
|
+
end
|
42
|
+
|
43
|
+
# @private
|
44
|
+
def set_default_configuration
|
45
|
+
self.follow_redirect_limit = 3
|
46
|
+
self.logger = default_logger
|
47
|
+
self.parsers = default_parsers
|
48
|
+
self.request_timeout = 30
|
49
|
+
self.strip_whitespace = false
|
50
|
+
self.user_agent = "Feedjira #{Feedjira::VERSION}"
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# @private
|
56
|
+
def default_logger
|
57
|
+
Logger.new(STDOUT).tap do |logger|
|
58
|
+
logger.progname = 'Feedjira'
|
59
|
+
logger.level = Logger::WARN
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# @private
|
64
|
+
def default_parsers
|
65
|
+
[
|
66
|
+
Feedjira::Parser::RSSFeedBurner,
|
67
|
+
Feedjira::Parser::GoogleDocsAtom,
|
68
|
+
Feedjira::Parser::AtomYoutube,
|
69
|
+
Feedjira::Parser::AtomFeedBurner,
|
70
|
+
Feedjira::Parser::Atom,
|
71
|
+
Feedjira::Parser::ITunesRSS,
|
72
|
+
Feedjira::Parser::RSS
|
73
|
+
]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -2,16 +2,18 @@
|
|
2
2
|
# Ruby Cookbook by Lucas Carlson and Leonard Richardson
|
3
3
|
# Published by O'Reilly
|
4
4
|
# ISBN: 0-596-52369-6
|
5
|
+
# rubocop:disable Style/DocumentationMethod
|
5
6
|
class Date
|
6
7
|
def feed_utils_to_gm_time
|
7
8
|
feed_utils_to_time(new_offset, :gm)
|
8
9
|
end
|
9
10
|
|
10
11
|
def feed_utils_to_local_time
|
11
|
-
feed_utils_to_time(new_offset(DateTime.now.offset-offset), :local)
|
12
|
+
feed_utils_to_time(new_offset(DateTime.now.offset - offset), :local)
|
12
13
|
end
|
13
14
|
|
14
15
|
private
|
16
|
+
|
15
17
|
def feed_utils_to_time(dest, method)
|
16
18
|
Time.send(method, dest.year, dest.month, dest.day, dest.hour, dest.min,
|
17
19
|
dest.sec, dest.zone)
|