Class: Dubhe::Store

Inherits:
Object
  • Object
show all
Defined in:
lib/dubhe/store.rb,
sig/dubhe.rbs

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root: nil) ⇒ Store

Returns a new instance of Store.

Parameters:

  • root: (String, nil) (defaults to: nil)


12
13
14
15
16
17
18
# File 'lib/dubhe/store.rb', line 12

def initialize(root: nil)
  data_root = root || ENV["XDG_DATA_HOME"] || File.join(Dir.home, ".local", "share")
  @root = root ? File.expand_path(root.to_s) : File.join(data_root.to_s, "dubhe")
  @index_root = File.join(@root, "index")
  @body_root = File.join(@root, "bodies")
  FileUtils.mkdir_p([@index_root, @body_root])
end

Instance Attribute Details

#root ⇒ Object (readonly)

Returns the value of attribute root.



10
11
12
# File 'lib/dubhe/store.rb', line 10

def root
  @root
end

Instance Method Details

#body(id) ⇒ Object

Parameters:

  • id (String)

Returns:

  • (Object)


68
69
70
71
72
73
74
75
76
# File 'lib/dubhe/store.rb', line 68

def body(id)
  digest = Digest::SHA256.hexdigest(id.to_s)
  directory = File.join(@body_root, digest[0, 2], digest[2, 2])
  path = %w[html text markdown].map { |kind| File.join(directory, "#{digest}.#{kind}") }.find { |candidate| File.file?(candidate) }
  return nil unless path

  kind = File.extname(path).delete_prefix(".").to_sym
  Body.new(kind: kind, content: File.binread(path), base_url: nil, attachments: [], headers: {})
end

#compact! ⇒ Object



78
79
80
81
82
# File 'lib/dubhe/store.rb', line 78

def compact!
  rewrite("entries.jsonl", entries.map { |entry| serialize_entry(entry) })
  rewrite("state.jsonl", state_records.values)
  self
end

#entries(source_id: nil) ⇒ Array[untyped]

Parameters:

  • source_id: (String, nil) (defaults to: nil)

Returns:

  • (Array[untyped])


30
31
32
33
34
35
36
37
38
39
40
# File 'lib/dubhe/store.rb', line 30

def entries(source_id: nil)
  records = read_jsonl("entries.jsonl")
  latest = {}
  records.each { |record| latest[record["id"].to_s] = record }
  states = state_records
  latest.values.filter_map do |record|
    next if source_id && record["source_id"] != source_id

    deserialize_entry(record, states[record["id"].to_s])
  end
end

#entry(id) ⇒ Object

Parameters:

  • id (String)

Returns:

  • (Object)


42
43
44
# File 'lib/dubhe/store.rb', line 42

def entry(id)
  entries.find { |item| item.id == id.to_s }
end

#save_body(id, body) ⇒ String

Parameters:

  • id (String)
  • body (Object)

Returns:

  • (String)


55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/dubhe/store.rb', line 55

def save_body(id, body)
  digest = Digest::SHA256.hexdigest(id.to_s)
  directory = File.join(@body_root, digest[0, 2], digest[2, 2])
  FileUtils.mkdir_p(directory)
  path = File.join(directory, "#{digest}.#{extension(body.kind)}")
  temporary = "#{path}.tmp-#{Process.pid}-#{rand(1_000_000)}"
  File.binwrite(temporary, body.content.to_s)
  File.rename(temporary, path)
  path
ensure
  File.delete(temporary) if temporary && File.file?(temporary)
end

#save_entries(entries) ⇒ Object



25
26
27
28
# File 'lib/dubhe/store.rb', line 25

def save_entries(entries)
  Array(entries).each { |entry| save_entry(entry) }
  entries
end

#save_entry(entry) ⇒ Object

Parameters:

  • entry (Object)

Returns:

  • (Object)


20
21
22
23
# File 'lib/dubhe/store.rb', line 20

def save_entry(entry)
  append("entries.jsonl", serialize_entry(entry))
  entry
end

#update_state(id, state: nil, starred: nil, tags: nil) ⇒ Hash[String, untyped]

Parameters:

  • id (String)
  • state: (Symbol, nil) (defaults to: nil)
  • starred: (Boolean, nil) (defaults to: nil)
  • tags: (Array[String], nil) (defaults to: nil)

Returns:

  • (Hash[String, untyped])


46
47
48
49
50
51
52
53
# File 'lib/dubhe/store.rb', line 46

def update_state(id, state: nil, starred: nil, tags: nil)
  current = state_records[id.to_s] || {}
  record = {"id" => id.to_s, "state" => (state || current["state"] || "unread"),
    "starred" => starred.nil? ? current["starred"] : starred,
    "tags" => tags.nil? ? current["tags"] : tags}
  append("state.jsonl", record)
  record
end