nvd-json_feeds 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/.document +3 -0
  3. data/.github/workflows/ruby.yml +29 -0
  4. data/.gitignore +9 -0
  5. data/.rspec +1 -0
  6. data/.yardopts +1 -0
  7. data/ChangeLog.md +25 -0
  8. data/Gemfile +13 -0
  9. data/LICENSE.txt +20 -0
  10. data/README.md +136 -0
  11. data/Rakefile +31 -0
  12. data/gemspec.yml +22 -0
  13. data/lib/nvd/json_feeds.rb +25 -0
  14. data/lib/nvd/json_feeds/exceptions.rb +15 -0
  15. data/lib/nvd/json_feeds/feed.rb +50 -0
  16. data/lib/nvd/json_feeds/feed_file.rb +95 -0
  17. data/lib/nvd/json_feeds/feed_uri.rb +131 -0
  18. data/lib/nvd/json_feeds/gz_feed_file.rb +60 -0
  19. data/lib/nvd/json_feeds/gz_feed_uri.rb +25 -0
  20. data/lib/nvd/json_feeds/json_feed_file.rb +21 -0
  21. data/lib/nvd/json_feeds/meta.rb +122 -0
  22. data/lib/nvd/json_feeds/meta_feed_uri.rb +22 -0
  23. data/lib/nvd/json_feeds/schema/configurations.rb +61 -0
  24. data/lib/nvd/json_feeds/schema/configurations/node.rb +98 -0
  25. data/lib/nvd/json_feeds/schema/cpe/has_uri.rb +66 -0
  26. data/lib/nvd/json_feeds/schema/cpe/match.rb +117 -0
  27. data/lib/nvd/json_feeds/schema/cpe/name.rb +67 -0
  28. data/lib/nvd/json_feeds/schema/cve_feed.rb +142 -0
  29. data/lib/nvd/json_feeds/schema/cve_item.rb +94 -0
  30. data/lib/nvd/json_feeds/schema/cvss_v2.rb +298 -0
  31. data/lib/nvd/json_feeds/schema/cvss_v3.rb +332 -0
  32. data/lib/nvd/json_feeds/schema/has_data_version.rb +54 -0
  33. data/lib/nvd/json_feeds/schema/impact.rb +73 -0
  34. data/lib/nvd/json_feeds/schema/impact/base_metric_v2.rb +132 -0
  35. data/lib/nvd/json_feeds/schema/impact/base_metric_v3.rb +79 -0
  36. data/lib/nvd/json_feeds/schema/timestamp.rb +9 -0
  37. data/lib/nvd/json_feeds/version.rb +6 -0
  38. data/lib/nvd/json_feeds/zip_feed_file.rb +64 -0
  39. data/lib/nvd/json_feeds/zip_feed_uri.rb +25 -0
  40. data/nvd-json_feeds.gemspec +61 -0
  41. data/spec/feed_file_examples.rb +27 -0
  42. data/spec/feed_file_spec.rb +42 -0
  43. data/spec/feed_spec.rb +56 -0
  44. data/spec/feed_uri_spec.rb +81 -0
  45. data/spec/fixtures/gz_feed_file/nvdcve-1.1-recent.json.gz +0 -0
  46. data/spec/fixtures/nvdcve-1.1-recent.json +180 -0
  47. data/spec/fixtures/zip_feed_file/nvdcve-1.1-recent.json.zip +0 -0
  48. data/spec/gz_feed_file_spec.rb +66 -0
  49. data/spec/gz_feed_uri_spec.rb +35 -0
  50. data/spec/json_feed_file_spec.rb +18 -0
  51. data/spec/json_feeds_spec.rb +8 -0
  52. data/spec/meta_spec.rb +141 -0
  53. data/spec/schema/configurations/node_spec.rb +87 -0
  54. data/spec/schema/configurations_spec.rb +57 -0
  55. data/spec/schema/cpe/match_spec.rb +188 -0
  56. data/spec/schema/cpe/name_spec.rb +54 -0
  57. data/spec/schema/cve_feed_spec.rb +162 -0
  58. data/spec/schema/cve_item_spec.rb +116 -0
  59. data/spec/schema/impact/base_metric_v2_spec.rb +183 -0
  60. data/spec/schema/impact/base_metric_v3_spec.rb +80 -0
  61. data/spec/schema/impact_spec.rb +53 -0
  62. data/spec/schema/shared_examples.rb +136 -0
  63. data/spec/schema/timestamp_spec.rb +8 -0
  64. data/spec/spec_helper.rb +8 -0
  65. data/spec/zip_feed_file_spec.rb +66 -0
  66. data/spec/zip_feed_uri_spec.rb +35 -0
  67. metadata +156 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bd4659807e5869138f57f659f9e910b664ae957404e5c02d51637db8b66d206d
