Module: Textus::Lanes::Ingest::Handlers

Defined in:
lib/textus/lanes/ingest/handlers.rb

Constant Summary collapse

SOURCE_KINDS =
%w[url file asset].freeze

Class Method Summary collapse

Class Method Details

.ingest(kind:, slug:, ctx:, call:, url: nil, path: nil, lane: nil, label: nil) ⇒ Object

Raises:



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/textus/lanes/ingest/handlers.rb', line 9

def ingest(kind:, slug:, ctx:, call:, url: nil, path: nil, lane: nil, label: nil)
  raise Textus::UsageError.new("kind must be one of #{SOURCE_KINDS.join("|")}") unless SOURCE_KINDS.include?(kind)

  case kind
  when "url"   then raise Textus::UsageError.new("url required") unless url
  when "file"  then raise Textus::UsageError.new("path required") unless path
  when "asset"
    raise Textus::UsageError.new("path required") unless path
    raise Textus::UsageError.new("lane required") unless lane
  end

  now = Time.now.utc
  key = KeyBuilder.derive_key(now, kind, slug)
  content_hash = KeyBuilder.compute_hash(kind:, url:, path:)

  entry_type = EntryTypes.for(kind)
  time = now
  structured = entry_type.build(url:, path:, lane:, label:, time:, layout: ctx.layout)

  lookup = Textus::Infra::Store::Index::Lookup.new(ctx.container.store.db)
  duplicate_key = Dedup.find(lookup, content_hash, url:)

  if duplicate_key && duplicate_key != key
    old_content = ctx.read(key: duplicate_key)&.content || {}
    Resolver.supersede(duplicate_key, key, ctx:, call:)

    EntryTypes::Asset.move(old_content["asset"], lane, ctx.layout) if (kind == "asset") && old_content["asset"]

    old_count = old_content["ingest_count"] || 1
    structured["ingest_count"] = old_count + 1
    structured["duplicated_at"] = now.utc.iso8601
    structured["supersedes"] = duplicate_key
  else
    structured["ingest_count"] = 1
  end

  env = ctx.put(key:, meta: {}, body: nil, content: structured, call:)

  IndexRebuilder.rebuild!(ctx.container.store.db, ctx.manifest.resolver)

  { "key" => key, "uid" => env.uid, "etag" => env.etag }
end