substrate 0.1.0 → 0.2.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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/lib/substrate/classify.rb +65 -0
  3. data/lib/substrate/cli/availability.rb +11 -0
  4. data/lib/substrate/cli/error.rb +7 -0
  5. data/lib/substrate/cli/runner.rb +31 -0
  6. data/lib/substrate/command.rb +24 -0
  7. data/lib/substrate/configuration.rb +21 -0
  8. data/lib/substrate/detection/path_resolver.rb +33 -0
  9. data/lib/substrate/distill.rb +31 -0
  10. data/lib/substrate/extract_pdf.rb +95 -0
  11. data/lib/substrate/handlers/article.rb +39 -0
  12. data/lib/substrate/handlers/pdf.rb +29 -0
  13. data/lib/substrate/handlers/raw_text.rb +22 -0
  14. data/lib/substrate/handlers/text_file.rb +26 -0
  15. data/lib/substrate/handlers/transcript.rb +48 -0
  16. data/lib/substrate/mediums/pdf/chapter.rb +9 -0
  17. data/lib/substrate/mediums/pdf/content.rb +13 -0
  18. data/lib/substrate/mediums/pdf/destination.rb +9 -0
  19. data/lib/substrate/mediums/pdf/destination_resolver.rb +131 -0
  20. data/lib/substrate/mediums/pdf/document.rb +46 -0
  21. data/lib/substrate/mediums/pdf/encrypted_pdf.rb +9 -0
  22. data/lib/substrate/mediums/pdf/entry.rb +9 -0
  23. data/lib/substrate/mediums/pdf/invalid_pdf.rb +9 -0
  24. data/lib/substrate/mediums/pdf/invalid_text.rb +9 -0
  25. data/lib/substrate/mediums/pdf/limit_exceeded.rb +17 -0
  26. data/lib/substrate/mediums/pdf/limits.rb +21 -0
  27. data/lib/substrate/mediums/pdf/named_destinations.rb +94 -0
  28. data/lib/substrate/mediums/pdf/no_selectable_text.rb +9 -0
  29. data/lib/substrate/mediums/pdf/outline.rb +9 -0
  30. data/lib/substrate/mediums/pdf/outline_facts.rb +115 -0
  31. data/lib/substrate/mediums/pdf/outline_parser.rb +67 -0
  32. data/lib/substrate/mediums/pdf/page.rb +9 -0
  33. data/lib/substrate/mediums/pdf/page_extractor.rb +28 -0
  34. data/lib/substrate/mediums/pdf/reader.rb +40 -0
  35. data/lib/substrate/mediums/pdf/text_extractor.rb +36 -0
  36. data/lib/substrate/primitives/article_content.rb +10 -0
  37. data/lib/substrate/primitives/extraction.rb +5 -0
  38. data/lib/substrate/primitives/metadata.rb +21 -0
  39. data/lib/substrate/primitives/page_collection.rb +5 -0
  40. data/lib/substrate/primitives/pdf_file.rb +5 -0
  41. data/lib/substrate/primitives/raw_text.rb +5 -0
  42. data/lib/substrate/primitives/source.rb +5 -0
  43. data/lib/substrate/primitives/text_content.rb +5 -0
  44. data/lib/substrate/primitives/text_file.rb +5 -0
  45. data/lib/substrate/primitives/transcripts/content.rb +11 -0
  46. data/lib/substrate/primitives/transcripts/metadata.rb +25 -0
  47. data/lib/substrate/primitives/transcripts/segment.rb +25 -0
  48. data/lib/substrate/primitives/transcripts/word.rb +23 -0
  49. data/lib/substrate/primitives/url_candidate.rb +13 -0
  50. data/lib/substrate/source_ref.rb +5 -0
  51. data/lib/substrate/sources/article.rb +34 -0
  52. data/lib/substrate/sources/audio.rb +57 -0
  53. data/lib/substrate/sources/pdf.rb +35 -0
  54. data/lib/substrate/sources/text.rb +23 -0
  55. data/lib/substrate/sources/url.rb +36 -0
  56. data/lib/substrate/transcribers/deepgram/client.rb +70 -0
  57. data/lib/substrate/transcribers/deepgram/configuration.rb +41 -0
  58. data/lib/substrate/transcribers/deepgram/response_parser.rb +102 -0
  59. data/lib/substrate/transcribers/deepgram.rb +45 -0
  60. data/lib/substrate/transcribers/whisper_cpp/response_parser.rb +66 -0
  61. data/lib/substrate/transcribers/whisper_cpp.rb +87 -0
  62. data/lib/substrate/transcripts/select_time_range.rb +59 -0
  63. data/lib/substrate/url_resolvers/generic.rb +71 -0
  64. data/lib/substrate/url_resolvers/resolver_for.rb +35 -0
  65. data/lib/substrate/version.rb +1 -1
  66. data/lib/substrate.rb +16 -3
  67. metadata +106 -1
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Substrate
4
+ module Transcripts
5
+ class SelectTimeRange < Command
6
+ def initialize(content:, range:)
7
+ @content = content
8
+ @range = range
9
+ end
10
+
11
+ def call
12
+ success(payload: Content.new(
13
+ source_ref: content.source_ref,
14
+ segments: selected_segments,
15
+ metadata: content.metadata
16
+ ))
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :content, :range
22
+
23
+ def selected_segments
24
+ content.segments.filter_map do |segment|
25
+ next unless overlaps?(segment)
26
+
27
+ selected_segment(segment)
28
+ end
29
+ end
30
+
31
+ def selected_segment(segment)
32
+ words = selected_words(segment.words)
33
+
34
+ Segment.new(
35
+ text: selected_text(segment, words),
36
+ start: [segment.start, range.begin].max,
37
+ end: [segment.end, range.end].min,
38
+ confidence: segment.confidence,
39
+ speaker: segment.speaker,
40
+ words: words
41
+ )
42
+ end
43
+
44
+ def selected_words(words)
45
+ words.select { |word| overlaps?(word) }
46
+ end
47
+
48
+ def selected_text(segment, words)
49
+ return words.map(&:text).join(" ") if words.any?
50
+
51
+ segment.text
52
+ end
53
+
54
+ def overlaps?(timed_item)
55
+ timed_item.start < range.end && timed_item.end > range.begin
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Substrate
4
+ module UrlResolvers
5
+ class Generic < Command
6
+ def initialize(url:)
7
+ @url = url
8
+ end
9
+
10
+ def call
11
+ result = Nous.fetch(url, details: true)
12
+ page = result.pages.first
13
+
14
+ return success(payload: []) unless page
15
+
16
+ metadata = build_metadata(page)
17
+ article = build_article(page, metadata)
18
+ candidate = build_candidate(article, page, metadata)
19
+
20
+ success(payload: [candidate])
21
+ rescue
22
+ success(payload: [])
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :url
28
+
29
+ def build_metadata(page)
30
+ Metadata.new(
31
+ requested_url: page.metadata[:requested_url],
32
+ final_url: page.url,
33
+ redirected: page.metadata[:redirected],
34
+ content_type: page.metadata[:content_type],
35
+ extractor: page.metadata[:extractor]
36
+ )
37
+ end
38
+
39
+ def build_article(page, metadata)
40
+ Sources::Article.new(
41
+ url: url,
42
+ text: page.content,
43
+ title: page.title,
44
+ metadata: metadata
45
+ )
46
+ end
47
+
48
+ def build_candidate(article, page, metadata)
49
+ UrlCandidate.new(
50
+ id: candidate_id(url, page),
51
+ kind: :article,
52
+ source: article,
53
+ rank: 1,
54
+ confidence: confidence_for(page),
55
+ label: "Article",
56
+ metadata: metadata
57
+ )
58
+ end
59
+
60
+ def candidate_id(url, page)
61
+ Digest::MD5.hexdigest("#{url}:#{page.title}")
62
+ end
63
+
64
+ def confidence_for(page)
65
+ return 0.5 unless page.title && page.content
66
+
67
+ (page.title.empty? || page.content.empty?) ? 0.5 : 0.8
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
4
+
5
+ module Substrate
6
+ module UrlResolvers
7
+ class ResolverFor < Command
8
+ class ResolutionError < StandardError; end
9
+
10
+ def initialize(url:)
11
+ @url = url
12
+ end
13
+
14
+ def call
15
+ resolver = resolver_for(uri)
16
+ result = resolver.call(url: url)
17
+ raise ResolutionError, result.error.message unless result.success?
18
+
19
+ success(payload: result.payload)
20
+ end
21
+
22
+ private
23
+
24
+ attr_reader :url
25
+
26
+ def uri
27
+ @uri ||= URI.parse(url)
28
+ end
29
+
30
+ def resolver_for(_uri)
31
+ Generic
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Substrate
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/substrate.rb CHANGED
@@ -1,8 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "substrate/version"
3
+ require "zeitwerk"
4
+ require "digest"
5
+ require "nous"
6
+ require "uri"
4
7
 
