feedjira 3.2.6 → 4.0.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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/.github/copilot-instructions.md +176 -0
  3. data/.github/workflows/ruby.yml +1 -1
  4. data/.gitignore +1 -0
  5. data/.rubocop.yml +4 -2
  6. data/.rubocop_todo.yml +354 -5
  7. data/CHANGELOG.md +10 -0
  8. data/feedjira.gemspec +1 -1
  9. data/lib/feedjira/feed_entry_utilities.rb +6 -3
  10. data/lib/feedjira/feed_utilities.rb +2 -2
  11. data/lib/feedjira/parser/json_feed_item.rb +2 -2
  12. data/lib/feedjira/preprocessor.rb +1 -1
  13. data/lib/feedjira/util/parse_time.rb +52 -0
  14. data/lib/feedjira/util.rb +7 -0
  15. data/lib/feedjira/version.rb +1 -1
  16. data/lib/feedjira.rb +2 -1
  17. data/spec/feedjira/atom_entry_utilities_spec.rb +50 -0
  18. data/spec/feedjira/feed_utilities_entry_spec.rb +75 -3
  19. data/spec/feedjira/feed_utilities_spec.rb +19 -0
  20. data/spec/feedjira/parser/atom_entry_spec.rb +2 -2
  21. data/spec/feedjira/parser/atom_feed_burner_entry_spec.rb +1 -1
  22. data/spec/feedjira/parser/atom_google_alerts_entry_spec.rb +19 -4
  23. data/spec/feedjira/parser/atom_youtube_entry_spec.rb +2 -2
  24. data/spec/feedjira/parser/google_docs_atom_spec.rb +36 -0
  25. data/spec/feedjira/parser/i_tunes_rss_category_spec.rb +40 -0
  26. data/spec/feedjira/parser/i_tunes_rss_item_spec.rb +1 -1
  27. data/spec/feedjira/parser/json_feed_item_spec.rb +37 -1
  28. data/spec/feedjira/parser/podlove_chapter_spec.rb +15 -7
  29. data/spec/feedjira/parser/rss_entry_spec.rb +37 -1
  30. data/spec/feedjira/parser/rss_feed_burner_entry_spec.rb +1 -1
  31. data/spec/feedjira/{core_ext/time_spec.rb → util/parse_time_spec.rb} +11 -11
  32. data/spec/feedjira_spec.rb +10 -10
  33. data/spec/support/coverage.rb +1 -1
  34. metadata +8 -7
  35. data/lib/feedjira/core_ext/date.rb +0 -19
  36. data/lib/feedjira/core_ext/string.rb +0 -11
  37. data/lib/feedjira/core_ext/time.rb +0 -38
  38. data/lib/feedjira/core_ext.rb +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 500a297ef504526f5995d9e2f410723b328ed8a23ba68aaa4d54ce1fc85b6479
4
- data.tar.gz: e69e151335dde76a9fec5772d47b608c7b1002e14b32eef00a5dfff89d6ef27e
3
+ metadata.gz: 8c0d5191e078e304c8167c6a751183e9fc696180d46197cd27514412a1b19ee7
4
+ data.tar.gz: 7468bd2d9e312250a8d01410b0934877566ebd924ff50d369d25faa0f9c9c285
5
5
  SHA512:
