Class: TWPipeline::Sources::HPLT
- Inherits:
-
Object
- Object
- TWPipeline::Sources::HPLT
- Defined in:
- lib/twpipeline/sources/hplt.rb,
sig/twpipeline.rbs
Defined Under Namespace
Classes: Decision
Constant Summary collapse
- EXCLUDED_TLDS =
%w[cn hk mo sg my].to_set.freeze
- TAIWAN_TLD =
"tw"- TAIWAN_LANG =
/\Azh-(?:TW|Hant-TW)\b/i- URL_HEAD =
4096- URL =
/"u":"([^"]*)"/n- HTML_LANG =
/"html_lang":\[([^\]]*)\]/n- REGISTERS =
%w[MT LY SP ID NA HI IN OP IP].freeze
Class Method Summary collapse
Instance Method Summary collapse
- #build(line, decision) ⇒ record
- #decide(line) ⇒ Decision
- #each_record(io) {|arg0| ... } ⇒ Object
- #host_of(line) ⇒ ::String?
-
#initialize(allowlist: Set.new) ⇒ HPLT
constructor
A new instance of HPLT.
- #probe(line, size) ⇒ ::String
- #register(document) ⇒ ::String?
- #score(document) ⇒ ::Float?
- #taiwan_lang?(line) ⇒ Boolean
Constructor Details
#initialize(allowlist: Set.new) ⇒ HPLT
Returns a new instance of HPLT.
18 19 20 |
# File 'lib/twpipeline/sources/hplt.rb', line 18 def initialize(allowlist: Set.new) @allowlist = allowlist end |
Class Method Details
.allowlist(path) ⇒ ::Set[::String]
104 105 106 107 108 |
# File 'lib/twpipeline/sources/hplt.rb', line 104 def allowlist(path) return Set.new if path.nil? || !Pathname(path).exist? Pathname(path).each_line.map { |line| line.strip.downcase }.reject(&:empty?).to_set end |
.open(path) {|arg0| ... } ⇒ Object
99 100 101 102 |
# File 'lib/twpipeline/sources/hplt.rb', line 99 def open(path, &block) command = path.to_s.end_with?(".zst") ? ["zstd", "-dc", "-T0", path.to_s] : ["cat", path.to_s] IO.popen(command, "rb") { |io| block.call(io) } end |
Instance Method Details
#build(line, decision) ⇒ record
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/twpipeline/sources/hplt.rb', line 65 def build(line, decision) document = Jsonl.parse(line.dup.force_encoding(Encoding::UTF_8).scrub) { id: document[:id], source: "hplt", url: document[:u], host: decision.host, gate: decision.gate.to_s, keep: decision.keep, crawl: document[:crawl_id], html_lang: document[:html_lang], lang: Array(document[:lang]).first, lang_prob: Array(document[:prob]).first, doc_score: score(document), register: register(document), text: document[:text].to_s, ok: true, findings: [] } end |
#decide(line) ⇒ Decision
33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/twpipeline/sources/hplt.rb', line 33 def decide(line) host = host_of(line) return Decision.new(keep: false, gate: :excluded, host: host) if host.nil? labels = host.split(".") tld = labels.last return Decision.new(keep: false, gate: :excluded, host: host) if EXCLUDED_TLDS.include?(tld) return Decision.new(keep: true, gate: :tld, host: host) if tld == TAIWAN_TLD return Decision.new(keep: true, gate: :allowlist, host: host) if @allowlist.include?(host) return Decision.new(keep: true, gate: :html_lang, host: host) if taiwan_lang?(line) Decision.new(keep: false, gate: :residue, host: host) end |
#each_record(io) ⇒ void #each_record(io) ⇒ ::Enumerator[record, void]
22 23 24 25 26 27 28 29 30 31 |
# File 'lib/twpipeline/sources/hplt.rb', line 22 def each_record(io) return to_enum(:each_record, io) unless block_given? io.each_line do |line| decision = decide(line) next if decision.gate == :excluded yield build(line, decision) if decision.keep || decision.gate == :residue end end |
#host_of(line) ⇒ ::String?
47 48 49 50 51 52 53 54 |
# File 'lib/twpipeline/sources/hplt.rb', line 47 def host_of(line) url = probe(line, URL_HEAD)[URL, 1] || line[URL, 1] return nil if url.nil? URI.parse(url).host&.downcase&.delete_prefix("www.") rescue URI::InvalidURIError url[%r{\Ahttps?://([^/:?#]+)}i, 1]&.downcase&.delete_prefix("www.") end |
#probe(line, size) ⇒ ::String
56 |
# File 'lib/twpipeline/sources/hplt.rb', line 56 def probe(line, size) = line.byteslice(0, size).force_encoding(Encoding::BINARY) |
#register(document) ⇒ ::String?
91 92 93 94 95 96 |
# File 'lib/twpipeline/sources/hplt.rb', line 91 def register(document) labels = document[:"web-register"] return nil unless labels.is_a?(Hash) labels.max_by { |_, value| value.to_f }&.first&.to_s end |
#score(document) ⇒ ::Float?
86 87 88 89 |
# File 'lib/twpipeline/sources/hplt.rb', line 86 def score(document) scores = Array(document[:doc_scores]).grep(Numeric) scores.empty? ? nil : (scores.sum / scores.length.to_f).round(2) end |
#taiwan_lang?(line) ⇒ Boolean
58 59 60 61 62 63 |
# File 'lib/twpipeline/sources/hplt.rb', line 58 def taiwan_lang?(line) captured = line[HTML_LANG, 1] return false if captured.nil? captured.scan(/"([^"]*)"/).flatten.any? { |tag| tag.match?(TAIWAN_LANG) } end |