webmention 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b40b0711592d5a14c2d9dc53b638e697ce1278ed3d3a851e559d6eb51752c7d4
4
- data.tar.gz: 8a5a3f9508a6f071cdcdb7fe5126909678538b20c1bf043110e0e06ea56e75d1
3
+ metadata.gz: 2939ada02eb29818ba6b84da3c64e7ce9f363cddc0299ddb423c60343fc202fc
4
+ data.tar.gz: 40e715d3602cebc2ef45261141b3cbf06de12661918ba746723e1785d689095e
5
5
  SHA512:
6
- metadata.gz: 8eb087999adce5389f37333598e1edaee18e96e748b9b11eee41f5bbb1ecc6cb511e0951eeba831df62d210972e296d0d5090adf6e25a3666eb182b503454d7e
7
- data.tar.gz: ccb4e243d5c050d6e912a47a4a1fa0ee02594211192e81737011db1ded8a88eac4bfd11f32749ffba7dea1b08a50d326ed446d0688bb1ce406095bbbc1f57a58
6
+ metadata.gz: c16e1234ec404e226d0c6f50362f0c53286416a2155094b372055f0f57e39d7ac8502d937ff101a835d7dcfe9be9fcd4716274af0acc521b7a7896dffa78753a
7
+ data.tar.gz: 620ed9d6bc592f1fe9174da42bc330592d459760e07e82a4b8f2b6361a3d377ab5c575d1de3a782c099e76b9c4b06ddaf65b2f08b8185897df91d963ed9bfb2a
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.1.0 / 2020-04-06
4
+
5
+ - Refactor `BaseParser` class and remove `Registerable` module (b706229)
6
+ - Refactor `HttpRequest` and `NodeParser` classes into Service Objects (f29c073 and 7456bf1)
7
+
3
8
  ## 2.0.0 / 2020-01-25
4
9
 
5
10
  - Add Ruby 2.7 to list of supported Ruby versions (c67ed14)
@@ -8,12 +8,14 @@ require 'webmention/version'
8
8
  require 'webmention/exceptions'
9
9
 
10
10
  require 'webmention/client'
11
- require 'webmention/http_request'
12
- require 'webmention/registerable'
13
11
 
14
12
  require 'webmention/parsers'
13
+ require 'webmention/parsers/base_parser'
15
14
  require 'webmention/parsers/html_parser'
16
15
 
16
+ require 'webmention/services/http_request_service'
17
+ require 'webmention/services/node_parser_service'
18
+
17
19
  module Webmention
18
20
  class << self
19
21
  def client(source)
@@ -23,7 +23,7 @@ module Webmention
23
23
 
24
24
  return unless endpoint
25
25
 
26
- HttpRequest.post(Addressable::URI.parse(endpoint), source: @source, target: target)
26
+ Services::HttpRequestService.post(Addressable::URI.parse(endpoint), source: @source, target: target)
27
27
  rescue IndieWeb::Endpoints::IndieWebEndpointsError => exception
28
28
  raise Webmention.const_get(exception.class.name.split('::').last), exception
29
29
  end
@@ -35,7 +35,7 @@ module Webmention
35
35
  end
36
36
 
37
37
  def source_response
38
- @source_response ||= HttpRequest.get(source_uri)
38
+ @source_response ||= Services::HttpRequestService.get(source_uri)
39
39
  end
40
40
 
41
41
  def source_uri
@@ -1,29 +1,11 @@
1
1
  module Webmention
2
2
  module Parsers
3
- extend Registerable
4
-
5
- class BaseParser
6
- def initialize(response)
7
- raise ArgumentError, "response must be an HTTP::Response (given #{response.class.name})" unless response.is_a?(HTTP::Response)
8
-
9
- @response = response
10
-
11
- raise UnsupportedMimeTypeError, "Unsupported MIME Type: #{response.mime_type}" unless self.class.mime_types.include?(response.mime_type)
12
- end
13
-
14
- def results
15
- @results ||= parse_response_body
16
- end
17
-
18
- private
19
-
20
- def response_body
21
- @response_body ||= @response.body.to_s
22
- end
3
+ def self.register(klass)
4
+ klass.mime_types.each { |mime_type| registered[mime_type] = klass }
5
+ end
23
6
 