6
- metadata.gz: 80af957b5eab0e0411a7b257d1fb8bbcf01c5b6e61d524b33cefbb585007fb59d319d38781097dec38d47ac5caf5d1ad5fbd4446e17556e8d77ebb3988696351
7
- data.tar.gz: 9ce8aa4c8a364b889c8761c563905250bbedf12c6950a5779e047fa543900b6b05321938acc3f0c1b1a5efe19958a58bb77e59818416d4c8057fccd88dbf1159
6
+ metadata.gz: 6db87062df76ea36471ae9c39502e7be29ccdbd317aa7fa1f9dd914cab6294a23ff0d154ee3578b101fecf4d6908dc0e800e44a5b7ef986e4af8d4ff320ad941
7
+ data.tar.gz: 0351de63585571aaac4742d475ae32700f701158a35e6d3f768edf79629c4172d99ec3e30be194dc067d722437fdd9be7b089faf8e6f35b0965c748253ff9aee
@@ -0,0 +1,176 @@
1
+ # Feedjira Ruby Library
2
+
3
+ Feedjira is a Ruby library designed to parse feeds (RSS, Atom, JSON feeds). It provides a unified interface for parsing different feed formats and extracting structured data from them.
4
+
5
+ Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.
6
+
7
+ ## Working Effectively
8
+
9
+ Bootstrap, build, and test the repository:
10
+
11
+ - `gem install bundler --user-install` -- installs bundler for user-specific installation
12
+ - `export PATH="$HOME/.local/share/gem/ruby/3.2.0/bin:$PATH"` -- add bundler to PATH
13
+ - `bundle config set --local path 'vendor/bundle'` -- configure local bundle installation
14
+ - `bundle install` -- takes 30-60 seconds to complete with dependencies installation. NEVER CANCEL. Set timeout to 120+ seconds.
15
+ - `bundle exec rake` -- runs both tests and rubocop, takes ~3 seconds. NEVER CANCEL. Set timeout to 60+ seconds.
16
+
17
+ Run tests specifically:
18
+ - `bundle exec rake spec` -- runs RSpec test suite, takes ~2 seconds. NEVER CANCEL. Set timeout to 60+ seconds.
19
+ - `bundle exec rake rubocop` -- runs code style checks, takes ~3 seconds. NEVER CANCEL. Set timeout to 60+ seconds.
20
+
21
+ Generate documentation:
22
+ - `bundle exec yard doc` -- generates API documentation, takes ~2 seconds. NEVER CANCEL. Set timeout to 60+ seconds.
23
+
24
+ ## Validation
25
+
26
+ Always manually validate any new code by running through complete scenarios after making changes:
27
+ - ALWAYS run the full test suite with `bundle exec rake` before submitting changes.
28
+ - ALWAYS test feed parsing functionality by creating a Ruby script that parses RSS, Atom, and JSON feeds.
29
+ - You can build and test the library successfully - it has excellent test coverage (98%+).
30
+ - Always run `bundle exec rake` (which includes `bundle exec rubocop`) before you are done or the CI (.github/workflows/ruby.yml) will fail.
31
+
32
+ ## Working with Feed Parsing
33
+
34
+ Test feed parsing functionality:
35
+ ```ruby
36
+ require './lib/feedjira'
37
+ require './spec/sample_feeds'
38
+ include SampleFeeds
39
+
40
+ # Parse RSS feed
41
+ rss_xml = sample_rss_feed
42
+ rss_feed = Feedjira.parse(rss_xml)
43
+ puts "RSS Title: #{rss_feed.title}"
44
+ puts "RSS Entries: #{rss_feed.entries.size}"
45
+
46
+ # Parse Atom feed
47
+ atom_xml = sample_atom_feed
48
+ atom_feed = Feedjira.parse(atom_xml)
49
+ puts "Atom Title: #{atom_feed.title}"
50
+
51
+ # Parse JSON feed
52
+ json_content = sample_json_feed
53
+ json_feed = Feedjira.parse(json_content)
54
+ puts "JSON Title: #{json_feed.title}"
55
+ ```
56
+
57
+ Launch interactive console for testing:
58
+ - `bundle exec irb -r ./lib/feedjira` -- starts IRB with Feedjira loaded
59
+ - `bundle exec pry -r ./lib/feedjira` -- starts Pry console with Feedjira loaded
60
+
61
+ ## Project Structure
62
+
63
+ ### Repository Root
64
+ ```
65
+ README.md # Project overview and usage examples
66
+ Gemfile # Ruby dependencies
67
+ Rakefile # Build tasks (spec, rubocop, yard)
68
+ feedjira.gemspec # Gem specification
69
+ .rubocop.yml # Code style configuration
70
+ .rspec # RSpec configuration
71
+ ```
72
+
73
+ ### Source Code
74
+ - `lib/feedjira.rb` -- Main library file and module definition
75
+ - `lib/feedjira/` -- Core library modules and utilities
76
+ - `lib/feedjira/parser/` -- Feed parser implementations (RSS, Atom, JSON, etc.)
77
+ - `lib/feedjira/core_ext/` -- Ruby core extensions (String, Time, Date)
78
+
79
+ ### Tests
80
+ - `spec/feedjira/` -- Main test files organized by module
81
+ - `spec/feedjira/parser/` -- Parser-specific tests
82
+ - `spec/sample_feeds/` -- XML and JSON sample feeds for testing
83
+ - `spec/spec_helper.rb` -- Test configuration and setup
84
+
85
+ ### Key Classes and Modules
86
+ - `Feedjira` -- Main module with `.parse()` and `.parser_for_xml()` methods
87
+ - `Feedjira::Parser::RSS` -- RSS feed parser
88
+ - `Feedjira::Parser::Atom` -- Atom feed parser
89
+ - `Feedjira::Parser::JSONFeed` -- JSON feed parser
90
+ - `Feedjira::Configuration` -- Global configuration options
91
+
92
+ ## Common Tasks
93
+
94
+ The following are outputs from frequently run commands. Reference them instead of viewing, searching, or running bash commands to save time.
95
+
96
+ ### Available Parsers
97
+ When you require the library, these parsers are available in order:
98
+ 1. `Feedjira::Parser::ITunesRSS`
99
+ 2. `Feedjira::Parser::RSSFeedBurner`
100
+ 3. `Feedjira::Parser::GoogleDocsAtom`
101
+ 4. `Feedjira::Parser::AtomYoutube`
102
+ 5. `Feedjira::Parser::AtomFeedBurner`
103
+ 6. `Feedjira::Parser::AtomGoogleAlerts`
104
+ 7. `Feedjira::Parser::Atom`
105
+ 8. `Feedjira::Parser::RSS`
106
+ 9. `Feedjira::Parser::JSONFeed`
107
+
108
+ ### Current Version
109
+ Feedjira version: 3.2.6
110
+
111
+ ### Dependencies
112
+ The project requires Ruby >= 3.1 and depends on:
113
+ - `sax-machine` for XML parsing
114
+ - `loofah` for HTML sanitization
115
+ - `logger` for logging
116
+
117
+ ### Development Dependencies
118
+ - `rspec` for testing
119
+ - `rubocop` for code style
120
+ - `yard` for documentation
121
+ - `pry` for debugging
122
+ - `faraday` for HTTP requests in tests
123
+ - `ox` and `oga` for alternative XML parsing
124
+
125
+ ## Validation Scenarios
126
+
127
+ ### Basic Feed Parsing Validation
128
+ After making changes, always test:
129
+ 1. Parse an RSS feed and verify title, URL, and entries are extracted
130
+ 2. Parse an Atom feed and verify metadata is correctly parsed
131
+ 3. Parse a JSON feed and verify structure is maintained
132
+ 4. Test parser selection works automatically for different feed types
133
+
134
+ ### Sample Test Script
135
+ Create this validation script in `/tmp/test_feedjira.rb`:
136
+ ```ruby
137
+ require './lib/feedjira'
138
+ require './spec/sample_feeds'
139
+ include SampleFeeds
140
+
141
+ # Test all major feed types
142
+ feeds = [
143
+ { type: 'RSS', content: sample_rss_feed },
144
+ { type: 'Atom', content: sample_atom_feed },
145
+ { type: 'JSON', content: sample_json_feed }
146
+ ]
147
+
148
+ feeds.each do |feed_info|
149
+ feed = Feedjira.parse(feed_info[:content])
150
+ puts "✓ #{feed_info[:type]} feed parsed successfully"
151
+ puts " Title: #{feed.title}"
152
+ puts " Entries: #{feed.entries.size}"
153
+ end
154
+
155
+ puts "✓ All feed types validated successfully"
156
+ ```
157
+
158
+ Run with: `bundle exec ruby /tmp/test_feedjira.rb`
159
+
160
+ ## Troubleshooting
161
+
162
+ ### Common Issues
163
+ - If bundler is not found: Install with `gem install bundler --user-install` and update PATH
164
+ - If bundle install fails with permissions: Use `bundle config set --local path 'vendor/bundle'`
165
+ - If tests fail: Check that all dependencies are installed with `bundle install`
166
+ - If rubocop fails: Run `bundle exec rubocop -a` to auto-correct style issues
167
+
168
+ ### Environment Requirements
169
+ - Ruby 3.1+ (tested on 3.1, 3.2, 3.3, 3.4)
170
+ - Bundler gem manager
171
+ - Standard UNIX environment (Linux/macOS)
172
+
173
+ ### CI Information
174
+ - GitHub Actions runs tests on multiple Ruby versions
175
+ - Tests also run with different XML handlers (nokogiri, ox, oga)
176
+ - All builds must pass both RSpec tests and RuboCop style checks
@@ -12,7 +12,7 @@ jobs:
12
12
  fail-fast: false
