feedjira 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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