Class: GeoLabels::Importer::YamlData

Inherits:
Object
  • Object
show all
Defined in:
lib/geo_labels/importer/yaml_data.rb

Defined Under Namespace

Classes: ImportLabel, LabelList

Class Method Summary collapse

Class Method Details

.import(yaml_h) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/geo_labels/importer/yaml_data.rb', line 6

def self.import(yaml_h)
  GeoLabels::Contact.delete_all
  GeoLabels::Label.delete_all
  GeoLabels::ContactLabel.delete_all
  labels_dict = persist_labels_tree yaml_h['labels']
  yaml_h['contacts'].each do |contact_attributes|
    label_names = Array(contact_attributes.delete('labels'))
    contact = GeoLabels::Contact.new(contact_attributes)
    contact.labels = label_names.map{ labels_dict[_1] }.compact
    contact.save
  end
  GeoLabels::Contact.count
end

.labels_text_to_tree(tree_text) ⇒ Object



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
# File 'lib/geo_labels/importer/yaml_data.rb', line 20

def self.labels_text_to_tree(tree_text)
  txt = tree_text.gsub("\n\u0001", "\n") # remove START OF HEADING TRASH
  txt.gsub! /^(\s*)[-*] /, '\1  ' # remove list punctuations and interpret just the spaces
  lines = txt.split("\n")
  root_label, current_indentation = ImportLabel.new('root'), -1
  working_object = root_label
  lines.each do |line|
    line_indentation = (line.match(/\s+/).try(:[], 0).try(:size) || 0) / 2
    # name = line[(2*line_indentation)..] # strip the leading spaces
    name = line.strip
    label = ImportLabel.new(name)
    if line_indentation > current_indentation # level deeper
      working_object = working_object.add_child(label)
    elsif line_indentation < current_indentation
      (current_indentation - line_indentation).times do
        working_object = working_object.parent unless working_object.parent.is_root?
      end
      working_object = working_object.add_sibling(label)
    else
      working_object = working_object.add_sibling label
    end
    current_indentation = line_indentation
  end
  root_label
end

.persist_labels_tree(tree_or_text = nil) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/geo_labels/importer/yaml_data.rb', line 46

def self.persist_labels_tree(tree_or_text = nil)
  tree = case tree_or_text
         when ImportLabel then tree_or_text
         when String      then labels_text_to_tree(tree_or_text)
         else
           raise 'Must provide a tree label object or tree text'
         end
  record_lookup_dict = {}
  persister = proc do |items, parent|
    items.each do |item|
      record = Label.create name: item.name, parent: parent
      record_lookup_dict[item.name] = record
      persister.call item.children, record if item.children.present?
    end
  end
  persister.call(tree.children, nil)
  record_lookup_dict
end