13
13
  matrix:
14
14
  os: [ubuntu]
15
- ruby: [2.7, 3.0, 3.1, 3.2, 3.3]
15
+ ruby: [3.1, 3.2, 3.3, 3.4]
16
16
  handler: [nokogiri, ox, oga]
17
17
  exclude:
18
18
  - { ruby: jruby, handler: ox }
data/.gitignore CHANGED
@@ -8,3 +8,4 @@ doc/
8
8
  pkg/
9
9
  rdoc/
10
10
  coverage/
11
+ vendor/bundle/
data/.rubocop.yml CHANGED
@@ -6,8 +6,8 @@ plugins:
6
6
  - rubocop-performance
7
7
 
8
8
  AllCops:
9
- TargetRubyVersion: 2.7
10
- NewCops: enable
9
+ EnabledByDefault: true
10
+ TargetRubyVersion: 3.1
11
11
 
12
12
  # Offense count: 3
13
13
  # Configuration parameters: IgnoredMethods.
@@ -58,3 +58,5 @@ RSpec/BeforeAfterAll:
58
58
 
59
59
  RSpec/RepeatedExample:
60
60
  Enabled: false
61
+
62
+ Style/Copyright: { Enabled: false }
data/.rubocop_todo.yml CHANGED
@@ -1,27 +1,239 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 400`
3
- # on 2025-06-09 17:10:23 UTC using RuboCop version 1.76.1.
3
+ # on 2025-08-24 01:08:06 UTC using RuboCop version 1.79.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
+ # Offense count: 12
10
+ # Configuration parameters: Include, IgnoredGems, OnlyFor.
11
+ # Include: **/*.gemfile, **/Gemfile, **/gems.rb
12
+ Bundler/GemComment:
13
+ Exclude:
14
+ - 'Gemfile'
15
+
16
+ # Offense count: 4
17
+ # This cop supports unsafe autocorrection (--autocorrect-all).
18
+ # Configuration parameters: Categories, ExpectedOrder.
19
+ # ExpectedOrder: module_inclusion, constants, public_class_methods, initializer, public_methods, protected_methods, private_methods
20
+ Layout/ClassStructure:
21
+ Exclude:
22
+ - 'lib/feedjira/parser/atom.rb'
23
+ - 'lib/feedjira/parser/atom_feed_burner.rb'
24
+ - 'lib/feedjira/parser/google_docs_atom.rb'
25
+ - 'lib/feedjira/parser/itunes_rss.rb'
26
+
27
+ # Offense count: 5
28
+ # This cop supports safe autocorrection (--autocorrect).
29
+ # Configuration parameters: EnforcedStyle.
30
+ # SupportedTypes: block, case, class, if, kwbegin, module
31
+ # SupportedStyles: same_line, new_line
32
+ Layout/MultilineAssignmentLayout:
33
+ Exclude:
34
+ - 'lib/feedjira/feed.rb'
35
+ - 'lib/feedjira/feed_entry_utilities.rb'
36
+ - 'spec/feedjira/feed_utilities_entry_spec.rb'
37
+ - 'spec/feedjira/feed_utilities_spec.rb'
38
+ - 'spec/feedjira_spec.rb'
39
+
40
+ # Offense count: 29
41
+ # This cop supports safe autocorrection (--autocorrect).
42
+ # Configuration parameters: AllowMultilineFinalElement.
43
+ Layout/MultilineMethodArgumentLineBreaks:
44
+ Exclude:
45
+ - 'lib/feedjira/atom_entry_utilities.rb'
46
+ - 'lib/feedjira/parser/atom_feed_burner.rb'
47
+ - 'lib/feedjira/parser/itunes_rss.rb'
48
+ - 'lib/feedjira/parser/itunes_rss_category.rb'
49
+ - 'lib/feedjira/parser/json_feed.rb'
50
+ - 'lib/feedjira/parser/json_feed_item.rb'
51
+
52
+ # Offense count: 13
53
+ # This cop supports safe autocorrection (--autocorrect).
54
+ # Configuration parameters: InspectBlocks.
55
+ Layout/RedundantLineBreak:
56
+ Exclude:
57
+ - 'lib/feedjira/atom_entry_utilities.rb'
58
+ - 'lib/feedjira/configuration.rb'
59
+ - 'lib/feedjira/parser/atom_feed_burner.rb'
60
+ - 'lib/feedjira/parser/itunes_rss.rb'
61
+ - 'lib/feedjira/parser/itunes_rss_category.rb'
62
+ - 'lib/feedjira/parser/json_feed.rb'
63
+ - 'spec/feedjira/parser/atom_entry_spec.rb'
64
+ - 'spec/feedjira/parser/itunes_rss_spec.rb'
65
+ - 'spec/feedjira/parser/rss_entry_spec.rb'
66
+ - 'spec/feedjira/parser/rss_feed_burner_entry_spec.rb'
67
+ - 'spec/feedjira/util/parse_time_spec.rb'
68
+
69
+ # Offense count: 7
70
+ # This cop supports safe autocorrection (--autocorrect).
71
+ Layout/SingleLineBlockChain:
72
+ Exclude:
73
+ - 'lib/feedjira/feed_utilities.rb'
74
+ - 'spec/feedjira/feed_utilities_entry_spec.rb'
75
+ - 'spec/feedjira/feed_utilities_spec.rb'
76
+ - 'spec/feedjira/parser/atom_feed_burner_spec.rb'
77
+
78
+ # Offense count: 355
79
+ # Configuration parameters: Only, Ignore.
80
+ Lint/ConstantResolution:
81
+ Exclude:
82
+ - 'Rakefile'
83
+ - 'feedjira.gemspec'
84
+ - 'lib/feedjira.rb'
85
+ - 'lib/feedjira/atom_entry_utilities.rb'
86
+ - 'lib/feedjira/configuration.rb'
87
+ - 'lib/feedjira/feed.rb'
88
+ - 'lib/feedjira/feed_entry_utilities.rb'
89
+ - 'lib/feedjira/feed_utilities.rb'
90
+ - 'lib/feedjira/parser/atom.rb'
91
+ - 'lib/feedjira/parser/atom_entry.rb'
92
+ - 'lib/feedjira/parser/atom_feed_burner.rb'
93
+ - 'lib/feedjira/parser/atom_feed_burner_entry.rb'
94
+ - 'lib/feedjira/parser/atom_google_alerts.rb'
95
+ - 'lib/feedjira/parser/atom_google_alerts_entry.rb'
96
+ - 'lib/feedjira/parser/atom_youtube.rb'
97
+ - 'lib/feedjira/parser/atom_youtube_entry.rb'
98
+ - 'lib/feedjira/parser/globally_unique_identifier.rb'
99
+ - 'lib/feedjira/parser/google_docs_atom.rb'
100
+ - 'lib/feedjira/parser/google_docs_atom_entry.rb'
101
+ - 'lib/feedjira/parser/itunes_rss.rb'
102
+ - 'lib/feedjira/parser/itunes_rss_category.rb'
103
+ - 'lib/feedjira/parser/itunes_rss_item.rb'
104
+ - 'lib/feedjira/parser/itunes_rss_owner.rb'
105
+ - 'lib/feedjira/parser/json_feed.rb'
106
+ - 'lib/feedjira/parser/json_feed_item.rb'
107
+ - 'lib/feedjira/parser/podlove_chapter.rb'
108
+ - 'lib/feedjira/parser/rss.rb'
109
+ - 'lib/feedjira/parser/rss_entry.rb'
110
+ - 'lib/feedjira/parser/rss_feed_burner.rb'
111
+ - 'lib/feedjira/parser/rss_feed_burner_entry.rb'
112
+ - 'lib/feedjira/parser/rss_image.rb'
113
+ - 'lib/feedjira/preprocessor.rb'
114
+ - 'lib/feedjira/rss_entry_utilities.rb'
115
+ - 'lib/feedjira/util/parse_time.rb'
116
+ - 'spec/feedjira/atom_entry_utilities_spec.rb'
117
+ - 'spec/feedjira/configuration_spec.rb'
118
+ - 'spec/feedjira/feed_spec.rb'
119
+ - 'spec/feedjira/feed_utilities_entry_spec.rb'
120
+ - 'spec/feedjira/feed_utilities_spec.rb'
121
+ - 'spec/feedjira/parser/atom_entry_spec.rb'
122
+ - 'spec/feedjira/parser/atom_feed_burner_entry_spec.rb'
123
+ - 'spec/feedjira/parser/atom_feed_burner_spec.rb'
124
+ - 'spec/feedjira/parser/atom_google_alerts_entry_spec.rb'
125
+ - 'spec/feedjira/parser/atom_google_alerts_spec.rb'
126
+ - 'spec/feedjira/parser/atom_spec.rb'
127
+ - 'spec/feedjira/parser/atom_youtube_entry_spec.rb'
128
+ - 'spec/feedjira/parser/atom_youtube_spec.rb'
129
+ - 'spec/feedjira/parser/google_docs_atom_entry_spec.rb'
130
+ - 'spec/feedjira/parser/google_docs_atom_spec.rb'
131
+ - 'spec/feedjira/parser/i_tunes_rss_category_spec.rb'
132
+ - 'spec/feedjira/parser/i_tunes_rss_item_spec.rb'
133
+ - 'spec/feedjira/parser/i_tunes_rss_owner_spec.rb'
134
+ - 'spec/feedjira/parser/itunes_rss_spec.rb'
135
+ - 'spec/feedjira/parser/json_feed_item_spec.rb'
136
+ - 'spec/feedjira/parser/json_feed_spec.rb'
137
+ - 'spec/feedjira/parser/podlove_chapter_spec.rb'
138
+ - 'spec/feedjira/parser/rss_entry_spec.rb'
139
+ - 'spec/feedjira/parser/rss_feed_burner_entry_spec.rb'
140
+ - 'spec/feedjira/parser/rss_feed_burner_spec.rb'
141
+ - 'spec/feedjira/parser/rss_spec.rb'
142
+ - 'spec/feedjira/preprocessor_spec.rb'
143
+ - 'spec/feedjira/util/parse_time_spec.rb'
144
+ - 'spec/feedjira_spec.rb'
145
+ - 'spec/sample_feeds.rb'
146
+ - 'spec/spec_helper.rb'
147
+ - 'spec/support/coverage.rb'
148
+
9
149
  # Offense count: 1
10
- # Configuration parameters: Mode, AllowedMethods.
150
+ # This cop supports unsafe autocorrection (--autocorrect-all).
151
+ # Configuration parameters: AllowedMethods, AllowedPatterns, IgnoredClasses.
152
+ # IgnoredClasses: Time, DateTime
153
+ Lint/NumberConversion:
154
+ Exclude:
155
+ - 'lib/feedjira/parser/podlove_chapter.rb'
156
+
157
+ # Offense count: 1
158
+ # Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates.
11
159
  # AllowedMethods: call
160
+ # WaywardPredicates: nonzero?
12
161
  Naming/PredicateMethod:
13
162
  Exclude:
14
163
  - 'lib/feedjira/feed_utilities.rb'
15
164
 
16
- # Offense count: 16
165
+ # Offense count: 1
166
+ Performance/ChainArrayAllocation:
167
+ Exclude:
168
+ - 'lib/feedjira/feed_entry_utilities.rb'
169
+
170
+ # Offense count: 1
171
+ # This cop supports safe autocorrection (--autocorrect).
172
+ RSpec/AlignLeftLetBrace:
173
+ Exclude:
174
+ - 'spec/feedjira/feed_utilities_spec.rb'
175
+
176
+ # Offense count: 1
177
+ # This cop supports safe autocorrection (--autocorrect).
178
+ RSpec/AlignRightLetBrace:
179
+ Exclude:
180
+ - 'spec/feedjira/feed_utilities_spec.rb'
181
+
182
+ # Offense count: 3
183
+ # Configuration parameters: EnforcedStyle.
184
+ # SupportedStyles: allow, expect
185
+ RSpec/MessageExpectation:
186
+ Exclude:
187
+ - 'spec/feedjira/util/parse_time_spec.rb'
188
+ - 'spec/feedjira_spec.rb'
189
+
190
+ # Offense count: 2
191
+ # This cop supports unsafe autocorrection (--autocorrect-all).
192
+ Style/ArrayFirstLast:
193
+ Exclude:
194
+ - 'spec/feedjira/parser/rss_entry_spec.rb'
195
+
196
+ # Offense count: 1
197
+ # This cop supports unsafe autocorrection (--autocorrect-all).
198
+ # Configuration parameters: PreferredMethods, MethodsAcceptingSymbol.
199
+ # MethodsAcceptingSymbol: inject, reduce
200
+ Style/CollectionMethods:
201
+ Exclude:
202
+ - 'lib/feedjira.rb'
203
+
204
+ # Offense count: 4
205
+ # Configuration parameters: IgnoreModules.
206
+ Style/ConstantVisibility:
207
+ Exclude:
208
+ - 'lib/feedjira.rb'
209
+ - 'lib/feedjira/feed_utilities.rb'
210
+ - 'lib/feedjira/version.rb'
211
+ - 'spec/sample_feeds.rb'
212
+
213
+ # Offense count: 1
214
+ # This cop supports unsafe autocorrection (--autocorrect-all).
215
+ # Configuration parameters: AllowCoercion.
216
+ Style/DateTime:
217
+ Exclude:
218
+ - 'lib/feedjira/feed_entry_utilities.rb'
219
+
220
+ # Offense count: 8
221
+ # This cop supports safe autocorrection (--autocorrect).
222
+ # Configuration parameters: AllowedCops.
223
+ Style/DisableCopsWithinSourceCodeDirective:
224
+ Exclude:
225
+ - 'lib/feedjira/feed_entry_utilities.rb'
226
+ - 'lib/feedjira/parser/atom_google_alerts.rb'
227
+ - 'lib/feedjira/rss_entry_utilities.rb'
228
+ - 'spec/feedjira/feed_utilities_spec.rb'
229
+
230
+ # Offense count: 14
17
231
  # Configuration parameters: AllowedConstants.
18
232
  Style/Documentation:
19
233
  Exclude:
20
234
  - 'spec/**/*'
21
235
  - 'test/**/*'
22
236
  - 'lib/feedjira/atom_entry_utilities.rb'
23
- - 'lib/feedjira/core_ext/string.rb'
24
- - 'lib/feedjira/core_ext/time.rb'
25
237
  - 'lib/feedjira/feed.rb'
26
238
  - 'lib/feedjira/feed_entry_utilities.rb'
27
239
  - 'lib/feedjira/feed_utilities.rb'
@@ -35,6 +247,143 @@ Style/Documentation:
35
247
  - 'lib/feedjira/preprocessor.rb'
36
248
  - 'lib/feedjira/rss_entry_utilities.rb'
37
249
 
250
+ # Offense count: 57
251
+ # Configuration parameters: AllowedMethods, RequireForNonPublicMethods.
252
+ Style/DocumentationMethod:
253
+ Exclude:
254
+ - 'spec/**/*'
255
+ - 'test/**/*'
256
+ - 'lib/feedjira/atom_entry_utilities.rb'
257
+ - 'lib/feedjira/feed.rb'
258
+ - 'lib/feedjira/feed_entry_utilities.rb'
259
+ - 'lib/feedjira/feed_utilities.rb'
260
+ - 'lib/feedjira/parser/atom.rb'
261
+ - 'lib/feedjira/parser/atom_feed_burner.rb'
262
+ - 'lib/feedjira/parser/atom_feed_burner_entry.rb'
263
+ - 'lib/feedjira/parser/atom_google_alerts.rb'
264
+ - 'lib/feedjira/parser/atom_google_alerts_entry.rb'
265
+ - 'lib/feedjira/parser/atom_youtube.rb'
266
+ - 'lib/feedjira/parser/globally_unique_identifier.rb'
267
+ - 'lib/feedjira/parser/google_docs_atom.rb'
268
+ - 'lib/feedjira/parser/itunes_rss.rb'
269
+ - 'lib/feedjira/parser/itunes_rss_category.rb'
270
+ - 'lib/feedjira/parser/json_feed.rb'
271
+ - 'lib/feedjira/parser/podlove_chapter.rb'
272
+ - 'lib/feedjira/parser/rss.rb'
273
+ - 'lib/feedjira/parser/rss_feed_burner.rb'
274
+ - 'lib/feedjira/parser/rss_feed_burner_entry.rb'
275
+ - 'lib/feedjira/preprocessor.rb'
276
+ - 'lib/feedjira/rss_entry_utilities.rb'
277
+
278
+ # Offense count: 8
279
+ Style/InlineComment:
280
+ Exclude:
281
+ - 'lib/feedjira/parser/atom_youtube.rb'
282
+ - 'lib/feedjira/parser/google_docs_atom.rb'
283
+ - 'lib/feedjira/parser/rss_feed_burner.rb'
284
+ - 'lib/feedjira/rss_entry_utilities.rb'
285
+ - 'spec/feedjira/feed_utilities_spec.rb'
286
+ - 'spec/feedjira/preprocessor_spec.rb'
287
+
288
+ # Offense count: 881
289
+ # This cop supports safe autocorrection (--autocorrect).
290
+ # Configuration parameters: IgnoreMacros, AllowedMethods, AllowedPatterns, IncludedMacros, AllowParenthesesInMultilineCall, AllowParenthesesInChaining, AllowParenthesesInCamelCaseMethod, AllowParenthesesInStringInterpolation, EnforcedStyle.
291
+ # SupportedStyles: require_parentheses, omit_parentheses
292
+ Style/MethodCallWithArgsParentheses:
293
+ Exclude:
294
+ - 'feedjira.gemspec'
295
+ - 'lib/feedjira.rb'
296
+ - 'lib/feedjira/atom_entry_utilities.rb'
297
+ - 'lib/feedjira/configuration.rb'
298
+ - 'lib/feedjira/feed_utilities.rb'
299
+ - 'lib/feedjira/parser/itunes_rss_category.rb'
300
+ - 'lib/feedjira/preprocessor.rb'
301
+ - 'lib/feedjira/rss_entry_utilities.rb'
302
+ - 'lib/feedjira/util/parse_time.rb'
303
+ - 'spec/feedjira/atom_entry_utilities_spec.rb'
304
+ - 'spec/feedjira/configuration_spec.rb'
305
+ - 'spec/feedjira/feed_spec.rb'
306
+ - 'spec/feedjira/feed_utilities_entry_spec.rb'
307
+ - 'spec/feedjira/feed_utilities_spec.rb'
308
+ - 'spec/feedjira/parser/atom_entry_spec.rb'
309
+ - 'spec/feedjira/parser/atom_feed_burner_entry_spec.rb'
310
+ - 'spec/feedjira/parser/atom_feed_burner_spec.rb'
311
+ - 'spec/feedjira/parser/atom_google_alerts_entry_spec.rb'
312
+ - 'spec/feedjira/parser/atom_google_alerts_spec.rb'
313
+ - 'spec/feedjira/parser/atom_spec.rb'
314
+ - 'spec/feedjira/parser/atom_youtube_entry_spec.rb'
315
+ - 'spec/feedjira/parser/atom_youtube_spec.rb'
316
+ - 'spec/feedjira/parser/google_docs_atom_entry_spec.rb'
317
+ - 'spec/feedjira/parser/google_docs_atom_spec.rb'
318
+ - 'spec/feedjira/parser/i_tunes_rss_category_spec.rb'
319
+ - 'spec/feedjira/parser/i_tunes_rss_item_spec.rb'
320
+ - 'spec/feedjira/parser/i_tunes_rss_owner_spec.rb'
321
+ - 'spec/feedjira/parser/itunes_rss_spec.rb'
322
+ - 'spec/feedjira/parser/json_feed_item_spec.rb'
323
+ - 'spec/feedjira/parser/json_feed_spec.rb'
324
+ - 'spec/feedjira/parser/podlove_chapter_spec.rb'
325
+ - 'spec/feedjira/parser/rss_entry_spec.rb'
326
+ - 'spec/feedjira/parser/rss_feed_burner_entry_spec.rb'
327
+ - 'spec/feedjira/parser/rss_feed_burner_spec.rb'
328
+ - 'spec/feedjira/parser/rss_spec.rb'
329
+ - 'spec/feedjira/preprocessor_spec.rb'
330
+ - 'spec/feedjira/util/parse_time_spec.rb'
331
+ - 'spec/feedjira_spec.rb'
332
+ - 'spec/spec_helper.rb'
333
+
334
+ # Offense count: 1
335
+ Style/MethodCalledOnDoEndBlock:
336
+ Exclude:
337
+ - 'spec/feedjira_spec.rb'
338
+
339
+ # Offense count: 4
340
+ # This cop supports safe autocorrection (--autocorrect).
341
+ # Configuration parameters: EnforcedStyle.
342
+ # SupportedStyles: if, case, both
343
+ Style/MissingElse:
344
+ Exclude:
345
+ - 'lib/feedjira.rb'
346
+ - 'lib/feedjira/feed_entry_utilities.rb'
347
+ - 'spec/feedjira/parser/rss_entry_spec.rb'
348
+ - 'spec/feedjira/parser/rss_feed_burner_entry_spec.rb'
349
+
350
+ # Offense count: 4
351
+ # Configuration parameters: SuspiciousParamNames, Allowlist.
352
+ # SuspiciousParamNames: options, opts, args, params, parameters
353
+ Style/OptionHash:
354
+ Exclude:
355
+ - 'lib/feedjira/feed.rb'
356
+
357
+ # Offense count: 35
358
+ # This cop supports unsafe autocorrection (--autocorrect-all).
359
+ Style/RequireOrder:
360
+ Exclude:
361
+ - 'lib/feedjira.rb'
362
+ - 'lib/feedjira/util/parse_time.rb'
363
+
364
+ # Offense count: 4
365
+ # This cop supports safe autocorrection (--autocorrect).
366
+ # Configuration parameters: EnforcedStyle.
367
+ # SupportedStyles: return, return_nil
368
+ Style/ReturnNil:
369
+ Exclude:
370
+ - 'lib/feedjira/parser/json_feed_item.rb'
371
+ - 'lib/feedjira/util/parse_time.rb'
372
+
373
+ # Offense count: 6
374
+ Style/Send:
375
+ Exclude:
376
+ - 'lib/feedjira/feed.rb'
377
+ - 'lib/feedjira/feed_entry_utilities.rb'
378
+ - 'lib/feedjira/feed_utilities.rb'
379
+
380
+ # Offense count: 9
381
+ # This cop supports unsafe autocorrection (--autocorrect-all).
382
+ Style/StringHashKeys:
383
+ Exclude:
384
+ - 'feedjira.gemspec'
385
+ - 'spec/feedjira/parser/json_feed_item_spec.rb'
386
+
38
387
  # Offense count: 1
39
388
  # This cop supports safe autocorrection (--autocorrect).
40
389
  Style/SuperArguments:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Feedjira Changelog
2
2
 
3
+ ## 4.0.0
4
+
5
+ * Drop support for Ruby 2.7 and 3.0 (#555)
6
+ * Remove core extensions (#539) (#542) (#549). This is unlikely to impact most
7
+ users, but if you were relying on any of the following methods, you'll need
8
+ to find an alternative:
9
+ * `Time.parse_safely` or `Time.parse_string_safely`
10
+ * `String#sanitize` or `String#sanitize!`
11
+ * `Date#feed_utils_to_gm_time`
12
+
3
13
  ## 3.2.6
