Class: Eco::API::Organization::TagTree
- Inherits:
-
Object
- Object
- Eco::API::Organization::TagTree
- Defined in:
- lib/eco/api/organization/tag_tree.rb
Overview
Provides helpers to deal with tagtrees.
Instance Attribute Summary collapse
-
#children_count ⇒ Object
readonly
Returns the value of attribute children_count.
-
#depth ⇒ Object
readonly
Returns the value of attribute depth.
-
#enviro ⇒ Object
readonly
Returns the value of attribute enviro.
-
#nodes ⇒ Object
readonly
Returns the value of attribute nodes.
-
#path(key = nil) ⇒ Array<String>
readonly
Finds the path from a node
key
to its root node in the tree. -
#tag ⇒ Object
Returns the value of attribute tag.
Instance Method Summary collapse
-
#as_json ⇒ Array[Hash]
Where
Hash
is anode
{"tag" => TAG, "nodes": Array[Hash]}
. -
#default_tag(*values) ⇒ String
Helper to decide which among the tags will be the default.
-
#diff(tagtree, differences: {}, level: 0, **options) ⇒ Array
With the differences.
- #dup ⇒ Eco::API::Organization::TagTree
-
#empty? ⇒ Boolean
true
if there are tags in the node,false
otherwise. -
#filter_tags(list) ⇒ Array<String>
Filters tags out that do not belong to the tree.
-
#flat? ⇒ Integer
If there's only top level.
-
#initialize(tagtree = [], depth: -1,, path: [], enviro: nil) ⇒ TagTree
constructor
A new instance of TagTree.
-
#node(key) ⇒ TagTree?
Finds a subtree node.
-
#subtag?(key) ⇒ Boolean
Verifies if a tag exists in the subtree(s).
-
#subtags ⇒ Array<String>
Gets all but the upper level tags of the current node tree.
-
#tag?(key) ⇒ Boolean
Verifies if a tag exists in the tree.
-
#tags(depth: nil) ⇒ Array<String>
Gets all the tags of the current node tree.
- #top? ⇒ Boolean
-
#total_depth ⇒ Integer
The highest
depth
of all the children. -
#user_tags(initial: [], final: [], preserve_custom: true, add_custom: false) ⇒ Array<String>
Helper to assign tags to a person account.
Constructor Details
#initialize(tagtree = [], depth: -1,, path: [], enviro: nil) ⇒ TagTree
Returns a new instance of TagTree.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/eco/api/organization/tag_tree.rb', line 21 def initialize(tagtree = [], depth: -1, path: [], enviro: nil) case tagtree when String @source = JSON.parse(tagtree) else @source = tagtree end fatal("You are trying to initialize a TagTree with a null tagtree") if !@source fatal("Expecting Environment object. Given: #{enviro}") if enviro && !enviro.is_a?(API::Common::Session::Environment) @enviro = enviro @depth = depth @tag = @source.is_a?(Array) ? nil : @source.dig('tag')&.upcase @path = path || [] @path.push(@tag) unless !@tag nodes = @source.is_a?(Array) ? @source : @source.dig('nodes') || [] @nodes = nodes.map {|cnode| TagTree.new(cnode, depth: @depth + 1, path: @path.dup, enviro: @enviro)} @children_count = @nodes.count init_hashes end |
Instance Attribute Details
#children_count ⇒ Object (readonly)
Returns the value of attribute children_count.
7 8 9 |
# File 'lib/eco/api/organization/tag_tree.rb', line 7 def children_count @children_count end |
#depth ⇒ Object (readonly)
Returns the value of attribute depth.
8 9 10 |
# File 'lib/eco/api/organization/tag_tree.rb', line 8 def depth @depth end |
#enviro ⇒ Object (readonly)
Returns the value of attribute enviro.
9 10 11 |
# File 'lib/eco/api/organization/tag_tree.rb', line 9 def enviro @enviro end |
#nodes ⇒ Object (readonly)
Returns the value of attribute nodes.
7 8 9 |
# File 'lib/eco/api/organization/tag_tree.rb', line 7 def nodes @nodes end |
#path(key = nil) ⇒ Array<String> (readonly)
the path
is not relative to the subtree, but absolute to the entire tree.
Finds the path from a node key
to its root node in the tree.
If key
is not specified, returns the path from current node to root.
155 156 157 |
# File 'lib/eco/api/organization/tag_tree.rb', line 155 def path @path end |
#tag ⇒ Object
Returns the value of attribute tag.
7 8 9 |
# File 'lib/eco/api/organization/tag_tree.rb', line 7 def tag @tag end |
Instance Method Details
#as_json ⇒ Array[Hash]
Returns where Hash
is a node
{"tag" => TAG, "nodes": Array[Hash]}
.
66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/eco/api/organization/tag_tree.rb', line 66 def as_json nodes_json = nodes.map {|node| node.as_json} if top? nodes_json else { "tag" => tag, "nodes" => nodes_json } end end |
#default_tag(*values) ⇒ String
Helper to decide which among the tags will be the default.
- take the deepest tag (the one that is further down in the tree)
- if there are different options (several nodes at the same depth):
- take the common node between them (i.e. you have Hamilton and Auckland -> take New Zealand)
- if there's no common node between them, take the
first
, unless they are at top level of the tree - to the above, take the
first
also on top level, but only if there's 1 level for the entire tree
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/eco/api/organization/tag_tree.rb', line 203 def default_tag(*values) values = (values) nodes = []; depth = -1 values.each do |tag| raise("Couldn't find the node of #{tag} in the tag-tree definition") unless cnode = node(tag) if cnode.depth > depth nodes = [cnode] depth = cnode.depth elsif cnode.depth == depth nodes.push(cnode) end end default_tag = nil if nodes.length > 1 common = nodes.reduce(self..reverse) {|com, cnode| com & cnode.path.reverse} default_tag = common.first if common.length > 0 && depth > 0 end default_tag = nodes.first&.tag if !default_tag && ( (depth > 0) || flat?) default_tag end |
#diff(tagtree, differences: {}, level: 0, **options) ⇒ Array
Returns with the differences.
56 57 58 59 |
# File 'lib/eco/api/organization/tag_tree.rb', line 56 def diff(tagtree, differences: {}, level: 0, **) require 'hashdiff' Hashdiff.diff(self.as_json, tagtree.as_json, **.slice(:array_path, :similarity, :use_lcs)) end |
#dup ⇒ Eco::API::Organization::TagTree
51 52 53 |
# File 'lib/eco/api/organization/tag_tree.rb', line 51 def dup self.class.new(as_json) end |
#empty? ⇒ Boolean
Returns true
if there are tags in the node, false
otherwise.
79 80 81 |
# File 'lib/eco/api/organization/tag_tree.rb', line 79 def empty? @has_tags.empty? end |
#filter_tags(list) ⇒ Array<String>
Filters tags out that do not belong to the tree
145 146 147 148 |
# File 'lib/eco/api/organization/tag_tree.rb', line 145 def (list) return [] unless list && list.is_a?(Array) list.select {|str| tag?(str)} end |
#flat? ⇒ Integer
Returns if there's only top level.
94 95 96 |
# File 'lib/eco/api/organization/tag_tree.rb', line 94 def flat? self.total_depth <= 0 end |
#node(key) ⇒ TagTree?
Finds a subtree node.
137 138 139 140 |
# File 'lib/eco/api/organization/tag_tree.rb', line 137 def node(key) return nil unless tag?(key) @hash_tags[key.upcase] end |
#subtag?(key) ⇒ Boolean
Verifies if a tag exists in the subtree(s).
123 124 125 |
# File 'lib/eco/api/organization/tag_tree.rb', line 123 def subtag?(key) .include?(key&.upcase) end |
#subtags ⇒ Array<String>
Gets all but the upper level tags of the current node tree.
116 117 118 |
# File 'lib/eco/api/organization/tag_tree.rb', line 116 def - (depth: depth) end |
#tag?(key) ⇒ Boolean
Verifies if a tag exists in the tree.
130 131 132 |
# File 'lib/eco/api/organization/tag_tree.rb', line 130 def tag?(key) @hash_tags.key?(key&.upcase) end |
#tags(depth: nil) ⇒ Array<String>
- this will include the upper level tag(s) as well
- to get all but the upper level tag(s) use
subtags
method instead
Gets all the tags of the current node tree.
104 105 106 107 108 109 110 111 112 |
# File 'lib/eco/api/organization/tag_tree.rb', line 104 def (depth: nil) if !depth || depth < 0 @hash_tags.keys else @hash_tags.select do |t, n| n.depth == depth end.keys end end |
#top? ⇒ Boolean
61 62 63 |
# File 'lib/eco/api/organization/tag_tree.rb', line 61 def top? depth == -1 end |
#total_depth ⇒ Integer
Returns the highest depth
of all the children.
84 85 86 87 88 89 90 91 |
# File 'lib/eco/api/organization/tag_tree.rb', line 84 def total_depth @total_depth ||= if children_count > 0 deepest_node = nodes.max_by {|node| node.total_depth} deepest_node.depth else depth end end |
#user_tags(initial: [], final: [], preserve_custom: true, add_custom: false) ⇒ Array<String>
Helper to assign tags to a person account.
- It preserves the
:initial
order, in case the:final
tags are the same
183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/eco/api/organization/tag_tree.rb', line 183 def (initial: [], final: [], preserve_custom: true, add_custom: false) initial = [initial].flatten.compact final = [final].flatten.compact raise "Expected Array for initial: and final:" unless initial.is_a?(Array) && final.is_a?(Array) final = (final) unless add_custom custom = initial - (initial) final = final + custom if preserve_custom = final - initial # keep same order as they where (initial & final) + end |