5
8
  module Substrate
6
- class Error < StandardError; end
7
- # Your code goes here...
9
+ class << self
10
+ def loader
11
+ @loader ||= begin
12
+ loader = Zeitwerk::Loader.for_gem
13
+ loader.inflector.inflect("pdf" => "Pdf")
14
+ loader.collapse("#{__dir__}/substrate/primitives")
15
+ loader
16
+ end
17
+ end
18
+ end
19
+
20
+ loader.setup
8
21
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: substrate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Frenette
@@ -9,8 +9,36 @@ bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: faraday
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
12
26
  - !ruby/object:Gem::Dependency
13
27
  name: hexapdf
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: 1.11.1
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 1.11.1
40
+ - !ruby/object:Gem::Dependency
41
+ name: marcel
14
42
  requirement: !ruby/object:Gem::Requirement
15
43
  requirements:
16
44
  - - ">="
@@ -23,6 +51,20 @@ dependencies:
23
51
  - - ">="
24
52
  - !ruby/object:Gem::Version
25
53
  version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: nous
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 0.5.0
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: 0.5.0
26
68
  - !ruby/object:Gem::Dependency
27
69
  name: zeitwerk
28
70
  requirement: !ruby/object:Gem::Requirement
@@ -42,6 +84,69 @@ extensions: []
42
84
  extra_rdoc_files: []
