feedjira 2.2.0 → 3.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/feed-parsing.md +15 -0
  3. data/.rubocop.yml +32 -8
  4. data/.rubocop_todo.yml +11 -0
  5. data/.travis.yml +3 -7
  6. data/CHANGELOG.md +18 -9
  7. data/CODE_OF_CONDUCT.md +74 -0
  8. data/Gemfile +8 -5
  9. data/README.md +46 -99
  10. data/Rakefile +8 -6
  11. data/feedjira.gemspec +31 -20
  12. data/lib/feedjira.rb +75 -41
  13. data/lib/feedjira/atom_entry_utilities.rb +51 -0
  14. data/lib/feedjira/configuration.rb +8 -10
  15. data/lib/feedjira/core_ext.rb +5 -3
  16. data/lib/feedjira/core_ext/date.rb +2 -1
  17. data/lib/feedjira/core_ext/string.rb +2 -1
  18. data/lib/feedjira/core_ext/time.rb +12 -12
  19. data/lib/feedjira/date_time_utilities.rb +8 -10
  20. data/lib/feedjira/date_time_utilities/date_time_epoch_parser.rb +3 -2
  21. data/lib/feedjira/date_time_utilities/date_time_language_parser.rb +4 -4
  22. data/lib/feedjira/date_time_utilities/date_time_pattern_parser.rb +11 -15
  23. data/lib/feedjira/feed.rb +12 -82
  24. data/lib/feedjira/feed_entry_utilities.rb +14 -7
  25. data/lib/feedjira/feed_utilities.rb +5 -4
  26. data/lib/feedjira/parser.rb +6 -1
  27. data/lib/feedjira/parser/atom.rb +6 -5
  28. data/lib/feedjira/parser/atom_entry.rb +4 -21
  29. data/lib/feedjira/parser/atom_feed_burner.rb +7 -6
  30. data/lib/feedjira/parser/atom_feed_burner_entry.rb +7 -18
  31. data/lib/feedjira/parser/atom_google_alerts.rb +26 -0
  32. data/lib/feedjira/parser/atom_google_alerts_entry.rb +21 -0
  33. data/lib/feedjira/parser/atom_youtube.rb +4 -3
  34. data/lib/feedjira/parser/atom_youtube_entry.rb +9 -8
  35. data/lib/feedjira/parser/globally_unique_identifier.rb +21 -0
  36. data/lib/feedjira/parser/google_docs_atom.rb +6 -6
  37. data/lib/feedjira/parser/google_docs_atom_entry.rb +3 -19
  38. data/lib/feedjira/parser/itunes_rss.rb +4 -3
  39. data/lib/feedjira/parser/itunes_rss_category.rb +6 -5
  40. data/lib/feedjira/parser/itunes_rss_item.rb +5 -8
  41. data/lib/feedjira/parser/itunes_rss_owner.rb +2 -1
  42. data/lib/feedjira/parser/json_feed.rb +41 -0
  43. data/lib/feedjira/parser/json_feed_item.rb +57 -0
  44. data/lib/feedjira/parser/podlove_chapter.rb +4 -3
  45. data/lib/feedjira/parser/rss.rb +5 -3
  46. data/lib/feedjira/parser/rss_entry.rb +3 -24
  47. data/lib/feedjira/parser/rss_feed_burner.rb +4 -3
  48. data/lib/feedjira/parser/rss_feed_burner_entry.rb +6 -26
  49. data/lib/feedjira/parser/rss_image.rb +2 -0
  50. data/lib/feedjira/preprocessor.rb +4 -4
  51. data/lib/feedjira/rss_entry_utilities.rb +53 -0
  52. data/lib/feedjira/version.rb +3 -1
  53. data/spec/feedjira/configuration_spec.rb +11 -16
  54. data/spec/feedjira/date_time_utilities_spec.rb +22 -20
  55. data/spec/feedjira/feed_entry_utilities_spec.rb +20 -18
  56. data/spec/feedjira/feed_spec.rb +17 -229
  57. data/spec/feedjira/feed_utilities_spec.rb +75 -73
  58. data/spec/feedjira/parser/atom_entry_spec.rb +41 -38
  59. data/spec/feedjira/parser/atom_feed_burner_entry_spec.rb +22 -20
  60. data/spec/feedjira/parser/atom_feed_burner_spec.rb +122 -118
  61. data/spec/feedjira/parser/atom_google_alerts_entry_spec.rb +34 -0
  62. data/spec/feedjira/parser/atom_google_alerts_spec.rb +62 -0
  63. data/spec/feedjira/parser/atom_spec.rb +83 -77
  64. data/spec/feedjira/parser/atom_youtube_entry_spec.rb +41 -39
  65. data/spec/feedjira/parser/atom_youtube_spec.rb +21 -19
  66. data/spec/feedjira/parser/google_docs_atom_entry_spec.rb +10 -8
  67. data/spec/feedjira/parser/google_docs_atom_spec.rb +25 -21
  68. data/spec/feedjira/parser/itunes_rss_item_spec.rb +39 -37
  69. data/spec/feedjira/parser/itunes_rss_owner_spec.rb +7 -5
  70. data/spec/feedjira/parser/itunes_rss_spec.rb +120 -116
  71. data/spec/feedjira/parser/json_feed_item_spec.rb +81 -0
  72. data/spec/feedjira/parser/json_feed_spec.rb +55 -0
  73. data/spec/feedjira/parser/podlove_chapter_spec.rb +14 -12
  74. data/spec/feedjira/parser/rss_entry_spec.rb +56 -34
  75. data/spec/feedjira/parser/rss_feed_burner_entry_spec.rb +36 -34
  76. data/spec/feedjira/parser/rss_feed_burner_spec.rb +49 -45
  77. data/spec/feedjira/parser/rss_spec.rb +38 -36
  78. data/spec/feedjira/preprocessor_spec.rb +9 -7
  79. data/spec/feedjira_spec.rb +166 -0
  80. data/spec/sample_feeds.rb +32 -29
  81. data/spec/sample_feeds/HuffPostCanada.xml +279 -0
  82. data/spec/sample_feeds/Permalinks.xml +22 -0
  83. data/spec/sample_feeds/a10.xml +72 -0
  84. data/spec/sample_feeds/google_alerts_atom.xml +1 -0
  85. data/spec/sample_feeds/json_feed.json +156 -0
  86. data/spec/spec_helper.rb +7 -5
  87. metadata +59 -70
  88. data/Dangerfile +0 -1
  89. data/fixtures/vcr_cassettes/fetch_failure.yml +0 -62
  90. data/fixtures/vcr_cassettes/parse_error.yml +0 -222
  91. data/fixtures/vcr_cassettes/success.yml +0 -281
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3b8cec1f08ed12a497f98c7e4b622f8ab06b688a75e968175dd985ad93cfd4bd
4
- data.tar.gz: 1015179ce20e86b0a02253411e02e9b78bf0294c8f18a8e2fba3fc92c5c04b01
3
+ metadata.gz: 0146f6f9717aa2550c7c3ee8ad10bdc2d1670b5a877979ec3b4b92acc8556a01
4
+ data.tar.gz: 336327b583cbda573b23b35c6c7e43633fb832ff8054be34126340ad8c8bff3a
5
5
  SHA512:
