feedjira 2.0.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +15 -0
  4. data/.travis.yml +31 -12
  5. data/CHANGELOG.md +34 -1
  6. data/Dangerfile +1 -0
  7. data/Gemfile +2 -1
  8. data/LICENSE +1 -1
  9. data/README.md +210 -7
  10. data/Rakefile +11 -1
  11. data/feedjira.gemspec +17 -14
  12. data/fixtures/vcr_cassettes/fetch_failure.yml +62 -0
  13. data/fixtures/vcr_cassettes/parse_error.yml +222 -0
  14. data/fixtures/vcr_cassettes/success.yml +281 -0
  15. data/lib/feedjira/configuration.rb +76 -0
  16. data/lib/feedjira/core_ext/date.rb +3 -1
  17. data/lib/feedjira/core_ext/string.rb +2 -1
  18. data/lib/feedjira/core_ext/time.rb +24 -17
  19. data/lib/feedjira/core_ext.rb +3 -3
  20. data/lib/feedjira/date_time_utilities/date_time_epoch_parser.rb +13 -0
  21. data/lib/feedjira/date_time_utilities/date_time_language_parser.rb +24 -0
  22. data/lib/feedjira/date_time_utilities/date_time_pattern_parser.rb +34 -0
  23. data/lib/feedjira/date_time_utilities.rb +32 -0
  24. data/lib/feedjira/feed.rb +89 -62
  25. data/lib/feedjira/feed_entry_utilities.rb +20 -19
  26. data/lib/feedjira/feed_utilities.rb +37 -22
  27. data/lib/feedjira/parser/atom.rb +10 -8
  28. data/lib/feedjira/parser/atom_entry.rb +11 -13
  29. data/lib/feedjira/parser/atom_feed_burner.rb +27 -10
  30. data/lib/feedjira/parser/atom_feed_burner_entry.rb +12 -14
  31. data/lib/feedjira/parser/atom_youtube.rb +21 -0
  32. data/lib/feedjira/parser/atom_youtube_entry.rb +30 -0
  33. data/lib/feedjira/parser/google_docs_atom.rb +8 -7
  34. data/lib/feedjira/parser/google_docs_atom_entry.rb +13 -11
  35. data/lib/feedjira/parser/itunes_rss.rb +41 -22
  36. data/lib/feedjira/parser/itunes_rss_category.rb +39 -0
  37. data/lib/feedjira/parser/itunes_rss_item.rb +32 -20
  38. data/lib/feedjira/parser/itunes_rss_owner.rb +4 -4
  39. data/lib/feedjira/parser/podlove_chapter.rb +22 -0
  40. data/lib/feedjira/parser/rss.rb +11 -8
  41. data/lib/feedjira/parser/rss_entry.rb +17 -21
  42. data/lib/feedjira/parser/rss_feed_burner.rb +5 -6
  43. data/lib/feedjira/parser/rss_feed_burner_entry.rb +24 -28
  44. data/lib/feedjira/parser/rss_image.rb +15 -0
  45. data/lib/feedjira/parser.rb +1 -1
  46. data/lib/feedjira/preprocessor.rb +4 -2
  47. data/lib/feedjira/version.rb +1 -1
  48. data/lib/feedjira.rb +15 -0
  49. data/spec/feedjira/configuration_spec.rb +25 -0
  50. data/spec/feedjira/date_time_utilities_spec.rb +47 -0
  51. data/spec/feedjira/feed_entry_utilities_spec.rb +23 -19
  52. data/spec/feedjira/feed_spec.rb +140 -75
  53. data/spec/feedjira/feed_utilities_spec.rb +83 -63
  54. data/spec/feedjira/parser/atom_entry_spec.rb +54 -34
  55. data/spec/feedjira/parser/atom_feed_burner_entry_spec.rb +27 -20
  56. data/spec/feedjira/parser/atom_feed_burner_spec.rb +87 -30
  57. data/spec/feedjira/parser/atom_spec.rb +50 -48
  58. data/spec/feedjira/parser/atom_youtube_entry_spec.rb +86 -0
  59. data/spec/feedjira/parser/atom_youtube_spec.rb +43 -0
  60. data/spec/feedjira/parser/google_docs_atom_entry_spec.rb +5 -4
  61. data/spec/feedjira/parser/google_docs_atom_spec.rb +6 -6
  62. data/spec/feedjira/parser/itunes_rss_item_spec.rb +49 -29
  63. data/spec/feedjira/parser/itunes_rss_owner_spec.rb +10 -9
  64. data/spec/feedjira/parser/itunes_rss_spec.rb +87 -30
  65. data/spec/feedjira/parser/podlove_chapter_spec.rb +37 -0
  66. data/spec/feedjira/parser/rss_entry_spec.rb +50 -33
  67. data/spec/feedjira/parser/rss_feed_burner_entry_spec.rb +55 -33
  68. data/spec/feedjira/parser/rss_feed_burner_spec.rb +31 -26
  69. data/spec/feedjira/parser/rss_spec.rb +56 -24
  70. data/spec/feedjira/preprocessor_spec.rb +11 -3
  71. data/spec/sample_feeds/AmazonWebServicesBlog.xml +797 -797
  72. data/spec/sample_feeds/AtomEscapedHTMLInPreTag.xml +13 -0
  73. data/spec/sample_feeds/CRE.xml +5849 -0
  74. data/spec/sample_feeds/FeedBurnerXHTML.xml +400 -400
  75. data/spec/sample_feeds/GiantRobotsSmashingIntoOtherGiantRobots.xml +682 -0
  76. data/spec/sample_feeds/ITunesWithSingleQuotedAttributes.xml +67 -0
  77. data/spec/sample_feeds/InvalidDateFormat.xml +20 -0
  78. data/spec/sample_feeds/PaulDixExplainsNothing.xml +175 -175
  79. data/spec/sample_feeds/PaulDixExplainsNothingAlternate.xml +175 -175
  80. data/spec/sample_feeds/PaulDixExplainsNothingFirstEntryContent.xml +16 -16
  81. data/spec/sample_feeds/PaulDixExplainsNothingWFW.xml +174 -174
  82. data/spec/sample_feeds/TenderLovemaking.xml +12 -2
  83. data/spec/sample_feeds/TrotterCashionHome.xml +611 -611
  84. data/spec/sample_feeds/TypePadNews.xml +368 -368
  85. data/spec/sample_feeds/itunes.xml +31 -2
  86. data/spec/sample_feeds/pet_atom.xml +229 -229
  87. data/spec/sample_feeds/youtube_atom.xml +395 -0
  88. data/spec/sample_feeds.rb +31 -21
  89. data/spec/spec_helper.rb +6 -0
  90. 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">&#39;feedjira&#39;</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">&quot;http://feedjira.com/blog/feed.xml&quot;</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"># =&gt; #&lt;Feedjira::Parser::Atom...&gt;</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"># =&gt; &quot;Feedjira Blog&quot;</span>
