Module: Consumer::Helper

Defined in:
lib/consumer/helper.rb

Class Method Summary collapse

Class Method Details

.compact_xml(xml) ⇒ Object

returns a copy of the xml without empty nodes. Also removes internal (non-leaf) nodes that only contain empty leaves. Nodes containing only whitespace characters (space, newline, tab, and return) are considered empty.



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/consumer/helper.rb', line 48

def self.compact_xml(xml)
  old_xml = xml
  loop do
    new_xml = old_xml.gsub(/\<(\w*?)\>[ \t\r\n]*\<\/\1\>\n?/, "")
    if old_xml == new_xml # nothing was changed
      return new_xml
    else # something changed, so we'll go through it again
      old_xml = new_xml
    end
  end
end

.hash_from_yaml(base_path, file, namespace = nil) ⇒ Object

returns a hash of defaults if self.yaml_defaults is defined and the file defined there exists, empty hash otherwise.

Also takes a namespace, i.e. a sub-hash, and when given a namespace it also enables a global namespace called ‘all’. Thus if you had the yaml:

<pre> all:

my_name: Buster

greetings:

hello: world

other:

irrelevant: data

</pre>

a namespace of ‘greetings’ would return the hash:

{"my_name" => "Buster", "hello" => "world"}

You don’t have to use the global namespace, but if you do, it will be included everywhere.



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/consumer/helper.rb', line 83

def self.hash_from_yaml(base_path, file, namespace = nil)
  begin
    hash = (base_path && file) ? YAML.load(File.read(File.join(base_path, file))) : {}
  rescue => e
    raise ArgumentError, "YAML load error: #{e.message}"
  end
  
  return {} if !hash
  
  if namespace
    global = hash["all"] || {}
    namespaced_hash = hash[namespace] || {}
    hash = global.merge(namespaced_hash)
  end
  
  return hash
end

.http_from_url(url) ⇒ Object



101
102
103
104
105
106
107
108
109
# File 'lib/consumer/helper.rb', line 101

def self.http_from_url(url)
  uri = URI.parse url
  http = Net::HTTP.new uri.host, uri.port
  if uri.port == 443
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  end
  return http, uri
end

.tidy(xml) ⇒ Object

if you pass in a newline-less glob of xml it’ll return an indented copy for improved readability.



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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/consumer/helper.rb', line 4

def self.tidy(xml)
  xml = xml.clone # avoid modifying @response_xml due to pass by reference
  
  # remove all formatting to start from a common base
  xml.gsub!(/\>[\t\n\r ]*\</, "><")
  # replace empty tag pairs with <tag/>
  xml.gsub!(/\<(\w*?)\>\<\/\1\>/, "<\\1/>")
  # add in newlines after >, and sometimse before <
  xml.gsub!(/\>\</,">\n<")
  
  declaration = /\<\?xml/
  start_tag   = /\<[^\/]+?\>[\n\t\r ]+/
  end_tag     = /^[\t ]*\<\//
  
  ## add appropriate spacing before each newline.
  tab = 0
  siblings = false
  first_tag = true
  return xml.collect do |line|
    next line if line =~ declaration
    
    # calculate the indentation.
    # In general we want to add spacing if it's a start tag or leaf node, and
    # remove spacing if it's an end tag. The only times we don't want to add
    # spacing is if it's the very first node or the previous node was a sibling
    # instead of a parent.
    if line =~ end_tag
      tab -= 1
    else
      tab += 1 unless first_tag || siblings
    end

    # if the line is a start tag, the next lines will no longer be siblings
    siblings = line =~ start_tag ? false : true
    first_tag = false
    
    # return line with appropriate amount of preceding spaces #
    line = "  " * (tab > 0 ? tab : 0) + line
  end.join << "\n"
end