Module: Sfdown::Metadata
- Defined in:
- lib/sfdown.rb
Overview
Serializes the Node tree to metadata.json: recursive and filesystem-like, enough to rebuild the tree and bootstrap stage 2 without re-scraping.
Constant Summary collapse
- Error =
Class.new(StandardError)
Class Method Summary collapse
- .join(parent, name) ⇒ Object
- .node_from(h, path) ⇒ Object
- .parse_ts(str) ⇒ Object
-
.read(file) ⇒ Object
Rebuild the root Node tree from a metadata file.
- .to_h(node) ⇒ Object
- .write(root, path) ⇒ Object
Class Method Details
.join(parent, name) ⇒ Object
698 699 700 |
# File 'lib/sfdown.rb', line 698 def join(parent, name) parent.empty? ? name.to_s : "#{parent}/#{name}" end |
.node_from(h, path) ⇒ Object
684 685 686 687 688 689 690 691 692 693 694 695 696 |
# File 'lib/sfdown.rb', line 684 def node_from(h, path) Node.new( name: h["name"], type: h["type"] == "d" ? :d : :f, path: path, timestamp: parse_ts(h["timestamp"]), size: h["size"] || 0, downloads: h["downloads"] || 0, md5: h["md5"], sha1: h["sha1"], children: Array(h["content"]).map { |c| node_from(c, join(path, c["name"])) } ) end |
.parse_ts(str) ⇒ Object
702 703 704 705 706 |
# File 'lib/sfdown.rb', line 702 def parse_ts(str) str && !str.empty? ? Time.parse(str).utc : nil rescue ArgumentError nil end |
.read(file) ⇒ Object
Rebuild the root Node tree from a metadata file. Paths aren't stored in the JSON, so they're reconstructed from the tree structure (root path = ""). Raises Metadata::Error on a structurally invalid document; lets Errno::ENOENT / JSON::ParserError propagate to the caller.
675 676 677 678 679 680 681 682 |
# File 'lib/sfdown.rb', line 675 def read(file) data = JSON.parse(File.read(file)) unless data.is_a?(Hash) && data["name"] && data["type"] == "d" raise Error, "not a valid sfdown metadata document (expected a directory root object)" end node_from(data, "") end |
.to_h(node) ⇒ Object
651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 |
# File 'lib/sfdown.rb', line 651 def to_h(node) h = { "name" => node.name, "type" => node.type.to_s, "size" => node.size, "downloads" => node.downloads, "timestamp" => node.&.strftime("%Y-%m-%d %H:%M:%S UTC") } if node.file? h["md5"] = node.md5 if node.md5 h["sha1"] = node.sha1 if node.sha1 end h["content"] = node.children.map { |c| to_h(c) } h end |