Module: Eco::Data::Locations::NodeLevel::Cleaner

Includes:
Convert, Language::AuxiliarLogger
Included in:
Parsing, Serial
Defined in:
lib/eco/data/locations/node_level/cleaner.rb

Instance Attribute Summary

Attributes included from Language::AuxiliarLogger

#logger

Instance Method Summary collapse

Methods included from Convert

#csv_from, #empty_array, #empty_level_tracker_hash, #hash_tree_to_tree_csv, #log_pretty_inspect, #normalize_arrays, #report_repeated_node_ids

Methods included from Language::AuxiliarLogger

#log

Instance Method Details

#done_idsObject

Tracker helper (those done)



68
69
70
# File 'lib/eco/data/locations/node_level/cleaner.rb', line 68

def done_ids
  @done_ids ||= []
end

#fill_in_parents(nodes) ⇒ Object

Sets the parentId property. Although with normalized nodes parents are self-contained we use this method



50
51
52
53
54
55
56
57
58
59
60
# File 'lib/eco/data/locations/node_level/cleaner.rb', line 50

def fill_in_parents(nodes)
  nodes.tap do |nodes|
    prev_nodes = empty_level_tracker_hash(11)
    nodes.each do |node|
      if parent_node = prev_nodes[node.actual_level - 1]
        node.parentId = parent_node.id
      end
      prev_nodes[node.raw_level] = node
    end
  end
end

#repeated_idsObject

Tracker helper (those repeated)



63
64
65
# File 'lib/eco/data/locations/node_level/cleaner.rb', line 63

def repeated_ids
  @repeated_ids ||= []
end

#reset_trackers!Object



72
73
74
75
# File 'lib/eco/data/locations/node_level/cleaner.rb', line 72

def reset_trackers!
  @done_ids     = []
  @repeated_ids = []
end

#tidy_nodes(nodes, prev_level: 0, main: true) ⇒ Array<NodeLevel>

Note:
  1. It first discards node ids/tags that have been already pulled (discard repeated)
  2. For non repeated, it identifies if there's a gap (jump of multiple levels)
  3. It covers the gap if present by decoupling merged parent(s) from the same node (see node.decouple)
  4. Then, it delegates the filling in of parents to fill_in_parents function.

Prevents repeated node ids/tags, decouples merged levels, covers gaps (jumping multiple levels)

Returns:

  • (Array<NodeLevel>)

    child to parent relationships solved and no double-ups.



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
# File 'lib/eco/data/locations/node_level/cleaner.rb', line 14

def tidy_nodes(nodes, prev_level: 0, main: true)
  reset_trackers! if main
  nodes.each_with_object([]) do |node, out|
    node_id = node.id
    if done_ids.include?(node_id)
      repeated_ids << "#{node_id} (level: #{node.level})"
    else
      level = node.actual_level
      if level > prev_level + 1
        gap = level - (prev_level + 1)
        msg = "(Row: #{node.row_num}) ID/Tag '#{node_id}' (lev #{level}) jumps #{gap} level(s) (expected #{prev_level + 1})."
        #puts "  " + node.tags_array.pretty_inspect
        missing_nodes = node.decouple(gap)

        msg << "\n  Adding missing upper level(s): " + missing_nodes.map(&:raw_tag).pretty_inspect
        log(:info) { msg }

        # The very top missing node (first in list) should be checked against prev_level
        # alongside any descendants in missing_nodes (when gap 2+)
        tidied_nodes = tidy_nodes(missing_nodes, prev_level: prev_level, main: false)
        out.push(*tidied_nodes)
        #level = prev_level + 1 # <= we are actually on level and filled in the gaps
      end
      out       << node
      done_ids  << node_id
      prev_level = level
    end
  end.yield_self do |out|
    report_repeated_node_ids(repeated_ids) if main
    fill_in_parents(out)
  end
end