Class: Eco::API::Organization::TagTree
- Inherits:
-
Object
- Object
- Eco::API::Organization::TagTree
- Includes:
- Enumerable
- Defined in:
- lib/eco/api/organization/tag_tree.rb
Overview
Provides helpers to deal with tagtrees.
Instance Attribute Summary collapse
-
#archived ⇒ Object
Returns the value of attribute archived.
-
#archived_token ⇒ Object
Returns the value of attribute archived_token.
- #children_count ⇒ Integer readonly
-
#depth ⇒ Object
readonly
Returns the value of attribute depth.
-
#enviro ⇒ Object
readonly
Returns the value of attribute enviro.
-
#id ⇒ Object
(also: #tag)
Returns the value of attribute id.
-
#name ⇒ Object
Returns the value of attribute name.
-
#nodes ⇒ Object
readonly
Returns the value of attribute nodes.
-
#parent ⇒ Object
readonly
Returns the value of attribute parent.
-
#path(key = nil) ⇒ Array<String>
readonly
Finds the path from a node
key
to its root node in the tree. -
#source ⇒ Object
readonly
Returns the value of attribute source.
-
#weight ⇒ Object
Returns the value of attribute weight.
Instance Method Summary collapse
-
#all_nodes(&block) ⇒ Array<TagTree>
All actual nodes of this tree.
-
#ancestors ⇒ Array<TagTree>
All the acenstor nodes of the current node.
- #archived? ⇒ Boolean
-
#as_json ⇒ Array[Hash]
Where
Hash
is anode
{"tag" => TAG, "nodes": Array[Hash]}
. -
#count ⇒ Integer
The number of locations.
-
#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
-
#each {|node| ... } ⇒ Enumerable<Eco::API::Organization::TagTree>
Iterate through all the nodes of this tree.
-
#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.
-
#has_children? ⇒ Boolean
It has subnodes.
-
#initialize(tagtree = [], name: nil, id: nil, depth: -1,, path: [], parent: nil, _weight: nil, enviro: nil) ⇒ TagTree
constructor
A new instance of TagTree.
-
#leafs ⇒ Array<String>
Returns all the tags with no children.
-
#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 = [], name: nil, id: nil, depth: -1,, path: [], parent: nil, _weight: nil, enviro: nil) ⇒ TagTree
Returns a new instance of TagTree.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/eco/api/organization/tag_tree.rb', line 30 def initialize(tagtree = [], name: nil, id: nil, depth: -1, path: [], parent: nil, _weight: nil, enviro: nil) @depth = depth @parent = parent 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 if @source.is_a?(Array) @id = id @name = name @raw_nodes = @source else @id = @source.values_at('tag', 'id').compact.first&.upcase @name = @source['name'] @archived = @source['archived'] || false @archived_token = @source['archived_token'] @source['weight'] = @weight = @source['weight'] || _weight @raw_nodes = @source['nodes'] || [] end @path = path || [] @path.push(@id) unless top? @nodes = @raw_nodes.map.with_index do |cnode, idx| TagTree.new(cnode, depth: depth + 1, path: @path.dup, parent: self, _weight: idx, enviro: @enviro) end init_hashes end |
Instance Attribute Details
#archived ⇒ Object
Returns the value of attribute archived.
9 10 11 |
# File 'lib/eco/api/organization/tag_tree.rb', line 9 def archived @archived end |
#archived_token ⇒ Object
Returns the value of attribute archived_token.
9 10 11 |
# File 'lib/eco/api/organization/tag_tree.rb', line 9 def archived_token @archived_token end |
#children_count ⇒ Integer (readonly)
203 204 205 |
# File 'lib/eco/api/organization/tag_tree.rb', line 203 def children_count @children_count end |
#depth ⇒ Object (readonly)
Returns the value of attribute depth.
13 14 15 |
# File 'lib/eco/api/organization/tag_tree.rb', line 13 def depth @depth end |
#enviro ⇒ Object (readonly)
Returns the value of attribute enviro.
14 15 16 |
# File 'lib/eco/api/organization/tag_tree.rb', line 14 def enviro @enviro end |
#id ⇒ Object Also known as: tag
Returns the value of attribute id.
6 7 8 |
# File 'lib/eco/api/organization/tag_tree.rb', line 6 def id @id end |
#name ⇒ Object
Returns the value of attribute name.
8 9 10 |
# File 'lib/eco/api/organization/tag_tree.rb', line 8 def name @name end |
#nodes ⇒ Object (readonly)
Returns the value of attribute nodes.
12 13 14 |
# File 'lib/eco/api/organization/tag_tree.rb', line 12 def nodes @nodes end |
#parent ⇒ Object (readonly)
Returns the value of attribute parent.
11 12 13 |
# File 'lib/eco/api/organization/tag_tree.rb', line 11 def parent @parent 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.
240 241 242 |
# File 'lib/eco/api/organization/tag_tree.rb', line 240 def path @path end |
#source ⇒ Object (readonly)
Returns the value of attribute source.
16 17 18 |
# File 'lib/eco/api/organization/tag_tree.rb', line 16 def source @source end |
#weight ⇒ Object
Returns the value of attribute weight.
8 9 10 |
# File 'lib/eco/api/organization/tag_tree.rb', line 8 def weight @weight end |
Instance Method Details
#all_nodes(&block) ⇒ Array<TagTree>
order is that of the parent to child relationships
All actual nodes of this tree
88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/eco/api/organization/tag_tree.rb', line 88 def all_nodes(&block) [].tap do |out_nodes| unless top? out_nodes.push(self) yield(self) if block_given? end nodes.each do |node| out_nodes.concat(node.all_nodes(&block)) end end end |
#ancestors ⇒ Array<TagTree>
it does not include the current node
All the acenstor nodes of the current node
103 104 105 106 107 108 109 110 |
# File 'lib/eco/api/organization/tag_tree.rb', line 103 def ancestors [].tap do |ans| unless parent.top? ans << parent ans.concat(parent.ancestors) end end end |
#archived? ⇒ Boolean
67 68 69 |
# File 'lib/eco/api/organization/tag_tree.rb', line 67 def archived? @archived end |
#as_json ⇒ Array[Hash]
Returns where Hash
is a node
{"tag" => TAG, "nodes": Array[Hash]}
.
123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/eco/api/organization/tag_tree.rb', line 123 def as_json nodes_json = nodes.map {|node| node.as_json} if top? nodes_json else { "id" => tag, "archived" => archived, "archived_token" => archived_token, "weight" => weight, "nodes" => nodes_json } end end |
#count ⇒ Integer
Returns the number of locations.
144 145 146 |
# File 'lib/eco/api/organization/tag_tree.rb', line 144 def count @hash_tags.keys.count 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
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 |
# File 'lib/eco/api/organization/tag_tree.rb', line 288 def default_tag(*values) values = (values) nodes = []; ddepth = -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 > ddepth nodes = [cnode] ddepth = cnode.depth elsif cnode.depth == ddepth 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 && ddepth > 0 end default_tag ||= nodes.first&.tag if (ddepth > 0) || flat? default_tag end |
#diff(tagtree, differences: {}, level: 0, **options) ⇒ Array
Returns with the differences.
113 114 115 116 |
# File 'lib/eco/api/organization/tag_tree.rb', line 113 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
72 73 74 |
# File 'lib/eco/api/organization/tag_tree.rb', line 72 def dup self.class.new(as_json) end |
#each {|node| ... } ⇒ Enumerable<Eco::API::Organization::TagTree>
Iterate through all the nodes of this tree
80 81 82 83 |
# File 'lib/eco/api/organization/tag_tree.rb', line 80 def each(&block) return to_enum(:each) unless block all_nodes.each(&block) end |
#empty? ⇒ Boolean
Returns true
if there are tags in the node, false
otherwise.
139 140 141 |
# File 'lib/eco/api/organization/tag_tree.rb', line 139 def empty? count <= 1 end |
#filter_tags(list) ⇒ Array<String>
Filters tags out that do not belong to the tree
230 231 232 233 |
# File 'lib/eco/api/organization/tag_tree.rb', line 230 def (list) return [] unless list && list.is_a?(Array) list.select {|str| tag?(str)} end |
#flat? ⇒ Integer
Returns if there's only top level.
161 162 163 |
# File 'lib/eco/api/organization/tag_tree.rb', line 161 def flat? self.total_depth <= 0 end |
#has_children? ⇒ Boolean
Returns it has subnodes.
208 209 210 |
# File 'lib/eco/api/organization/tag_tree.rb', line 208 def has_children? children_count > 0 end |
#leafs ⇒ Array<String>
Returns all the tags with no children
196 197 198 199 200 |
# File 'lib/eco/api/organization/tag_tree.rb', line 196 def leafs .select do |tag| !node(tag).has_children? end end |
#node(key) ⇒ TagTree?
Finds a subtree node.
222 223 224 225 |
# File 'lib/eco/api/organization/tag_tree.rb', line 222 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).
190 191 192 |
# File 'lib/eco/api/organization/tag_tree.rb', line 190 def subtag?(key) .include?(key&.upcase) end |
#subtags ⇒ Array<String>
Gets all but the upper level tags of the current node tree.
183 184 185 |
# File 'lib/eco/api/organization/tag_tree.rb', line 183 def - (depth: depth) end |
#tag?(key) ⇒ Boolean
Verifies if a tag exists in the tree.
215 216 217 |
# File 'lib/eco/api/organization/tag_tree.rb', line 215 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.
171 172 173 174 175 176 177 178 179 |
# File 'lib/eco/api/organization/tag_tree.rb', line 171 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
118 119 120 |
# File 'lib/eco/api/organization/tag_tree.rb', line 118 def top? depth == -1 end |
#total_depth ⇒ Integer
Returns the highest depth
of all the children.
149 150 151 152 153 154 155 156 157 158 |
# File 'lib/eco/api/organization/tag_tree.rb', line 149 def total_depth @total_depth ||= if has_children? deepest_node = nodes.max_by do |node| node.total_depth end deepest_node.total_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
268 269 270 271 272 273 274 275 276 277 278 |
# File 'lib/eco/api/organization/tag_tree.rb', line 268 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 |