4
14
 
5
15
  * Add explicit logger dependency in gemspec for ruby 3.5+ (#532)
data/feedjira.gemspec CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |s|
29
29
  s.files = `git ls-files`.split("\n")
30
30
  s.require_paths = ["lib"]
31
31
 
32
- s.required_ruby_version = ">=2.7"
32
+ s.required_ruby_version = ">=3.1"
33
33
 
34
34
  s.add_dependency "logger", ">= 1.0", "< 2"
35
35
  s.add_dependency "loofah", ">= 2.3.1", "< 3"
@@ -9,7 +9,7 @@ module Feedjira
9
9
  end
10
10
 
11
11
  def parse_datetime(string)
12
- DateTime.parse(string).feed_utils_to_gm_time
12
+ DateTime.parse(string).to_time.utc
13
13
  rescue StandardError => e
14
14
  Feedjira.logger.debug("Failed to parse date #{string.inspect}")
15
15
  Feedjira.logger.debug(e)
@@ -41,8 +41,11 @@ module Feedjira
41
41
 
42
42
  def sanitize!
43
43
  %w[title author summary content image].each do |name|
44
- if respond_to?(name) && send(name).respond_to?(:sanitize!)
45
- send(name).send(:sanitize!)
44
+ next unless respond_to?(name)
45
+
46
+ current_value = send(name)
47
+ if current_value.is_a?(String)
48
+ send(:"#{name}=", Loofah.scrub_fragment(current_value, :prune).to_s)
46
49
  end
47
50
  end
48
51
  end
@@ -12,10 +12,10 @@ module Feedjira
12
12
  end
13
13
 
14
14
  module ClassMethods
15
- def parse(xml, &block)
15
+ def parse(xml, &)
16
16
  xml = strip_whitespace(xml)
17
17
  xml = preprocess(xml) if preprocess_xml
18
- super xml, &block
18
+ super(xml, &)
19
19
  end
20
20
 
21
21
  def preprocess(xml)