88
+ <span class="n">feed</span><span class="nf">.url</span>
89
+ <span class="c1"># =&gt; &quot;http://feedjira.com/blog&quot;</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"># =&gt; [&lt;Feedjira::Feed::Entry ...&gt;, &lt;Feedjira::Feed::Entry ...&gt;, ...]</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"># =&gt; &quot;Announcing verison 1.0&quot;</span>
97
+ <span class="n">entry</span><span class="nf">.url</span>
98
+ <span class="c1"># =&gt; &quot;http://feedjira.com/blog/2014-02-12-announcing-version-10.html&quot;</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"># =&gt; &quot;Announcing verison 1.0&quot;</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">&#39;generator&#39;</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">&quot;http://www.pauldix.net/atom.xml&quot;</span><span class="p">)</span><span class="nf">.generator</span> <span class="c1"># =&gt; &#39;TypePad&#39;</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">&#39;geo:lat&#39;</span><span class="p">,</span> <span class="ss">:as</span> <span class="o">=&gt;</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">&quot;http://www.earthpublisher.com/georss.php&quot;</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">&quot;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">&quot;
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">&#39;lib/feedzirra/parser/rss_entry&#39;</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">&#39;geo:lat&#39;</span><span class="p">,</span> <span class="ss">:as</span> <span class="o">=&gt;</span> <span class="ss">:lat</span>
154
+ <span class="n">element</span> <span class="s1">&#39;geo:long&#39;</span><span class="p">,</span> <span class="ss">:as</span> <span class="o">=&gt;</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">&quot;http://www.earthpublisher.com/georss.php&quot;</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">&quot;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">&quot;</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&rsquo;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&rsquo;s an
177
+ open-source project that&rsquo;s easy to deploy to any host, there&rsquo;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&rsquo;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&rsquo;s free to start and also has a paid premium version. There&rsquo;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&rsquo;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&rsquo;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">&lt;p&gt;About a year ago, I took Feedjira to &lt;a href="http://feedjira.com/blog/2014/03/17/feedjira-goes-one-point-oh.html"&gt;version 1.0&lt;/a&gt; and today I&amp;rsquo;m releasing
59
+ version 2.0. Not much has changed actually - the biggest difference is that
60
+ &lt;code&gt;curb&lt;/code&gt; has been replaced with &lt;code&gt;faraday&lt;/code&gt;. For many users, upgrading to version
61
+ 2.0 won&amp;rsquo;t require anything more than a &lt;code&gt;bundle update feedjira&lt;/code&gt;.&lt;/p&gt;
62
+
63
+ &lt;p&gt;The other big change is that the &lt;code&gt;Feedjira#update&lt;/code&gt; method was removed. It was
64
+ unreliable and mostly just caused issues. To read more about why this was
65
+ removed, check out &lt;a href="https://github.com/feedjira/feedjira/issues/218#issuecomment-40282091"&gt;this comment&lt;/a&gt; on a GitHub issue that was opened
66
+ about it not working as expected.&lt;/p&gt;
67
+
68
+ &lt;p&gt;I&amp;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.&lt;/p&gt;
71
+
72
+ &lt;p&gt;I hope you like version 2.0 - feel free to hit me up &lt;a href="https://twitter.com/feedjira"&gt;on Twitter&lt;/a&gt; or if
73
+ you have any trouble, open a &lt;a href="https://github.com/feedjira/feedjira/issues"&gt;GitHub issue&lt;/a&gt; and I&amp;rsquo;ll give you a hand.&lt;/p&gt;
74
+
75
+ &lt;p&gt;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!&lt;/p&gt;
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">&lt;p&gt;TLDR: development of version 2.0 is being done on the &lt;a href="https://github.com/feedjira/feedjira/tree/two-point-oh"&gt;two-point-oh branch&lt;/a&gt;
89
+ and a &lt;a href="https://github.com/feedjira/feedjira/issues/221"&gt;GitHub issue&lt;/a&gt; is open for you to give feedback on its direction.&lt;/p&gt;
90
+
91
+ &lt;p&gt;I&amp;rsquo;ve starting work on a rewrite for Feedjira and I wanted to try using a &lt;a href="https://github.com/feedjira/feedjira/issues/221"&gt;GitHub
92
+ issue&lt;/a&gt; to discuss what I&amp;rsquo;d like to see in the new version. I&amp;rsquo;m very
93
+ interested in what users think, so please chime in!!&lt;/p&gt;
94
+
95
+ &lt;p&gt;In no particular order, here are some design goals for the new version:&lt;/p&gt;
96
+
97
+ &lt;h2&gt;Change HTTP Library&lt;/h2&gt;
98
+
99
+ &lt;p&gt;This gem depends on &lt;a href="https://github.com/taf2/curb"&gt;curb&lt;/a&gt;, but I&amp;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 &lt;a href="https://github.com/lostisland/faraday"&gt;Faraday&lt;/a&gt;, so that&amp;rsquo;s what I&amp;rsquo;m using at the moment.&lt;/p&gt;
102
+
103
+ &lt;h2&gt;Forget Concurrency&lt;/h2&gt;
104
+
105
+ &lt;p&gt;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&amp;rsquo;t think
107
+ it&amp;rsquo;s reality. I think what&amp;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.&lt;/p&gt;
110
+
111
+ &lt;h2&gt;More Objects&lt;/h2&gt;
112
+
113
+ &lt;p&gt;Feedjira has a dirty little secret and it&amp;rsquo;s the &lt;code&gt;Feedjira::Feed&lt;/code&gt; class. If you
114
+ open that sucker up, you&amp;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 &lt;a href="http://en.wikipedia.org/wiki/Single_responsibility_principle"&gt;SRP&lt;/a&gt; off in the corner crying, its a mess to
117
+ test. I&amp;rsquo;d like to break this down into smaller objects that get instantiated and
118
+ passed around in normal OO fashion.&lt;/p&gt;
119
+
120
+ &lt;h2&gt;Fewer Parsers&lt;/h2&gt;
121
+
122
+ &lt;p&gt;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&amp;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.&lt;/p&gt;
126
+
127
+ &lt;h2&gt;Custom Parser Project&lt;/h2&gt;
128
+
129
+ &lt;p&gt;With version 1.2, I was able to spin off the benchmarks into &lt;a href="https://github.com/feedjira/feedjira-benchmarks"&gt;their own
130
+ project&lt;/a&gt; and I was very happy with how it turned out - I&amp;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.&lt;/p&gt;
135
+
136
+ &lt;h2&gt;Raise Exceptions Instead of Callbacks&lt;/h2&gt;
137
+
138
+ &lt;p&gt;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.&lt;/p&gt;
143
+
144
+ &lt;h2&gt;Feed Updating is Business Logic&lt;/h2&gt;
145
+
146
+ &lt;p&gt;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
+ &lt;a href="https://github.com/feedjira/feedjira/issues/218"&gt;this discussion&lt;/a&gt; for more, but needless to say, I&amp;rsquo;d like to see this entire
150
+ feature set removed.&lt;/p&gt;
151
+
152
+ &lt;h2&gt;Configuration&lt;/h2&gt;
153
+
154
+ &lt;p&gt;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.&lt;/p&gt;
157
+
158
+ &lt;h2&gt;Feedback Appreciated&lt;/h2&gt;
159
+
160
+ &lt;p&gt;Do you have any other ideas to make Feedjira better? Please check out the
161
+ &lt;a href="https://github.com/feedjira/feedjira/issues/221"&gt;GitHub issue&lt;/a&gt; and share what you&amp;rsquo;re thinking. I&amp;rsquo;m open to any feedback, so
162
+ if I just threw your favorite feature on the chopping block, please tell me!&lt;/p&gt;
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">&lt;p&gt;With the release of version 1.2.0, the benchmarks for Feedjira have been moved
175
+ to a separate project: &lt;a href="https://github.com/feedjira/feedjira-benchmarks"&gt;https://github.com/feedjira/feedjira-benchmarks&lt;/a&gt;.&lt;/p&gt;
176
+
177
+ &lt;p&gt;What&amp;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 &lt;a href="/benchmarks.html"&gt;Benchmarks page&lt;/a&gt; on this site so please check that out.&lt;/p&gt;
180
+
181
+ &lt;p&gt;One benchmark that I didn&amp;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&amp;rsquo;t feel like it was scientific enough.&lt;/p&gt;
184
+
185
+ &lt;p&gt;In its place I&amp;rsquo;ve added a benchmark for parsing speed that&amp;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.&lt;/p&gt;
190
+
191
+ &lt;p&gt;For the charts, I ended up learning some &lt;a href="http://www.r-project.org/"&gt;R&lt;/a&gt; so that I could have a little
192
+ more control.&lt;/p&gt;
193
+
194
+ &lt;p&gt;Benchmarks are really only valuable if they can be reproduced by others, so I&amp;rsquo;ve
195
+ written up instructions in the README for setting things up and running them. If
196
+ you&amp;rsquo;re interested, take a look and try running them yourself!&lt;/p&gt;
197
+
198
+ &lt;p&gt;I&amp;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
+ (&lt;a href="https://twitter.com/feedjira"&gt;@feedjira&lt;/a&gt;) or &lt;a href="https://github.com/feedjira/feedjira-benchmarks/issues"&gt;open an issue&lt;/a&gt; on the project&amp;rsquo;s repo.&lt;/p&gt;
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">&lt;p&gt;Last fall, I asked &lt;a href="http://www.pauldix.net"&gt;Paul Dix&lt;/a&gt; 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&amp;rsquo;t have time to work
216
+ on it anymore and so I should feel free to do whatever I thought was best.&lt;/p&gt;
217
+
218
+ &lt;p&gt;Score!&lt;/p&gt;
219
+
220
+ &lt;p&gt;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&amp;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.&lt;/p&gt;
225
+
226
+ &lt;p&gt;I was pleasantly surprised by the nice way many people responded and we got to
227
+ work addressing their questions and issues.&lt;/p&gt;
228
+
229
+ &lt;p&gt;As I was working through issues and pull requests, I kept &lt;a href="http://semver.org"&gt;SemVer&lt;/a&gt; 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.&lt;/p&gt;
235
+
236
+ &lt;p&gt;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.&lt;/p&gt;
240
+
241
+ &lt;p&gt;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 &lt;a href="http://danielariza.com"&gt;Daniel Ariza&lt;/a&gt; to make it happen. I
244
+ ripped apart the README and rewrote just about all the sections.&lt;/p&gt;
245
+
246
+ &lt;p&gt;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.&lt;/p&gt;
251
+
252
+ &lt;p&gt;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 &lt;a href="/versions.html"&gt;three versions&lt;/a&gt; to make the jump to 1.0.&lt;/p&gt;
255
+
256
+ &lt;p&gt;For most users, upgrading to 1.0 should be a breeze, but I have an &lt;a href="/upgrading.html"&gt;upgrade
257
+ page&lt;/a&gt; to help with a couple details. If you have any trouble upgrading,
258
+ please let me know by &lt;a href="https://github.com/feedjira/feedjira/issues"&gt;opening an issue&lt;/a&gt;.&lt;/p&gt;
259
+
260
+ &lt;p&gt;There are still lots of things I&amp;rsquo;d like to do with this Gem. I mentioned seeing
261
+ things that I wanted to completely rewrite, so that&amp;rsquo;ll be something that I work
262
+ on for a 2.0 release, but that&amp;rsquo;s a ways off. I&amp;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.&lt;/p&gt;
265
+
266
+ &lt;p&gt;The list goes on.&lt;/p&gt;
267
+
268
+ &lt;p&gt;I do have a request before I finish this thing: I&amp;rsquo;d like to hear from users that
269
+ have apps in production using Feedjira. If you&amp;rsquo;re using Feedjira for a
270
+ commercial app, please &lt;a href="feedjira@gmail.com"&gt;email me&lt;/a&gt;!&lt;/p&gt;
271
+
272
+ &lt;p&gt;Thanks to everyone who has helped me accomplish this, but especially &lt;a href="http://www.pauldix.net"&gt;Paul
273
+ Dix&lt;/a&gt; for creating such a fun project to work on, &lt;a href="http://danielariza.com"&gt;Daniel Ariza&lt;/a&gt; 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!! &amp;lt;3 &amp;lt;3 &amp;lt;3&lt;/p&gt;
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)
@@ -1,6 +1,7 @@
1
+ # rubocop:disable Style/DocumentationMethod Style/Documentation
1
2
  class String
2
3
  def sanitize!
3
- self.replace(sanitize)
4
+ replace(sanitize)
4
5
  end
5
6
 
6
7
  def sanitize