6
- metadata.gz: ba84e098bed14b11cf07a816500ff853e3337039bce117abf1bedc17d28d5bc3072d39bb43f747580f8c48de57417df23284fb0d71eb1d79d9f35896ae5c2f5c
7
- data.tar.gz: 8ab31a4eb8427f70d5f26f817c3296a5ab5ea650b1885d4ac5f9518cb7c85fc852ccd29923b29c2f3300f67c6efa558de44a2f4290314ba9b206fe428b6ca13e
6
+ metadata.gz: db78dc79cc38419c6f81a0336f4794d8f744b2cab24786c3c9ac9b92f2b72f2c5db190a982fcfb16de6ccec1b358309c76e3c165ec16141b8816736774339662
7
+ data.tar.gz: b9a4466a3371c7d1fb837cdc8ffcced9af1a830810b47113cd2a790c8c1145c0aae1a9faad91b642bec50a12469917ead27a48fc798e257e2017d736ef0e5101
@@ -0,0 +1,15 @@
1
+ ---
2
+ name: Feed Parsing
3
+ about: Your feed is parsing incorrectly, or you have a feed type that is not supported
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ ### Steps to reproduce
11
+ <!-- (Guidelines for creating a bug report are [available
12
+ here](https://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html#creating-a-bug-report)) -->
13
+
14
+ ### Example feed URL
15
+ <!-- Tell us what should happen -->
@@ -1,15 +1,39 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
1
3
  AllCops:
2
- TargetRubyVersion: 2.1
4
+ TargetRubyVersion: 2.5
5
+ NewCops: enable
6
+
3
7
 
4
- Style/Documentation:
5
- Enabled: true
8
+ Gemspec/RequiredRubyVersion:
6
9
  Exclude:
7
- - 'spec/**/*'
10
+ - 'feedjira.gemspec'
11
+
12
+ # Offense count: 3
13
+ # Configuration parameters: IgnoredMethods.
14
+ Metrics/AbcSize:
15
+ Max: 24
16
+
17
+ # Offense count: 33
18
+ # Configuration parameters: CountComments, CountAsOne, ExcludedMethods.
19
+ # ExcludedMethods: refine
20
+ Metrics/BlockLength:
21
+ Max: 235
8
22
 
9
- Style/DocumentationMethod:
10
- Enabled: true
23
+ # Offense count: 7
24
+ # Configuration parameters: CountComments, CountAsOne, ExcludedMethods.
25
+ Metrics/MethodLength:
26
+ Max: 25
27
+
28
+ Layout/LineLength:
11
29
  Exclude:
12
- - 'spec/**/*'
30
+ - 'spec/**/*.rb'
31
+
32
+ Style/AsciiComments:
33
+ Enabled: false
13
34
 
14
- Style/ClassAndModuleChildren:
35
+ Style/IfUnlessModifier:
15
36
  Enabled: false
37
+
38
+ Style/StringLiterals:
39
+ EnforcedStyle: double_quotes
@@ -0,0 +1,11 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2020-09-02 20:02:06 UTC using RuboCop version 0.90.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 20
10
+ Style/Documentation:
11
+ Enabled: false
@@ -3,9 +3,9 @@ language: ruby
3
3
  cache: bundler
4
4
 
5
5
  rvm:
6
- - 2.1
7
- - 2.2
8
- - 2.3
6
+ - 2.5
7
+ - 2.6
8
+ - 2.7
9
9
  - jruby-9
10
10
  - ruby-head
11
11
 
@@ -28,10 +28,6 @@ before_install:
28
28
 
29
29
  script:
30
30
  - bundle exec rake
31
- - bundle exec danger
32
31
 
33
32
  notifications:
34
33
  email: false
35
- webhooks:
36
- urls:
37
- secure: XjoUz2rPXFHnitw//jN4qA92jq7bH19iOI/5KnuptLzz5HrWq1VAXxAr/Fh0KxYZT29G/9i5szaHX1QacfO7he4xa2tZKudRL70Dw3KRLgqLi70G6kFuZYlh+MgMHZy6KwZ/4/250wO31fpv24PCb2M56iTsev2g2uporeobO0Q=
@@ -1,19 +1,28 @@
1
1
  # Feedjira Changelog
2
2
 
3
- ## 2.2.0
3
+ ## Unreleased
4
4
 
5
- * General
6
- * Backport support for parsing new iTunes podcasting tags
7
-
8
- ## 2.1.4
5
+ * Enhancements
6
+ * Add support for the `a10` namespace used in RSS 2.0 feeds generated by .NET applications. Currently `a10:link`, `a10:updated`, `a10:content` and `a10:name` are supported. [#440][] (@knu)
9
7
 
10
- * Bug fixes
11
- * Prevent errors when a feed has multiple dates and some are unparseable
8
+ ## 3.1.0
12
9
 
13
- ## 2.1.3
10
+ * Breaking Changes
11
+ * `title` of Atom entry classes always return a plain text even in case the entry has a title of the HTML or XML type. [#423][] (@knu)
14
12
 
15
13
  * Enhancements
16
- * No longer log date parsing errors as warnings, they are now debug messages
14
+ * `raw_title` and `title_type` are added to Atom entry classes. [#423][] (@knu)
15
+ * AtomGoogleAlerts is now a supported parser [#424][] (@knu)
16
+
17
+ ## 3.0.0
18
+
19
+ * Breaking Changes
20
+ * `Feedjira::Feed.parse` has moved to `Feedjira.parse`
21
+ * `Feedjira::Feed.fetch_and_parse` has been removed. See README examples for
22
+ how to request XML and parse.
23
+
24
+ * General
25
+ * Drop support for Ruby 2.1
17
26
 
18
27
  ## 2.1.1
19
28
 
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at mikeastock@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile CHANGED
@@ -1,11 +1,14 @@
1
- source 'https://rubygems.org/'
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org/"
2
4
 
3
5
  gemspec
4
6
 
5
- gem 'pry'
7
+ gem "pry"
8
+ gem "rubocop", "~> 0.90"
6
9
 
7
10
  group :test do
8
- gem 'oga'
9
- gem 'ox', platforms: [:mri, :rbx]
10
- gem 'rake'
11
+ gem "oga"
12
+ gem "ox", platforms: %i[mri rbx]
13
+ gem "rake"
11
14
  end
data/README.md CHANGED
@@ -9,96 +9,34 @@
9
9
  [gitter-badge]: https://badges.gitter.im/feedjira/feedjira.svg
10
10
  [gitter]: https://gitter.im/feedjira/feedjira?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
11
11
 
12
- Feedjira (formerly Feedzirra) is a Ruby library designed to fetch and parse
13
- feeds as quickly as possible.
12
+ Feedjira is a Ruby library designed to parse feeds.
14
13
 
15
- ## Getting Started
14
+ ## Installation
16
15
 
17
- Feedjira is tested with Ruby version 1.9.3 and 2.x so like any Ruby gem, the
18
- first step is to install the gem:
19
-
20
- ```
21
- $ gem install feedjira
22
- ```
23
-
24
- Or add it to your Gemfile:
16
+ Add this line to your application's Gemfile:
25
17
 
26
18
  ```ruby
27
19
  gem "feedjira"
28
20
  ```
29
21
 
30
- ## Fetching and Parsing
31
-
32
- For many users, the `fetch_and_parse` method is what they use Feedjira for. This
33
- method takes a url and returns a Parser object:
34
-
35
- ```ruby
36
- url = "http://feedjira.com/blog/feed.xml"
37
- feed = Feedjira::Feed.fetch_and_parse(url)
38
- # => #<Feedjira::Parser::Atom...>
39
- ```
40
-
41
- These feed objects have both the meta data for a feed and an `entries`
42
- collection that contains all the entries that were found:
43
-
44
- ```ruby
45
- feed.title
46
- # => "Feedjira Blog"
47
- feed.url
48
- # => "http://feedjira.com/blog"
49
- feed.entries # returns an array of Entry objects
50
- # => [<Feedjira::Feed::Entry ...>, <Feedjira::Feed::Entry ...>, ...]
51
- ```
52
-
53
- These entry objects contain the data parsed from the feed XML:
54
-
55
- ```ruby
56
- entry = feed.entries.first
57
- entry.title
58
- # => "Announcing verison 1.0"
59
- entry.url
60
- # => "http://feedjira.com/blog/2014-02-12-announcing-version-10.html"
61
- ```
62
-
63
- ## Just Parsing
22
+ ## Parsing
64
23
 
65
- The parsing functionality of Feedjira has been exposed so that it can be used in
66
- isolation:
24
+ An example of parsing a feed with Feedjira:
67
25
 
68
26
  ```ruby
69
- xml = Faraday.get(url).body
70
- feed = Feedjira::Feed.parse xml
27
+ xml = HTTParty.get(url).body
28
+ feed = Feedjira.parse(xml)
71
29
  feed.entries.first.title
72
- # => "Announcing verison 1.0"
73
- ```
74
-
75
- ## Adding a feed parsing class
76
-
77
- When determining which parser to use for a given XML document, the following
78
- list of parser classes is used:
79
-
80
- * `Feedjira::Parser::RSSFeedBurner`
81
- * `Feedjira::Parser::GoogleDocsAtom`
82
- * `Feedjira::Parser::AtomFeedBurner`
83
- * `Feedjira::Parser::Atom`
84
- * `Feedjira::Parser::ITunesRSS`
85
- * `Feedjira::Parser::RSS`
86
-
87
- You can insert your own parser at the front of this stack by calling
88
- `add_feed_class`, like this:
89
-
90
- ```ruby
91
- Feedjira::Feed.add_feed_class(MyAwesomeParser)
30
+ # => "Announcing version 3.0"
92
31
  ```
93
32
 
94
- Now when you `fetch_and_parse`, `MyAwesomeParser` will be the first one to get a
95
- chance to parse the feed.
33
+ ## Specifying parser
96
34
 
97
35
  If you have the XML and just want to provide a parser class for one parse, you
98
- can specify that using `parse_with`:
36
+ can specify that using `parse` with the parser option:
99
37
 
100
38
  ```ruby
101
- Feedjira::Feed.parse_with(MyAwesomeParser, xml)
39
+ Feedjira.parse(xml, parser: MyAwesomeParser)
102
40
  ```
103
41
 
104
42
  ## Adding attributes to all feeds types / all entries types
@@ -106,7 +44,8 @@ Feedjira::Feed.parse_with(MyAwesomeParser, xml)
106
44
  ```ruby
107
45
  # Add the generator attribute to all feed types
108
46
  Feedjira::Feed.add_common_feed_element("generator")
109
- Feedjira::Feed.fetch_and_parse("http://www.pauldix.net/atom.xml").generator
47
+ xml = HTTParty.get("http://www.pauldix.net/atom.xml").body
48
+ Feedjira.parse(xml).generator
110
49
  # => "TypePad"
111
50
  ```
112
51
 
@@ -123,60 +62,59 @@ end
123
62
 
124
63
  # Fetch a feed containing GeoRss info and print them
125
64
  url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/significant_week.atom"
126
- Feedjira::Feed.fetch_and_parse(url).entries.each do |entry|
65
+ xml = HTTParty.get(url).body
66
+ Feedjira.parse(xml).entries.each do |entry|
127
67
  puts "Elevation: #{entry.elevation}"
128
68
  end
129
69
  ```
130
70
 
131
71
  ## Configuration
132
72
 
133
- #### Stripping whitespace from XML
134
-
135
- Feedjira can be configured to strip all whitespace but defaults to lstrip only:
136
-
137
- ```ruby
138
- Feedjira.configure do |config|
139
- config.strip_whitespace = true
140
- end
141
- ```
73
+ ### Parsers
142
74
 
143
- #### Follow redirect limit
75
+ #### Adding a custom parser
144
76
 
145
- For fetching feeds, the follow redirect limit defaults to 3 but can be set:
77
+ You can insert your own parser at the front of the available parser list by:
146
78
 
147
79
  ```ruby
148
80
  Feedjira.configure do |config|
149
- config.follow_redirect_limit = 5
81
+ config.parsers.unshift(MyAwesomeParser)
150
82
  end
151
83
  ```
152
84
 
153
- #### Request timeout
85
+ Now when you call `Feedjira.parse`, `MyAwesomeParser` will be the first one to
86
+ get a chance to parse the feed.
154
87
 
155
- The request timeout defaults to 30 but can be set:
88
+ #### Explicitly set all available parsers
89
+
90
+ Feedjira can be configured to use a specific set of parsers and in a specific order:
156
91
 
157
92
  ```ruby
158
93
  Feedjira.configure do |config|
159
- config.request_timeout = 45
94
+ config.parsers = [
95
+ Feedjira::Parser::ITunesRSS,
96
+ MyAwesomeParser,
97
+ Feedjira::Parser::RSS
98
+ ]
160
99
  end
161
100
  ```
162
101
 
163
- #### User agent
102
+ #### Stripping whitespace from XML
164
103
 
165
- The default user agent is "Feedjira #{Version}" but can be set:
104
+ Feedjira can be configured to strip all whitespace but defaults to lstrip only:
166
105
 
167
106
  ```ruby
168
107
  Feedjira.configure do |config|
169
- config.user_agent = "Awesome Feed Reader"
108
+ config.strip_whitespace = true
170
109
  end
171
110
  ```
172
111
 
173
- ## Testing
174
-
175
- Feedjira uses [faraday][] to perform requests, so testing Feedjira is really
176
- about [stubbing out faraday requests][stub].
112
+ ## Contributing
177
113
 
178
- [faraday]: https://github.com/lostisland/faraday
179
- [stub]: https://github.com/lostisland/faraday#using-faraday-for-testing
114
+ Bug reports and pull requests are welcome on GitHub at
115
+ https://github.com/feedjira/feedjira. This project is intended to be a safe,
116
+ welcoming space for collaboration, and contributors are expected to adhere to
117
+ the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
180
118
 
181
119
  ## Projects that use Feedjira
182
120
 
@@ -205,6 +143,12 @@ add-ons and everything in between. Here are some of them:
205
143
 
206
144
  * [Solve for All][solve]: Solve for All combines search engine and feed parsing
207
145
  while protecting your privacy. It's even extendable by the community!
146
+
147
+ * [Feedi API][feedi]: Feedi simplifies how you handle RSS, Atom, or JSON feeds. You can add and keep track of your favourite feed data with a simple and clean REST API. All entries are enriched by Machine Learning and Semantic engines.
148
+
149
+ * [Breaker][breaker]: The social podcast app
150
+
151
+ * [Huginn][huginn]: Huginn is a system for building agents that perform automated tasks for you online.
208
152
 
209
153
  [Feedbin]: https://feedbin.com/
210
154
  [Stringer]: https://github.com/swanson/stringer
@@ -212,6 +156,9 @@ add-ons and everything in between. Here are some of them:
212
156
  [Feedbunch]: https://github.com/amatriain/feedbunch
213
157
  [old]: http://theoldreader.com/
214
158
  [solve]: https://solveforall.com/
159
+ [feedi]: https://github.com/davidesantangelo/feedi
160
+ [breaker]: https://breaker.audio
161
+ [huginn]: https://github.com/huginn/huginn
215
162
 
216
163
  Note: to get your project on this list, simply [send an email](mailto:feedjira@gmail.com)
217
164
  with your project's details.