24
- def response_url
25
- @response_url ||= @response.uri.to_s
26
- end
7
+ def self.registered
8
+ @registered ||= {}
27
9
  end
28
10
  end
29
11
  end
@@ -0,0 +1,31 @@
1
+ module Webmention
2
+ module Parsers
3
+ class BaseParser
4
+ class << self
5
+ attr_reader :mime_types
6
+ end
7
+
8
+ def initialize(response)
9
+ raise ArgumentError, "response must be an HTTP::Response (given #{response.class.name})" unless response.is_a?(HTTP::Response)
10
+
11
+ @response = response
12
+
13
+ raise UnsupportedMimeTypeError, "Unsupported MIME Type: #{response.mime_type}" unless self.class.mime_types.include?(response.mime_type)
14
+ end
15
+
16
+ def results
17
+ @results ||= parse_response_body
18
+ end
19
+
20
+ private
21
+
22
+ def response_body
23
+ @response_body ||= @response.body.to_s
24
+ end
25
+
26
+ def response_url
27
+ @response_url ||= @response.uri.to_s
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,9 +1,7 @@
1
1
  module Webmention
2
2
  module Parsers
3
3
  class HtmlParser < BaseParser
4
- def self.mime_types
5
- ['text/html']
6
- end
4
+ @mime_types = ['text/html']
7
5
 
8
6
  Parsers.register(self)
9
7
 
@@ -38,35 +36,11 @@ module Webmention
38
36
  end
39
37
 
40
38
  def root_node
41
- @root_node ||= doc.css('.h-entry .e-content').first || doc.css('.h-entry').first || doc.css('body')
39
+ @root_node ||= doc.at_css('.h-entry .e-content') || doc.at_css('.h-entry') || doc.css('body')
42
40
  end
43
41
 
44
42
  def search_node(attribute, selectors)
45
- NodeParser.nodes_from(root_node, selectors).map { |node| NodeParser.values_from(node, attribute) }.reject(&:empty?)
46
- end
47
-
48
- module NodeParser
49
- class << self
50
- # Search a node for matching elements
51
- #
52
- # @param node [Nokogiri::XML::Element]
53
- # @param selectors [Array]
54
- # @return [Nokogiri::XML::NodeSet]
55
- def nodes_from(node, selectors)
56
- node.css(*selectors)
57
- end
58
-
59
- # Derive attribute values from a single node
60
- #
61
- # @param node [Nokogiri::XML::Element]
62
- # @param attribute [Symbol]
63
- # @return [Array] the HTML attribute values
64
- def values_from(node, attribute)
65
- return Array(node[attribute]) unless attribute == :srcset
66
-
67
- node[attribute].split(',').map { |value| value.strip.match(/^\S+/).to_s }
68
- end
69
- end
43
+ Services::NodeParserService.nodes_from(root_node, selectors).map { |node| Services::NodeParserService.values_from(node, attribute) }.reject(&:empty?)
70
44
  end
71
45
  end
72
46
  end
@@ -0,0 +1,47 @@
1
+ module Webmention
2
+ module Services
3
+ module HttpRequestService
4
+ # Defaults derived from Webmention specification examples
5
+ # https://www.w3.org/TR/webmention/#limits-on-get-requests
6
+ # rubocop:disable Layout/HashAlignment
7
+ HTTP_CLIENT_OPTS = {
8
+ follow: {
9
+ max_hops: 20
10
+ },
11
+ headers: {
12
+ accept: '*/*',
13
+ user_agent: 'Webmention Client (https://rubygems.org/gems/webmention)'
14
+ },
15
+ timeout_options: {
16
+ connect_timeout: 5,
17
+ read_timeout: 5
18
+ }
19
+ }.freeze
20
+ # rubocop:enable Layout/HashAlignment
21
+
22
+ class << self
23
+ def get(uri)
24
+ request(:get, uri)
25
+ end
26
+
27
+ def post(uri, **options)
28
+ request(:post, uri, form: options)
29
+ end
30
+
31
+ private
32
+
33
+ def client
34
+ @client ||= HTTP::Client.new(HTTP_CLIENT_OPTS)
35
+ end
36
+
37
+ def request(method, uri, **options)
38
+ client.request(method, uri, options)
39
+ rescue HTTP::ConnectionError,
40
+ HTTP::TimeoutError,
41
+ HTTP::Redirector::TooManyRedirectsError => exception
42
+ raise Webmention.const_get(exception.class.name.split('::').last), exception
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,25 @@
1
+ module Webmention
2
+ module Services
3
+ module NodeParserService
4
+ # Search a node for matching elements
5
+ #
6
+ # @param node [Nokogiri::XML::Element]
7
+ # @param selectors [Array]
8
+ # @return [Nokogiri::XML::NodeSet]
9
+ def self.nodes_from(node, selectors)
10
+ node.css(*selectors)
11
+ end
12
+
13
+ # Derive attribute values from a single node
14
+ #
15
+ # @param node [Nokogiri::XML::Element]
16
+ # @param attribute [Symbol]
17
+ # @return [Array] the HTML attribute values
18
+ def self.values_from(node, attribute)
19
+ return Array(node[attribute]) unless attribute == :srcset
20
+
21
+ node[attribute].split(',').map { |value| value.strip.match(/^\S+/).to_s }
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,3 +1,3 @@
1
1
  module Webmention