43
85
  files:
44
86
  - lib/substrate.rb
87
+ - lib/substrate/classify.rb
88
+ - lib/substrate/cli/availability.rb
89
+ - lib/substrate/cli/error.rb
90
+ - lib/substrate/cli/runner.rb
91
+ - lib/substrate/command.rb
92
+ - lib/substrate/configuration.rb
93
+ - lib/substrate/detection/path_resolver.rb
94
+ - lib/substrate/distill.rb
95
+ - lib/substrate/extract_pdf.rb
96
+ - lib/substrate/handlers/article.rb
97
+ - lib/substrate/handlers/pdf.rb
98
+ - lib/substrate/handlers/raw_text.rb
99
+ - lib/substrate/handlers/text_file.rb
100
+ - lib/substrate/handlers/transcript.rb
101
+ - lib/substrate/mediums/pdf/chapter.rb
102
+ - lib/substrate/mediums/pdf/content.rb
103
+ - lib/substrate/mediums/pdf/destination.rb
104
+ - lib/substrate/mediums/pdf/destination_resolver.rb
105
+ - lib/substrate/mediums/pdf/document.rb
106
+ - lib/substrate/mediums/pdf/encrypted_pdf.rb
107
+ - lib/substrate/mediums/pdf/entry.rb
108
+ - lib/substrate/mediums/pdf/invalid_pdf.rb
109
+ - lib/substrate/mediums/pdf/invalid_text.rb
110
+ - lib/substrate/mediums/pdf/limit_exceeded.rb
111
+ - lib/substrate/mediums/pdf/limits.rb
112
+ - lib/substrate/mediums/pdf/named_destinations.rb
113
+ - lib/substrate/mediums/pdf/no_selectable_text.rb
114
+ - lib/substrate/mediums/pdf/outline.rb
115
+ - lib/substrate/mediums/pdf/outline_facts.rb
116
+ - lib/substrate/mediums/pdf/outline_parser.rb
117
+ - lib/substrate/mediums/pdf/page.rb
118
+ - lib/substrate/mediums/pdf/page_extractor.rb
119
+ - lib/substrate/mediums/pdf/reader.rb
120
+ - lib/substrate/mediums/pdf/text_extractor.rb
121
+ - lib/substrate/primitives/article_content.rb
122
+ - lib/substrate/primitives/extraction.rb
123
+ - lib/substrate/primitives/metadata.rb
124
+ - lib/substrate/primitives/page_collection.rb
125
+ - lib/substrate/primitives/pdf_file.rb
126
+ - lib/substrate/primitives/raw_text.rb
127
+ - lib/substrate/primitives/source.rb
128
+ - lib/substrate/primitives/text_content.rb
129
+ - lib/substrate/primitives/text_file.rb
130
+ - lib/substrate/primitives/transcripts/content.rb
131
+ - lib/substrate/primitives/transcripts/metadata.rb
132
+ - lib/substrate/primitives/transcripts/segment.rb
133
+ - lib/substrate/primitives/transcripts/word.rb
134
+ - lib/substrate/primitives/url_candidate.rb
135
+ - lib/substrate/source_ref.rb
136
+ - lib/substrate/sources/article.rb
137
+ - lib/substrate/sources/audio.rb
138
+ - lib/substrate/sources/pdf.rb
139
+ - lib/substrate/sources/text.rb
140
+ - lib/substrate/sources/url.rb
141
+ - lib/substrate/transcribers/deepgram.rb
142
+ - lib/substrate/transcribers/deepgram/client.rb
143
+ - lib/substrate/transcribers/deepgram/configuration.rb
144
+ - lib/substrate/transcribers/deepgram/response_parser.rb
145
+ - lib/substrate/transcribers/whisper_cpp.rb
146
+ - lib/substrate/transcribers/whisper_cpp/response_parser.rb
147
+ - lib/substrate/transcripts/select_time_range.rb
148
+ - lib/substrate/url_resolvers/generic.rb
149
+ - lib/substrate/url_resolvers/resolver_for.rb
45
150
  - lib/substrate/version.rb
46
151
  licenses: []
47
152
  metadata: {}