html2rss 0.26.0 → 0.27.1
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.
- checksums.yaml +4 -4
- data/README.md +41 -18
- data/html2rss.gemspec +1 -1
- data/lib/html2rss/auto_source/README.md +57 -0
- data/lib/html2rss/auto_source/cleanup.rb +121 -56
- data/lib/html2rss/auto_source/scraper.rb +13 -0
- data/lib/html2rss/auto_source.rb +34 -8
- data/lib/html2rss/capture/README.md +61 -0
- data/lib/html2rss/capture.rb +120 -117
- data/lib/html2rss/cli.rb +35 -17
- data/lib/html2rss/config/schema.rb +12 -0
- data/lib/html2rss/config/validator.rb +33 -8
- data/lib/html2rss/config.rb +28 -0
- data/lib/html2rss/error.rb +24 -6
- data/lib/html2rss/feed_pipeline/README.md +42 -0
- data/lib/html2rss/feed_pipeline/auto_fallback.rb +22 -9
- data/lib/html2rss/feed_pipeline/strategy_plan.rb +11 -0
- data/lib/html2rss/feed_pipeline.rb +30 -12
- data/lib/html2rss/html/article_extractor/category_extractor.rb +36 -22
- data/lib/html2rss/html/article_extractor/date_extractor.rb +5 -3
- data/lib/html2rss/html/article_extractor.rb +95 -17
- data/lib/html2rss/html/article_rules/category.rb +28 -11
- data/lib/html2rss/html/article_rules/date.rb +60 -6
- data/lib/html2rss/html/article_rules/description.rb +122 -0
- data/lib/html2rss/html/card_walk.rb +42 -0
- data/lib/html2rss/html/feed_link.rb +34 -0
- data/lib/html2rss/html/navigator.rb +18 -0
- data/lib/html2rss/html/sst_article_extractor.rb +119 -32
- data/lib/html2rss/link_destination/path_classifier.rb +49 -35
- data/lib/html2rss/mcp/config_argument.rb +42 -0
- data/lib/html2rss/mcp/contract.rb +173 -0
- data/lib/html2rss/mcp/inspect.rb +241 -0
- data/lib/html2rss/mcp/outcome.rb +188 -0
- data/lib/html2rss/mcp/server.rb +253 -409
- data/lib/html2rss/request_service/botasaurus_contract.rb +193 -102
- data/lib/html2rss/request_service/botasaurus_strategy.rb +15 -8
- data/lib/html2rss/request_service/compressed_body.rb +109 -0
- data/lib/html2rss/request_service/faraday_strategy.rb +3 -1
- data/lib/html2rss/request_service/policy.rb +1 -1
- data/lib/html2rss/request_service/response.rb +57 -6
- data/lib/html2rss/request_service.rb +6 -1
- data/lib/html2rss/selectors.rb +2 -1
- data/lib/html2rss/status.rb +27 -11
- data/lib/html2rss/url.rb +20 -0
- data/lib/html2rss/version.rb +1 -1
- data/lib/html2rss.rb +30 -6
- data/schema/html2rss-config.schema.json +40 -16
- metadata +15 -4
|
@@ -33,8 +33,13 @@ module Html2rss
|
|
|
33
33
|
class BlockedSurfaceDetected < Html2rss::Error; end
|
|
34
34
|
# Raised when a request times out.
|
|
35
35
|
class RequestTimedOut < Html2rss::Error; end
|
|
36
|
+
|
|
36
37
|
# Raised when Botasaurus configuration is missing or invalid.
|
|
37
|
-
class BotasaurusConfigurationError < Html2rss::Error
|
|
38
|
+
class BotasaurusConfigurationError < Html2rss::Error
|
|
39
|
+
# Short empty-feed guidance owned once (composed by {Html2rss::NoFeedItemsExtracted}).
|
|
40
|
+
EMPTY_FEED_HINT = 'Configure BOTASAURUS_SCRAPER_URL to enable the Botasaurus request strategy.'
|
|
41
|
+
end
|
|
42
|
+
|
|
38
43
|
# Raised when the Botasaurus service cannot be reached (network / DNS / SSL).
|
|
39
44
|
class BotasaurusConnectionFailed < Html2rss::Error; end
|
|
40
45
|
# Raised when Botasaurus responds but the scrape fails (upstream error, bad payload).
|
data/lib/html2rss/selectors.rb
CHANGED
data/lib/html2rss/status.rb
CHANGED
|
@@ -8,7 +8,8 @@ module Html2rss
|
|
|
8
8
|
# Stable telemetry payload for cross-repo consumers (e.g. html2rss-web observability).
|
|
9
9
|
# Tallies and counters are validated and frozen at construction (including Marshal load).
|
|
10
10
|
Status = Data.define(
|
|
11
|
-
:version, :scraper_tallies, :dedup_dropped, :selected_strategy, :attempt_count,
|
|
11
|
+
:version, :scraper_tallies, :dedup_dropped, :selected_strategy, :attempt_count,
|
|
12
|
+
:strategy_attempts, :admission_drops
|
|
12
13
|
) do
|
|
13
14
|
class << self
|
|
14
15
|
##
|
|
@@ -19,8 +20,11 @@ module Html2rss
|
|
|
19
20
|
# @param selected_strategy [Symbol, nil] concrete strategy that succeeded under +:auto+ (else +nil+)
|
|
20
21
|
# @param attempt_count [Integer] auto-fallback attempt count (0 when not under +:auto+)
|
|
21
22
|
# @param strategy_attempts [Array<Hash>] auto-fallback attempt hashes (empty outside +:auto+)
|
|
23
|
+
# @param admission_drops [Hash{String => Integer}] Cleanup reason → count (empty when unused)
|
|
22
24
|
# @return [Html2rss::Status]
|
|
23
|
-
|
|
25
|
+
# rubocop:disable Metrics/ParameterLists -- Status kwargs stay co-located
|
|
26
|
+
def build(articles:, dedup_dropped: 0, selected_strategy: nil, attempt_count: 0,
|
|
27
|
+
strategy_attempts: [], admission_drops: {})
|
|
24
28
|
tallies = articles.filter_map(&:scraper).tally.transform_keys { |klass| scraper_name(klass) }
|
|
25
29
|
new(
|
|
26
30
|
version: Html2rss::VERSION,
|
|
@@ -28,9 +32,11 @@ module Html2rss
|
|
|
28
32
|
dedup_dropped:,
|
|
29
33
|
selected_strategy:,
|
|
30
34
|
attempt_count:,
|
|
31
|
-
strategy_attempts
|
|
35
|
+
strategy_attempts:,
|
|
36
|
+
admission_drops:
|
|
32
37
|
)
|
|
33
38
|
end
|
|
39
|
+
# rubocop:enable Metrics/ParameterLists
|
|
34
40
|
|
|
35
41
|
##
|
|
36
42
|
# @param klass [Class, #to_s] scraper class
|
|
@@ -47,9 +53,11 @@ module Html2rss
|
|
|
47
53
|
# @param selected_strategy [Symbol, nil]
|
|
48
54
|
# @param attempt_count [Integer]
|
|
49
55
|
# @param strategy_attempts [Array<Hash>]
|
|
56
|
+
# @param admission_drops [Hash{String => Integer}]
|
|
50
57
|
# rubocop:disable Metrics/ParameterLists, Metrics/MethodLength -- Status Data.define members
|
|
51
58
|
def initialize(
|
|
52
|
-
version:, scraper_tallies:, dedup_dropped:, selected_strategy: nil, attempt_count: 0,
|
|
59
|
+
version:, scraper_tallies:, dedup_dropped:, selected_strategy: nil, attempt_count: 0,
|
|
60
|
+
strategy_attempts: [], admission_drops: {}
|
|
53
61
|
)
|
|
54
62
|
dedup = Integer(dedup_dropped)
|
|
55
63
|
attempts = Integer(attempt_count)
|
|
@@ -61,7 +69,8 @@ module Html2rss
|
|
|
61
69
|
dedup_dropped: dedup,
|
|
62
70
|
selected_strategy:,
|
|
63
71
|
attempt_count: attempts,
|
|
64
|
-
strategy_attempts: freeze_attempts(strategy_attempts)
|
|
72
|
+
strategy_attempts: freeze_attempts(strategy_attempts),
|
|
73
|
+
admission_drops: freeze_tallies(admission_drops)
|
|
65
74
|
)
|
|
66
75
|
end
|
|
67
76
|
# rubocop:enable Metrics/ParameterLists, Metrics/MethodLength
|
|
@@ -69,11 +78,13 @@ module Html2rss
|
|
|
69
78
|
##
|
|
70
79
|
# Observability hash for web (+scraper_status+). Omits empty/absent optional keys:
|
|
71
80
|
# +:scraper_tallies+ when empty, +:selected_strategy+ when +nil+, +:attempt_count+ when zero,
|
|
72
|
-
# +:strategy_attempts+ when empty.
|
|
81
|
+
# +:strategy_attempts+ / +:admission_drops+ when empty.
|
|
73
82
|
# Data members remain available via readers even when omitted here.
|
|
74
83
|
#
|
|
75
84
|
# @return [Hash{Symbol => Object}] always +:version+ (String), +:dedup_dropped+ (Integer);
|
|
76
|
-
# optionally +:scraper_tallies+, +:selected_strategy+, +:attempt_count+,
|
|
85
|
+
# optionally +:scraper_tallies+, +:selected_strategy+, +:attempt_count+,
|
|
86
|
+
# +:strategy_attempts+, +:admission_drops+
|
|
87
|
+
# rubocop:disable Metrics/AbcSize -- omit-empty optional keys stay explicit
|
|
77
88
|
def to_h
|
|
78
89
|
{
|
|
79
90
|
version:,
|
|
@@ -81,9 +92,11 @@ module Html2rss
|
|
|
81
92
|
**(scraper_tallies.any? ? { scraper_tallies: } : {}),
|
|
82
93
|
**(selected_strategy.nil? ? {} : { selected_strategy: }),
|
|
83
94
|
**(attempt_count.positive? ? { attempt_count: } : {}),
|
|
84
|
-
**(strategy_attempts.any? ? { strategy_attempts: } : {})
|
|
95
|
+
**(strategy_attempts.any? ? { strategy_attempts: } : {}),
|
|
96
|
+
**(admission_drops.any? ? { admission_drops: } : {})
|
|
85
97
|
}
|
|
86
98
|
end
|
|
99
|
+
# rubocop:enable Metrics/AbcSize
|
|
87
100
|
|
|
88
101
|
##
|
|
89
102
|
# Formats the RSS +generator+ string and JSON Feed +user_comment+.
|
|
@@ -101,11 +114,14 @@ module Html2rss
|
|
|
101
114
|
private
|
|
102
115
|
|
|
103
116
|
def marshal_dump
|
|
104
|
-
[version, scraper_tallies, dedup_dropped, selected_strategy, attempt_count, strategy_attempts
|
|
117
|
+
[version, scraper_tallies, dedup_dropped, selected_strategy, attempt_count, strategy_attempts,
|
|
118
|
+
admission_drops]
|
|
105
119
|
end
|
|
106
120
|
|
|
107
|
-
def marshal_load((version, scraper_tallies, dedup_dropped, selected_strategy, attempt_count,
|
|
108
|
-
|
|
121
|
+
def marshal_load((version, scraper_tallies, dedup_dropped, selected_strategy, attempt_count,
|
|
122
|
+
strategy_attempts, admission_drops))
|
|
123
|
+
initialize(version:, scraper_tallies:, dedup_dropped:, selected_strategy:, attempt_count:,
|
|
124
|
+
strategy_attempts:, admission_drops: admission_drops || {})
|
|
109
125
|
end
|
|
110
126
|
|
|
111
127
|
def freeze_tallies(tallies)
|
data/lib/html2rss/url.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'addressable/uri'
|
|
4
4
|
require 'cgi'
|
|
5
|
+
require 'ipaddr'
|
|
5
6
|
require 'nokogiri'
|
|
6
7
|
|
|
7
8
|
module Html2rss
|
|
@@ -152,6 +153,16 @@ module Html2rss
|
|
|
152
153
|
# @return [String, nil] URI host component
|
|
153
154
|
def host = @uri.host
|
|
154
155
|
|
|
156
|
+
# Registrable domain (eTLD+1). Same-site hosts like www.wp.pl and wiadomosci.wp.pl
|
|
157
|
+
# share `wp.pl`. IP literals stay the host so 1.2.3.4 is not treated as `3.4`.
|
|
158
|
+
#
|
|
159
|
+
# @return [String, nil]
|
|
160
|
+
def domain
|
|
161
|
+
return host if ip_address_host?
|
|
162
|
+
|
|
163
|
+
@uri.domain || host
|
|
164
|
+
end
|
|
165
|
+
|
|
155
166
|
# @return [Integer, nil] URI port component
|
|
156
167
|
def port = @uri.port
|
|
157
168
|
|
|
@@ -281,6 +292,15 @@ module Html2rss
|
|
|
281
292
|
#
|
|
282
293
|
# @return [String] the debug representation
|
|
283
294
|
def inspect = "#<#{self.class}:#{object_id} @uri=#{@uri.inspect}>"
|
|
295
|
+
|
|
296
|
+
private
|
|
297
|
+
|
|
298
|
+
def ip_address_host?
|
|
299
|
+
IPAddr.new(host.to_s)
|
|
300
|
+
true
|
|
301
|
+
rescue IPAddr::Error
|
|
302
|
+
false
|
|
303
|
+
end
|
|
284
304
|
end
|
|
285
305
|
# rubocop:enable Metrics/ClassLength
|
|
286
306
|
end
|
data/lib/html2rss/version.rb
CHANGED
data/lib/html2rss.rb
CHANGED
|
@@ -70,11 +70,35 @@ module Html2rss
|
|
|
70
70
|
|
|
71
71
|
# rubocop:disable Metrics/ParameterLists
|
|
72
72
|
|
|
73
|
+
##
|
|
74
|
+
# Scrapes the provided URL without hand-written selectors and returns {FeedResult}.
|
|
75
|
+
#
|
|
76
|
+
# Prefer this when callers need {FeedResult#status} (MCP envelope payload, CLI +--explain+).
|
|
77
|
+
#
|
|
78
|
+
# @param url [String] source page URL
|
|
79
|
+
# @param strategy [Symbol] request strategy to use
|
|
80
|
+
# @param items_selector [String, nil] optional selector hint for item extraction
|
|
81
|
+
# @param max_redirects [Integer, nil] optional redirect limit override
|
|
82
|
+
# @param max_requests [Integer] optional request budget override (default: 4 for sitemap sub-fetches)
|
|
83
|
+
# @param local_file_path [String, nil] optional local HTML file path
|
|
84
|
+
# @param limit [Integer, nil] max articles to keep (default: {AutoSource::DEFAULT_LIMIT})
|
|
85
|
+
# @return [Html2rss::FeedResult]
|
|
86
|
+
def self.auto_feed_result(url,
|
|
87
|
+
strategy: :auto,
|
|
88
|
+
items_selector: nil,
|
|
89
|
+
max_redirects: nil,
|
|
90
|
+
max_requests: 4,
|
|
91
|
+
local_file_path: nil,
|
|
92
|
+
limit: nil)
|
|
93
|
+
feed_result(build_auto_source_config(url:, strategy:, items_selector:, max_redirects:, max_requests:,
|
|
94
|
+
local_file_path:, limit:))
|
|
95
|
+
end
|
|
96
|
+
|
|
73
97
|
##
|
|
74
98
|
# Scrapes the provided URL without hand-written selectors and returns an RSS object.
|
|
75
99
|
#
|
|
76
100
|
# Builds an auto_source config, then FeedPipeline runs structured scrapers and
|
|
77
|
-
# (when needed) the SST heuristic path — see
|
|
101
|
+
# (when needed) the SST heuristic path — see lib/html2rss/auto_source/README.md.
|
|
78
102
|
#
|
|
79
103
|
# @param url [String] source page URL
|
|
80
104
|
# @param strategy [Symbol] request strategy to use
|
|
@@ -91,14 +115,14 @@ module Html2rss
|
|
|
91
115
|
max_requests: 4,
|
|
92
116
|
local_file_path: nil,
|
|
93
117
|
limit: nil)
|
|
94
|
-
|
|
95
|
-
|
|
118
|
+
auto_feed_result(url, strategy:, items_selector:, max_redirects:, max_requests:,
|
|
119
|
+
local_file_path:, limit:).to_rss
|
|
96
120
|
end
|
|
97
121
|
|
|
98
122
|
##
|
|
99
123
|
# Scrapes the provided URL without hand-written selectors and returns a JSONFeed 1.1 hash.
|
|
100
124
|
#
|
|
101
|
-
# Same auto_source pipeline as {.auto_source}; see
|
|
125
|
+
# Same auto_source pipeline as {.auto_source}; see lib/html2rss/auto_source/README.md.
|
|
102
126
|
#
|
|
103
127
|
# @param url [String] source page URL
|
|
104
128
|
# @param strategy [Symbol] request strategy to use
|
|
@@ -115,8 +139,8 @@ module Html2rss
|
|
|
115
139
|
max_requests: 4,
|
|
116
140
|
local_file_path: nil,
|
|
117
141
|
limit: nil)
|
|
118
|
-
|
|
119
|
-
|
|
142
|
+
auto_feed_result(url, strategy:, items_selector:, max_redirects:, max_requests:,
|
|
143
|
+
local_file_path:, limit:).to_json_feed
|
|
120
144
|
end
|
|
121
145
|
|
|
122
146
|
##
|
|
@@ -66,6 +66,17 @@
|
|
|
66
66
|
"directory": {
|
|
67
67
|
"type": "object",
|
|
68
68
|
"properties": {
|
|
69
|
+
"title": {
|
|
70
|
+
"type": "string",
|
|
71
|
+
"minLength": 1
|
|
72
|
+
},
|
|
73
|
+
"summary": {
|
|
74
|
+
"type": [
|
|
75
|
+
"null",
|
|
76
|
+
"string"
|
|
77
|
+
],
|
|
78
|
+
"maxLength": 160
|
|
79
|
+
},
|
|
69
80
|
"topics": {
|
|
70
81
|
"type": "array",
|
|
71
82
|
"items": {
|
|
@@ -92,7 +103,9 @@
|
|
|
92
103
|
"minItems": 1
|
|
93
104
|
}
|
|
94
105
|
},
|
|
95
|
-
"required": [
|
|
106
|
+
"required": [
|
|
107
|
+
"title"
|
|
108
|
+
]
|
|
96
109
|
},
|
|
97
110
|
"headers": {
|
|
98
111
|
"type": "object",
|
|
@@ -684,7 +697,8 @@
|
|
|
684
697
|
"not": {
|
|
685
698
|
"type": "null"
|
|
686
699
|
},
|
|
687
|
-
"
|
|
700
|
+
"minimum": 1,
|
|
701
|
+
"maximum": 20
|
|
688
702
|
},
|
|
689
703
|
"scroll": {
|
|
690
704
|
"type": "boolean",
|
|
@@ -692,12 +706,6 @@
|
|
|
692
706
|
"type": "null"
|
|
693
707
|
}
|
|
694
708
|
},
|
|
695
|
-
"scroll_to_bottom": {
|
|
696
|
-
"type": "boolean",
|
|
697
|
-
"not": {
|
|
698
|
-
"type": "null"
|
|
699
|
-
}
|
|
700
|
-
},
|
|
701
709
|
"block_images": {
|
|
702
710
|
"type": "boolean",
|
|
703
711
|
"not": {
|
|
@@ -737,13 +745,28 @@
|
|
|
737
745
|
"minLength": 1
|
|
738
746
|
},
|
|
739
747
|
"window_size": {
|
|
740
|
-
"type": "
|
|
741
|
-
"
|
|
742
|
-
"
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
748
|
+
"type": "object",
|
|
749
|
+
"properties": {
|
|
750
|
+
"width": {
|
|
751
|
+
"type": "integer",
|
|
752
|
+
"not": {
|
|
753
|
+
"type": "null"
|
|
754
|
+
},
|
|
755
|
+
"exclusiveMinimum": 0
|
|
756
|
+
},
|
|
757
|
+
"height": {
|
|
758
|
+
"type": "integer",
|
|
759
|
+
"not": {
|
|
760
|
+
"type": "null"
|
|
761
|
+
},
|
|
762
|
+
"exclusiveMinimum": 0
|
|
763
|
+
}
|
|
764
|
+
},
|
|
765
|
+
"required": [
|
|
766
|
+
"width",
|
|
767
|
+
"height"
|
|
768
|
+
],
|
|
769
|
+
"additionalProperties": false
|
|
747
770
|
},
|
|
748
771
|
"lang": {
|
|
749
772
|
"type": "string",
|
|
@@ -756,7 +779,8 @@
|
|
|
756
779
|
"type": "object"
|
|
757
780
|
}
|
|
758
781
|
},
|
|
759
|
-
"required": []
|
|
782
|
+
"required": [],
|
|
783
|
+
"additionalProperties": false
|
|
760
784
|
},
|
|
761
785
|
"local_file_path": {
|
|
762
786
|
"type": "string",
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: html2rss
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.27.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gil Desmarais
|
|
@@ -119,14 +119,14 @@ dependencies:
|
|
|
119
119
|
requirements:
|
|
120
120
|
- - "~>"
|
|
121
121
|
- !ruby/object:Gem::Version
|
|
122
|
-
version: '1.
|
|
122
|
+
version: '1.2'
|
|
123
123
|
type: :runtime
|
|
124
124
|
prerelease: false
|
|
125
125
|
version_requirements: !ruby/object:Gem::Requirement
|
|
126
126
|
requirements:
|
|
127
127
|
- - "~>"
|
|
128
128
|
- !ruby/object:Gem::Version
|
|
129
|
-
version: '1.
|
|
129
|
+
version: '1.2'
|
|
130
130
|
- !ruby/object:Gem::Dependency
|
|
131
131
|
name: mime-types
|
|
132
132
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -319,6 +319,7 @@ files:
|
|
|
319
319
|
- lib/html2rss/article/deduplicator.rb
|
|
320
320
|
- lib/html2rss/article/enclosure.rb
|
|
321
321
|
- lib/html2rss/auto_source.rb
|
|
322
|
+
- lib/html2rss/auto_source/README.md
|
|
322
323
|
- lib/html2rss/auto_source/cleanup.rb
|
|
323
324
|
- lib/html2rss/auto_source/scraper.rb
|
|
324
325
|
- lib/html2rss/auto_source/scraper/html.rb
|
|
@@ -350,6 +351,7 @@ files:
|
|
|
350
351
|
- lib/html2rss/auto_source/segmenter/primary_link.rb
|
|
351
352
|
- lib/html2rss/auto_source/segmenter/semantic.rb
|
|
352
353
|
- lib/html2rss/capture.rb
|
|
354
|
+
- lib/html2rss/capture/README.md
|
|
353
355
|
- lib/html2rss/channel.rb
|
|
354
356
|
- lib/html2rss/cli.rb
|
|
355
357
|
- lib/html2rss/config.rb
|
|
@@ -370,6 +372,7 @@ files:
|
|
|
370
372
|
- lib/html2rss/feed_builder/rss.rb
|
|
371
373
|
- lib/html2rss/feed_builder/rss/stylesheet.rb
|
|
372
374
|
- lib/html2rss/feed_pipeline.rb
|
|
375
|
+
- lib/html2rss/feed_pipeline/README.md
|
|
373
376
|
- lib/html2rss/feed_pipeline/auto_fallback.rb
|
|
374
377
|
- lib/html2rss/feed_pipeline/runtime_policy.rb
|
|
375
378
|
- lib/html2rss/feed_pipeline/strategy_plan.rb
|
|
@@ -386,8 +389,11 @@ files:
|
|
|
386
389
|
- lib/html2rss/html/article_rules.rb
|
|
387
390
|
- lib/html2rss/html/article_rules/category.rb
|
|
388
391
|
- lib/html2rss/html/article_rules/date.rb
|
|
392
|
+
- lib/html2rss/html/article_rules/description.rb
|
|
389
393
|
- lib/html2rss/html/article_rules/enclosure.rb
|
|
390
394
|
- lib/html2rss/html/article_rules/image.rb
|
|
395
|
+
- lib/html2rss/html/card_walk.rb
|
|
396
|
+
- lib/html2rss/html/feed_link.rb
|
|
391
397
|
- lib/html2rss/html/navigator.rb
|
|
392
398
|
- lib/html2rss/html/navigator/text_extractor.rb
|
|
393
399
|
- lib/html2rss/html/rendering.rb
|
|
@@ -405,12 +411,17 @@ files:
|
|
|
405
411
|
- lib/html2rss/link_destination/path_classifier.rb
|
|
406
412
|
- lib/html2rss/link_destination/text_classifier.rb
|
|
407
413
|
- lib/html2rss/mcp.rb
|
|
414
|
+
- lib/html2rss/mcp/config_argument.rb
|
|
415
|
+
- lib/html2rss/mcp/contract.rb
|
|
416
|
+
- lib/html2rss/mcp/inspect.rb
|
|
417
|
+
- lib/html2rss/mcp/outcome.rb
|
|
408
418
|
- lib/html2rss/mcp/server.rb
|
|
409
419
|
- lib/html2rss/request_service.rb
|
|
410
420
|
- lib/html2rss/request_service/blocked_surface.rb
|
|
411
421
|
- lib/html2rss/request_service/botasaurus_contract.rb
|
|
412
422
|
- lib/html2rss/request_service/botasaurus_strategy.rb
|
|
413
423
|
- lib/html2rss/request_service/budget.rb
|
|
424
|
+
- lib/html2rss/request_service/compressed_body.rb
|
|
414
425
|
- lib/html2rss/request_service/context.rb
|
|
415
426
|
- lib/html2rss/request_service/faraday_strategy.rb
|
|
416
427
|
- lib/html2rss/request_service/local_file_strategy.rb
|
|
@@ -475,7 +486,7 @@ licenses:
|
|
|
475
486
|
- MIT
|
|
476
487
|
metadata:
|
|
477
488
|
allowed_push_host: https://rubygems.org
|
|
478
|
-
changelog_uri: https://github.com/html2rss/html2rss/releases/tag/v0.
|
|
489
|
+
changelog_uri: https://github.com/html2rss/html2rss/releases/tag/v0.27.1
|
|
479
490
|
rubygems_mfa_required: 'true'
|
|
480
491
|
rdoc_options: []
|
|
481
492
|
require_paths:
|