Module: GeoLabels::Importer

Defined in:
lib/geo_labels/importer.rb

Defined Under Namespace

Classes: ImportLabel, LabelList

Class Method Summary collapse

Class Method Details

.import(subject) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/geo_labels/importer.rb', line 4

def self.import(subject)
  yaml_h =  case subject
            when String
              if subject.start_with?('/') or subject.start_with?('./')
                YAML.load_file(subject)
              else
                YAML.safe_load(subject)
              end
            when File                               then YAML.safe_load(subject.read)
            when Pathname                           then YAML.safe_load(subject.read)
            when ActionDispatch::Http::UploadedFile then YAML.safe_load(subject.read)
            else
              raise 'Argument not recognized'
            end
  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



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

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



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/geo_labels/importer.rb', line 57

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