nous 0.4.0 → 0.5.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.
- checksums.yaml +4 -4
- data/.agents/skills/verify-nous/SKILL.md +6 -0
- data/CHANGELOG.md +23 -1
- data/CODING_STANDARDS.md +203 -0
- data/README.md +104 -15
- data/Rakefile +2 -0
- data/docs/setup/defuddle.md +38 -0
- data/docs/setup/verification.md +21 -0
- data/docs/verification/README.md +77 -0
- data/docs/verification/defuddle.md +45 -0
- data/docs/verification/failure-propagation.md +37 -0
- data/docs/verification/retained-html.md +37 -0
- data/javascript/build.mjs +24 -0
- data/javascript/defuddle.mjs +28 -0
- data/lib/nous/cli.rb +3 -3
- data/lib/nous/crawler/recursive_page_fetcher.rb +25 -17
- data/lib/nous/decode_html.rb +80 -0
- data/lib/nous/extract_html.rb +109 -0
- data/lib/nous/extractor/default.rb +0 -2
- data/lib/nous/extractor/defuddle/client.rb +57 -0
- data/lib/nous/extractor/defuddle/run_process.rb +104 -0
- data/lib/nous/extractor/defuddle.rb +23 -0
- data/lib/nous/extractor/extraction_error.rb +7 -0
- data/lib/nous/fetcher/extraction_runner.rb +24 -9
- data/lib/nous/fetcher/page_extractor.rb +15 -6
- data/lib/nous/fetcher.rb +35 -25
- data/lib/nous/version.rb +1 -1
- data/lib/nous.rb +1 -1
- data/package-lock.json +858 -0
- data/package.json +15 -0
- data/tasks/verification.rake +23 -0
- data/vendor/THIRD_PARTY_LICENSES.txt +518 -0
- data/vendor/defuddle.mjs +403 -0
- data/vendor/defuddle.mjs.LEGAL.txt +10 -0
- metadata +23 -3
- data/lib/nous/extractor/jina/client.rb +0 -59
- data/lib/nous/extractor/jina.rb +0 -26
|
@@ -9,8 +9,22 @@ module Nous
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def call
|
|
12
|
-
|
|
12
|
+
extract_content
|
|
13
|
+
report_page
|
|
14
|
+
rescue => error
|
|
15
|
+
failure(error)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
attr_reader :extractor, :record
|
|
21
|
+
|
|
22
|
+
def extract_content
|
|
23
|
+
@extraction = extractor.extract(record)
|
|
24
|
+
end
|
|
13
25
|
|
|
26
|
+
def report_page
|
|
27
|
+
result = @extraction
|
|
14
28
|
unless result.success?
|
|
15
29
|
warn("[nous] extract skip #{record.final_url}: #{result.error.message}") if Nous.configuration.debug?
|
|
16
30
|
return failure(result.error)
|
|
@@ -28,13 +42,8 @@ module Nous
|
|
|
28
42
|
redirected: record.redirected
|
|
29
43
|
}
|
|
30
44
|
)
|
|
31
|
-
|
|
32
45
|
success(payload: page)
|
|
33
46
|
end
|
|
34
|
-
|
|
35
|
-
private
|
|
36
|
-
|
|
37
|
-
attr_reader :extractor, :record
|
|
38
47
|
end
|
|
39
48
|
end
|
|
40
49
|
end
|
data/lib/nous/fetcher.rb
CHANGED
|
@@ -4,50 +4,60 @@ module Nous
|
|
|
4
4
|
class Fetcher < Command
|
|
5
5
|
class FetchError < StandardError; end
|
|
6
6
|
|
|
7
|
-
def initialize(seed_url:, extractor: Extractor::
|
|
7
|
+
def initialize(seed_url:, extractor: Extractor::Defuddle.new, http_client: nil, details: false)
|
|
8
8
|
@seed_url = seed_url
|
|
9
9
|
@extractor = extractor
|
|
10
10
|
@http_client = http_client
|
|
11
|
-
@single_page = Nous.configuration.single_page?
|
|
12
11
|
@details = details
|
|
13
12
|
end
|
|
14
13
|
|
|
15
14
|
def call
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
resolve_fetch_mode
|
|
16
|
+
acquire_records
|
|
17
|
+
verify_acquisition
|
|
18
|
+
extract_readable_pages
|
|
19
|
+
report_fetch_outcomes
|
|
20
|
+
end
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
raise FetchError, failed_records.first&.error || "fetch failed"
|
|
21
|
-
end
|
|
22
|
+
private
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
attr_reader :seed_url, :extractor, :http_client, :single_page, :details
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
pages: pages,
|
|
28
|
-
failures: build_failures(failed_records),
|
|
29
|
-
total_requested: records.length
|
|
30
|
-
))
|
|
31
|
-
else
|
|
32
|
-
success(payload: pages)
|
|
33
|
-
end
|
|
26
|
+
def resolve_fetch_mode
|
|
27
|
+
@single_page = Nous.configuration.single_page?
|
|
34
28
|
end
|
|
35
29
|
|
|
36
|
-
|
|
30
|
+
def acquire_records
|
|
31
|
+
@records = crawl
|
|
32
|
+
@successful_records, @failed_records = @records.partition(&:ok)
|
|
33
|
+
end
|
|
37
34
|
|
|
38
|
-
|
|
35
|
+
def verify_acquisition
|
|
36
|
+
if single_page && !details && @successful_records.empty?
|
|
37
|
+
raise FetchError, @failed_records.first&.error || "fetch failed"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
39
40
|
|
|
40
|
-
def
|
|
41
|
-
|
|
42
|
-
raise
|
|
41
|
+
def extract_readable_pages
|
|
42
|
+
@extraction = ExtractionRunner.call(records: @successful_records, extractor:)
|
|
43
|
+
raise @extraction.error if @extraction.failure?
|
|
44
|
+
end
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
def report_fetch_outcomes
|
|
47
|
+
return success(payload: @extraction.payload) unless details
|
|
48
|
+
|
|
49
|
+
success(payload: FetchResult.new(
|
|
50
|
+
pages: @extraction.payload,
|
|
51
|
+
failures: build_failures(@failed_records) + @extraction.metadata.fetch(:failures),
|
|
52
|
+
total_requested: @total_requested
|
|
53
|
+
))
|
|
45
54
|
end
|
|
46
55
|
|
|
47
|
-
def
|
|
48
|
-
result =
|
|
56
|
+
def crawl
|
|
57
|
+
result = Crawler.call(seed_url:, http_client:)
|
|
49
58
|
raise FetchError, result.error.message if result.failure?
|
|
50
59
|
|
|
60
|
+
@total_requested = result.metadata.fetch(:total_requested, result.payload.length)
|
|
51
61
|
result.payload
|
|
52
62
|
end
|
|
53
63
|
|
data/lib/nous/version.rb
CHANGED
data/lib/nous.rb
CHANGED
|
@@ -18,7 +18,7 @@ module Nous
|
|
|
18
18
|
@configuration = nil
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
def fetch(seed_url, extractor: Extractor::
|
|
21
|
+
def fetch(seed_url, extractor: Extractor::Defuddle.new, http_client: nil, details: false, **options)
|
|
22
22
|
configure(**options)
|
|
23
23
|
|
|
24
24
|
result = Fetcher.call(seed_url:, extractor:, http_client:, details:)
|