4
+ data.tar.gz: 211b9c2e6dd6a12a7ce4af222598b78e9320a8e0620f28123fe340d88596b43e
5
+ SHA512:
6
+ metadata.gz: e7872a3817bc270911fce04eb11b61ed2ae1b9aa5a7473dd685eb61ec925630a367d72a9b8155a203b621d1717f9223d75260071c88ffc7fbe865141bfabc521
7
+ data.tar.gz: 6393801ec6a605b09446e87a71aac5146a09e08d62898c48ab15050ddd4f3c0ff532fb05f979e993430c53b396ef8e32c65422a4bc29c1ec2f59d4d2b4ddcf1d
@@ -0,0 +1,3 @@
1
+ -
2
+ ChangeLog.md
3
+ LICENSE.txt
@@ -0,0 +1,29 @@
1
+ name: CI
2
+
3
+ on: [ push, pull_request ]
4
+
5
+ jobs:
6
+ tests:
7
+ runs-on: ubuntu-latest
8
+ strategy:
9
+ fail-fast: false
10
+ matrix:
11
+ ruby:
12
+ # - 2.4
13
+ # - 2.5
14
+ # - 2.6
15
+ - 2.7
16
+ - 3.0
17
+ # TODO: uncomment when jruby supports ruby >= 2.7
18
+ # - jruby
19
+ name: Ruby ${{ matrix.ruby }}
20
+ steps:
21
+ - uses: actions/checkout@v2
22
+ - name: Set up Ruby
23
+ uses: ruby/setup-ruby@v1
24
+ with:
25
+ ruby-version: ${{ matrix.ruby }}
26
+ - name: Install dependencies
27
+ run: bundle install --jobs 4 --retry 3
28
+ - name: Run tests
29
+ run: bundle exec rake test
@@ -0,0 +1,9 @@
1
+ /.bundle
2
+ /.yardoc/
3
+ /Gemfile.lock
4
+ /doc/
5
+ /pkg/
6
+ /spec/fixtures/downloads/
7
+ /spec/fixtures/gz_feed_file/*.json
8
+ /spec/fixtures/zip_feed_file/*.json
9
+ /vendor/cache/*.gem
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour --format documentation
@@ -0,0 +1 @@
1
+ --markup markdown --title "nvd-json_feeds Documentation" --protected
@@ -0,0 +1,25 @@
1
+ ### 0.1.0 / 2021-01-20
2
+
3
+ * Initial release:
4
+ * Supports [NVD JSON 1.1 Schema].
5
+ * [ruby] >= 2.7.0
6
+ * Added {NVD::JSONFeeds::FeedURI}.
7
+ * Added {NVD::JSONFeeds::MetaFeedURI}.
8
+ * Added {NVD::JSONFeeds::Meta}.
9
+ * Added {NVD::JSONFeeds::GzFeedURI}.
10
+ * Added {NVD::JSONFeeds::ZipFeedURI}.
11
+ * Added {NVD::JSONFeeds::FeedFile}.
12
+ * Added {NVD::JSONFeeds::GzFeedFile}.
13
+ * Added {NVD::JSONFeeds::ZipFeedFile}.
14
+ * Added {NVD::JSONFeeds::JSONFeedFile}.
15
+ * Added {NVD::JSONFeeds::Schema::Configurations}.
16
+ * Added {NVD::JSONFeeds::Schema::CPE::Name}.
17
+ * Added {NVD::JSONFeeds::Schema::CPE::Match}.
18
+ * Added {NVD::JSONFeeds::Schema::CVEFeed}.
19
+ * Added {NVD::JSONFeeds::Schema::CVEItem}.
20
+ * Added {NVD::JSONFeeds::Schema::CVSSv2}.
21
+ * Added {NVD::JSONFeeds::Schema::CVSSv3}.
22
+ * Added {NVD::JSONFeeds::Schema::Impact}.
23
+
24
+ [NVD JSON 1.1 Schema]: https://csrc.nist.gov/schema/nvd/feed/1.1/nvd_cve_feed_json_1.1.schema
25
+ [ruby]: https://www.ruby-lang.org/
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'rake'
7
+ gem 'rubygems-tasks', '~> 0.2'
8
+
9
+ gem 'rspec', '~> 3.0'
10
+
11
+ gem 'kramdown'
12
+ gem 'yard', '~> 0.9'
13
+ end
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2021 Hal Brodigan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,136 @@
1
+ # nvd-json_feeds
2
+
3
+ * [Homepage](https://github.com/postmodern/nvd-json_feeds.rb#readme)
4
+ * [Issues](https://github.com/postmodern/nvd-json_feeds.rb/issues)
5
+ * [Documentation](http://rubydoc.info/gems/nvd-json_feeds/frames)
6
+ * [Email](mailto:postmodern.mod3 at gmail.com)
7
+
8
+ ## Description
9
+
10
+ Provides a Ruby API to [NVD JSON Feeds].
11
+
12
+ ## Features
13
+
14
+ * Supports [NVD JSON 1.1 Schema].
15
+ * Supports recent, modified, and Year number `.gz`/`.zip` JSON feed files.
16
+ * Supports parsing META feed files.
17
+ * Supports downloading `.gz`/`.zip` JSON feed files.
18
+ * Supports reading `.gz`/`.zip` JSON feed files, without extracting them.
19
+ * Supports extracting `.gz`/`.zip` JSON feed files.
20
+ * Supports parsing extracted JSON feed files.
21
+
22
+ ## Examples
23
+
24
+ require 'nvd/json_feeds'
25
+
26
+ Access the Modified CVEs feed:
27
+
28
+ NVD::JSONFeeds[:modified]
29
+ # => #<NVD::JSONFeeds::Feed:0x0000556b4db58660
30
+ # @gz=
31
+ # #<NVD::JSONFeeds::GzFeedURI: https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-modified.json.gz>,
32
+ # @meta=
33
+ # #<NVD::JSONFeeds::MetaFeedURI: https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-modified.meta>,
34
+ # @name=:modified,
35
+ # @zip=
36
+ # #<NVD::JSONFeeds::ZipFeedURI: https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-modified.json.zip>>
37
+
38
+ Access the Recent CVEs feed:
39
+
40
+ NVD::JSONFeeds[:recent]
41
+ # => #<NVD::JSONFeeds::Feed:0x0000556b4da14c68
42
+ # @gz=
43
+ # #<NVD::JSONFeeds::GzFeedURI: https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-recent.json.gz>,
44
+ # @meta=
45
+ # #<NVD::JSONFeeds::MetaFeedURI: https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-recent.meta>,
46
+ # @name=:recent,
47
+ # @zip=
48
+ # #<NVD::JSONFeeds::ZipFeedURI: https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-recent.json.zip>>
49
+
50
+ Access the year 2020 CVEs feed:
51
+
52
+ NVD::JSONFeeds[2020]
53
+ # => #<NVD::JSONFeeds::Feed:0x0000556b4d55da80
54
+ # @gz=
55
+ # #<NVD::JSONFeeds::GzFeedURI: https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-2020.json.gz>,
56
+ # @meta=
57
+ # #<NVD::JSONFeeds::MetaFeedURI: https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-2020.meta>,
58
+ # @name=2020,
59
+ # @zip=
60
+ # #<NVD::JSONFeeds::ZipFeedURI: https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-2020.json.zip>>
61
+
62
+ Read the `.meta` feed file:
63
+
64
+ meta = NVD::JSONFeeds[2020].meta.parse
65
+ # => #<NVD::JSONFeeds::Meta:0x0000556b4e6f4960
66
+ meta.last_modified_date
67
+ # => #<DateTime: 2021-01-17T03:17:48-05:00 ((2459232j,29868s,0n),-18000s,2299161j)>
68
+ meta.size
69
+ # => 67524038
70
+ meta.zip_size
71
+ # => 3777141
72
+ meta.gz_size
73
+ # => 3777005
74
+ meta.sha256
75
+ # => "9288B92370FC4D6E92ACB6FFDDDA378C4B9F1B3B5257105BD6D92535DA46BD55"
76
+
77
+ Download the `.zip`/`.gz` feed file:
78
+
79
+ zip_feed = NVD::JSONFeeds[2020].zip.download(dest)
80
+ # => #<NVD::JSONFeeds::ZipFeedFile: ...>
81
+ gz_feed = NVD::JSONFeeds[2020].gz.download(dest)
82
+ # => #<NVD::JSONFeeds::GzFeedFile: ...>
83
+
84
+ Access a pre-downloaded `.zip`/`.gz` feed file:
85
+
86
+ zip_feed = NVD::JSONFeeds::ZipFeedFile.new('path/to/nvdcve-1.1-2020.json.zip')
87
+ # => #<NVD::JSONFeeds::ZipFeedFile: ...>
88
+ gz_feed = NVD::JSONFeeds::GzFeedFile.new('path/to/nvdcve-1.1-2020.json.gz')
89
+ # => #<NVD::JSONFeeds::GzFeedFile: ...>
90
+
91
+ Parse a `.zip`/`.gz` feed file (without extracting it):
92
+
93
+ cve_feed = zip_feed.parse
94
+ # => #<NVD::JSONFeeds::Schema::CVEFeed: ...>
95
+ cve_feed = gz_feed.parse
96
+ # => #<NVD::JSONFeeds::Schema::CVEFeed: ...>
97
+
98
+ Extracts a `.zip`/`.gz` feed file:
99
+
100
+ json_feed = zip_feed.extract(dest_dir)
101
+ # => #<NVD::JSONFeeds::JSONFeedFile: ...>
102
+ json_feed = gz_feed.extract
103
+ # => #<NVD::JSONFeeds::JSONFeedFile: ...>
104
+
105
+ Access a pre-extracted `.json` feed file:
106
+
107
+ json_feed = NVD::JSONFeeds::JSONFeed.new('path/to/nvdcve-1.1-2020.json')
108
+ # => #<NVD::JSONFeeds::JSONFeedFile: ...>
109
+ cve_feed = json_feed.parse
110
+ # => #<NVD::JSONFeeds::Schema::CVEFeed: ...>
111
+
112
+ ## Requirements
113
+
114
+ * [ruby] >= 2.7.0
115
+ * [multi_json] ~> 1.0
116
+ * [cve_schema] ~> 0.1
117
+
118
+ ## Install
119
+
120
+ $ gem install nvd-json_feeds
121
+
122
+ ### Gemfile
123
+
124
+ gem 'nvd-json_feeds', '~> 0.1'
125
+
126
+ ## Copyright
127
+
128
+ Copyright (c) 2021 Hal Brodigan
129
+
130
+ See {file:LICENSE.txt} for details.
131
+
132
+ [NVD JSON Feeds]: https://nvd.nist.gov/vuln/data-feeds#JSON_FEEDS
133
+ [NVD JSON 1.1 Schema]: https://csrc.nist.gov/schema/nvd/feed/1.1/nvd_cve_feed_json_1.1.schema
134
+
135
+ [multi_json]: https://github.com/intridea/multi_json#readme
136
+ [cve_schema]: https://github.com/postmodern/cve_schema.rb#readme
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+
5
+ begin
6
+ require 'bundler/setup'
7
+ rescue LoadError => e
8
+ abort e.message
9
+ end
10
+
11
+ require 'rake'
12
+
13
+
14
+ require 'rubygems/tasks'
15
+ Gem::Tasks.new
16
+
17
+ require 'rspec/core/rake_task'
18
+ RSpec::Core::RakeTask.new
19
+
20
+ namespace :spec do
21
+ RSpec::Core::RakeTask.new(:integration) do |t|
22
+ t.rspec_opts = '--tag integration'
23
+ end
24
+ end
25
+
26
+ task :test => [:spec, 'spec:integration']
27
+ task :default => :spec
28
+
29
+ require 'yard'
30
+ YARD::Rake::YardocTask.new
31
+ task :doc => :yard
@@ -0,0 +1,22 @@
1
+ name: nvd-json_feeds
2
+ summary: A Ruby API to NVD JSON Feeds
3
+ description: Provides a Ruby API to NVD JSON Feeds.
4
+ license: MIT
5
+ authors: Postmodern
6
+ email: postmodern.mod3@gmail.com
7
+ homepage: https://github.com/postmodern/nvd-json_feeds#readme
8
+
9
+ metadata:
10
+ documentation_uri: https://rubydoc.info/gems/nvd-json_feeds
11
+ source_code_uri: https://github.com/postmodern/nvd-json_feeds.rb
12
+ bug_tracker_uri: https://github.com/postmodern/nvd-json_feeds.rb/issues
13
+ changelog_uri: https://github.com/postmodern/nvd-json_feeds.rb/blob/main/ChangeLog.md
14
+
15
+ required_ruby_version: ">= 2.7.0"
16
+
17
+ dependencies:
18
+ multi_json: ~> 1.0
19
+ cve_schema: ~> 0.1
20
+
21
+ development_dependencies:
22
+ bundler: ~> 2.0
@@ -0,0 +1,25 @@
1
+ require 'nvd/json_feeds/feed'
2
+ require 'nvd/json_feeds/version'
3
+
4
+ require 'date'
5
+
6
+ module NVD
7
+ module JSONFeeds
8
+ FEEDS = Hash[[:modified, :recent, *(2002 .. Date.today.year)].map { |name|
9
+ [name, Feed.new(name)]
10
+ }]
11
+
12
+ #
13
+ # Accesses a feed with the given name or year number.
14
+ #
15
+ # @param [:modified, :recent, Integer] name
16
+ # The feed name or year number.
17
+ #
18
+ # @return [Feed, nil]
19
+ # The feed.
20
+ #
21
+ def self.[](name)
22
+ FEEDS[name]
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,15 @@
1
+ module NVD
2
+ module JSONFeeds
3
+ class MetaParseError < RuntimeError
4
+ end
5
+
6
+ class FeedFileError < RuntimeError
7
+ end
8
+
9
+ class ReadFailed < FeedFileError
10
+ end
11
+
12
+ class ExtractFailed < FeedFileError
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'nvd/json_feeds/meta_feed_uri'
4
+ require 'nvd/json_feeds/gz_feed_uri'
5
+ require 'nvd/json_feeds/zip_feed_uri'
6
+
7
+ module NVD
8
+ module JSONFeeds
9
+ #
10
+ # Represents a feed and it's various downloads.
11
+ #
12
+ class Feed
13
+
14
+ # The feed name or year number.
15
+ #
16
+ # @return [:modified, :recent, Integer]
17
+ attr_reader :name
18
+
19
+ # The "meta" feed URI.
20
+ #
21
+ # @return [MetaFeedURI]
22
+ attr_reader :meta
23
+
24
+ # The ".gz" feed URI.
25
+ #
26
+ # @return [GzFeedURI]
27
+ attr_reader :gz
28
+
29
+ # The ".zip" feed URI.
30
+ #
31
+ # @return [ZipFeedURI]
32
+ attr_reader :zip
33
+
34
+ #
35
+ # Initializes the feed.
36
+ #
37
+ # @param [:modified, :recent, Integer] name
38
+ # The feed name or year number.
39
+ #
40
+ def initialize(name)
41
+ @name = name
42
+
43
+ @meta = MetaFeedURI.new(@name,'.meta')
44
+ @gz = GzFeedURI.new(@name,'.json.gz')
45
+ @zip = ZipFeedURI.new(@name,'.json.zip')
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,95 @@
1
+ require 'nvd/json_feeds/schema/cve_feed'
2
+
3
+ require 'multi_json'
4
+ require 'digest/sha2'
5
+
6
+ module NVD
7
+ module JSONFeeds
8
+ class FeedFile
9
+
10
+ # The path to the feed file.
11
+ #
12
+ # @return [String]
13
+ attr_reader :path
14
+
15
+ #
16
+ # Initializes the feed file.
17
+ #
18
+ # @param [String] path
19
+ # The path to the feed file.
20
+ #
21
+ def initialize(path)
22
+ @path = File.expand_path(path)
23
+ end
24
+
25
+ #
26
+ # @see #parse
27
+ #
28
+ def self.parse(path)
29
+ new(path).parse
30
+ end
31
+
32
+ #
33
+ # Calculates the SHA256 checksum of the feed file.
34
+ #
35
+ # @return [String]
36
+ #
37
+ # @note NVD uses all upper-case SHA256 checksums.
38
+ #
39
+ def sha256
40
+ Digest::SHA256.hexdigest(read).upcase
41
+ end
42
+
43
+ #
44
+ # Reads the feed file.
45
+ #
46
+ # @return [String]
47
+ #
48
+ # @abstract
49
+ #
50
+ def read
51
+ raise(NotImplementedError,"#{self.class}#read not implemented")
52
+ end
53
+
54
+ #
55
+ # Parses the JSON.
56
+ #
57
+ # @return [Hash{String => Object}]
58
+ # The parsed JSON.
59
+ #
60
+ def json
61
+ MultiJson.load(read)
62
+ end
63
+
64
+ #
65
+ # Loads the CVE data from the feed file.
66
+ #
67
+ # @return [CVEFeed]
68
+ # The CVE feed data.
69
+ #
70
+ def parse
71
+ Schema::CVEFeed.load(json)
72
+ end
73
+
74
+ #
75
+ # Converts the feed file to a String.
76
+ #
77
+ # @return [String]
78
+ # The feed file path.
79
+ #
80
+ def to_s
81
+ @path
82
+ end
83
+
84
+ #
85
+ # Inspects the feed file.
86
+ #
87
+ # @return [String]
88
+ #
89
+ def inspect
90
+ "#<#{self.class}: #{self}>"
91
+ end
92
+
93
+ end
94
+ end
95
+ end