2
- VERSION = '2.0.0'.freeze
2
+ VERSION = '2.1.0'.freeze
3
3
  end
@@ -28,16 +28,16 @@ Gem::Specification.new do |spec|
28
28
  spec.add_development_dependency 'minitest', '~> 5.14'
29
29
  spec.add_development_dependency 'minitest-reporters', '~> 1.4'
30
30
  spec.add_development_dependency 'rake', '~> 13.0'
31
- spec.add_development_dependency 'reek', '~> 5.6'
32
- spec.add_development_dependency 'rubocop', '~> 0.79.0'
31
+ spec.add_development_dependency 'reek', '~> 6.0'
32
+ spec.add_development_dependency 'rubocop', '~> 0.81.0'
33
33
  spec.add_development_dependency 'rubocop-performance', '~> 1.5'
34
- spec.add_development_dependency 'simplecov', '~> 0.17.1'
35
- spec.add_development_dependency 'simplecov-console', '~> 0.6.0'
34
+ spec.add_development_dependency 'simplecov', '~> 0.18.5'
35
+ spec.add_development_dependency 'simplecov-console', '~> 0.7.2'
36
36
  spec.add_development_dependency 'webmock', '~> 3.8'
37
37
 
38
38
  spec.add_runtime_dependency 'absolutely', '~> 3.1'
39
39
  spec.add_runtime_dependency 'addressable', '~> 2.7'
40
- spec.add_runtime_dependency 'http', '~> 4.3'
40
+ spec.add_runtime_dependency 'http', '~> 4.4'
41
41
  spec.add_runtime_dependency 'indieweb-endpoints', '~> 2.0'
42
42
  spec.add_runtime_dependency 'nokogiri', '~> 1.10'
43
43
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webmention
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Parecki
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-01-25 00:00:00.000000000 Z
12
+ date: 2020-04-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: minitest
@@ -59,28 +59,28 @@ dependencies:
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: '5.6'
62
+ version: '6.0'
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: '5.6'
69
+ version: '6.0'
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: rubocop
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
74
  - - "~>"
75
75
  - !ruby/object:Gem::Version
76
- version: 0.79.0
76
+ version: 0.81.0
77
77
  type: :development
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
81
  - - "~>"
82
82
  - !ruby/object:Gem::Version
83
- version: 0.79.0
83
+ version: 0.81.0
84
84
  - !ruby/object:Gem::Dependency
85
85
  name: rubocop-performance
86
86
  requirement: !ruby/object:Gem::Requirement
@@ -101,28 +101,28 @@ dependencies:
101
101
  requirements:
102
102
  - - "~>"
103
103
  - !ruby/object:Gem::Version
104
- version: 0.17.1
104
+ version: 0.18.5
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
109
  - - "~>"
110
110
  - !ruby/object:Gem::Version
111
- version: 0.17.1
111
+ version: 0.18.5
112
112
  - !ruby/object:Gem::Dependency
113
113
  name: simplecov-console
114
114
  requirement: !ruby/object:Gem::Requirement
115
115
  requirements:
116
116
  - - "~>"
117
117
  - !ruby/object:Gem::Version
118
- version: 0.6.0
118
+ version: 0.7.2
119
119
  type: :development
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
122
  requirements:
123
123
  - - "~>"
124
124
  - !ruby/object:Gem::Version
125
- version: 0.6.0
125
+ version: 0.7.2
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: webmock
128
128
  requirement: !ruby/object:Gem::Requirement
@@ -171,14 +171,14 @@ dependencies:
171
171
  requirements:
172
172
  - - "~>"
173
173
  - !ruby/object:Gem::Version
174
- version: '4.3'
174
+ version: '4.4'
175
175
  type: :runtime
176
176
  prerelease: false
177
177
  version_requirements: !ruby/object:Gem::Requirement
178
178
  requirements:
179
179
  - - "~>"
180
180
  - !ruby/object:Gem::Version
181
- version: '4.3'
181
+ version: '4.4'
182
182
  - !ruby/object:Gem::Dependency
183
183
  name: indieweb-endpoints
184
184
  requirement: !ruby/object:Gem::Requirement
@@ -231,10 +231,11 @@ files:
231
231
  - lib/webmention.rb
232
232
  - lib/webmention/client.rb
233
233
  - lib/webmention/exceptions.rb
234
- - lib/webmention/http_request.rb
235
234
  - lib/webmention/parsers.rb
235
+ - lib/webmention/parsers/base_parser.rb
236
236
  - lib/webmention/parsers/html_parser.rb
237
- - lib/webmention/registerable.rb
237
+ - lib/webmention/services/http_request_service.rb
238
+ - lib/webmention/services/node_parser_service.rb
238
239
  - lib/webmention/version.rb
239
240
  - webmention.gemspec
240
241
  homepage: https://github.com/indieweb/webmention-client-ruby
@@ -242,7 +243,7 @@ licenses:
242
243
  - Apache-2.0
243
244
  metadata:
244
245
  bug_tracker_uri: https://github.com/indieweb/webmention-client-ruby/issues
245
- changelog_uri: https://github.com/indieweb/webmention-client-ruby/blob/v2.0.0/CHANGELOG.md
246
+ changelog_uri: https://github.com/indieweb/webmention-client-ruby/blob/v2.1.0/CHANGELOG.md
246
247
  post_install_message:
247
248
  rdoc_options: []
248
249
  require_paths:
@@ -261,7 +262,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
261
262
  - !ruby/object:Gem::Version
262
263
  version: '0'
263
264
  requirements: []
264
- rubygems_version: 3.0.6
265
+ rubygems_version: 3.1.2
265
266
  signing_key:
266
267
  specification_version: 4
267
268
  summary: Webmention notification client
@@ -1,41 +0,0 @@
1
- module Webmention
2
- class HttpRequest
3
- # Defaults derived from Webmention specification examples
4
- # https://www.w3.org/TR/webmention/#limits-on-get-requests
5
- # rubocop:disable Layout/HashAlignment
6
- HTTP_CLIENT_OPTS = {
7
- follow: {
8
- max_hops: 20
9
- },
10
- headers: {
11
- accept: '*/*',
12
- user_agent: 'Webmention Client (https://rubygems.org/gems/webmention)'
13
- },
14
- timeout_options: {
15
- connect_timeout: 5,
16
- read_timeout: 5
17
- }
18
- }.freeze
19
- # rubocop:enable Layout/HashAlignment
20
-
21
- class << self
22
- def get(uri)
23
- request(:get, uri)
24
- end
25
-
26
- def post(uri, **options)
27
- request(:post, uri, form: options)
28
- end
29
-
30
- private
31
-
32
- def request(method, uri, **options)
33
- HTTP::Client.new(HTTP_CLIENT_OPTS).request(method, uri, options)
34
- rescue HTTP::ConnectionError,
35
- HTTP::TimeoutError,
36
- HTTP::Redirector::TooManyRedirectsError => exception
37
- raise Webmention.const_get(exception.class.name.split('::').last), exception
38
- end
39
- end
40
- end
41
- end
@@ -1,11 +0,0 @@
1
- module Webmention
2
- module Registerable
3
- def register(klass)
4
- klass.mime_types.each { |mime_type| registered[mime_type] = klass }
5
- end
6
-
7
- def registered
8
- @registered ||= {}
9
- end
10
- end
11
- end