Class: Yawast::Shared::Output

Inherits:
Object
  • Object
show all
Defined in:
lib/shared/output.rb

Class Method Summary collapse

Class Method Details

.encode_utf8(str) ⇒ Object



88
89
90
91
92
93
94
# File 'lib/shared/output.rb', line 88

def self.encode_utf8(str)
  str = str.dup

  str = str.force_encoding('UTF-8') if [Encoding::ASCII_8BIT, Encoding::US_ASCII].include?(str.encoding)

  str
end

.escape_hash(hash) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/shared/output.rb', line 126

def self.escape_hash(hash)
  hash.each_pair do |k, v|
    if v.is_a?(Hash)
      escape_hash(v)
    elsif v.is_a?(String)
      # first, attempt to force utf-8
      v = encode_utf8 v
      hash[k] = v

      # if needed, Base64 encode to ensure that we can produce the JSON output
      hash[k] = Base64.encode64 v unless v.valid_encoding?
    end
  end
end

.get_target(super_parent = nil, parent = nil) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/shared/output.rb', line 96

def self.get_target(super_parent = nil, parent = nil)
  target = @data

  # make sure we are on the right URI, and that it exists
  unless @current_uri.nil?
    target['targets'][@current_uri] = {} if target['targets'][@current_uri].nil?
    target = target['targets'][@current_uri]
  end

  # fix parent vs super confusion
  if parent.nil? && !super_parent.nil?
    parent = super_parent
    super_parent = nil
  end

  unless super_parent.nil?
    target[super_parent] = {} if target[super_parent].nil?

    target = target[super_parent]
  end

  unless parent.nil?
    target[parent] = {} if target[parent].nil?

    target = target[parent]
  end

  target
end

.log_append_value(super_parent = nil, parent = nil, key, value) ⇒ Object



61
62
63
64
65
66
67
68
69
70
# File 'lib/shared/output.rb', line 61

def self.log_append_value(super_parent = nil, parent = nil, key, value)
  return unless @setup

  target = get_target super_parent, parent

  target[key] = [] if target[key].nil?

  # add value, after checking if it's already included
  target[key].push encode_utf8(value.to_s) unless target[key].include? encode_utf8(value.to_s)
end

.log_hash(super_parent = nil, parent = nil, key, hash) ⇒ Object



80
81
82
83
84
85
86
# File 'lib/shared/output.rb', line 80

def self.log_hash(super_parent = nil, parent = nil, key, hash)
  return unless @setup

  target = get_target super_parent, parent

  target[key] = escape_hash hash
end

.log_json(super_parent = nil, parent = nil, key, json_block) ⇒ Object



72
73
74
75
76
77
78
# File 'lib/shared/output.rb', line 72

def self.log_json(super_parent = nil, parent = nil, key, json_block)
  return unless @setup

  target = get_target super_parent, parent

  target[key] = escape_hash(JSON.parse(json_block))
end

.log_value(super_parent = nil, parent = nil, key, value) ⇒ Object



53
54
55
56
57
58
59
# File 'lib/shared/output.rb', line 53

def self.log_value(super_parent = nil, parent = nil, key, value)
  return unless @setup

  target = get_target super_parent, parent

  target[key] = encode_utf8(value.to_s)
end

.set_current_uri(uri) ⇒ Object



49
50
51
# File 'lib/shared/output.rb', line 49

def self.set_current_uri(uri)
  @current_uri = uri
end

.setup(uri, options) ⇒ Object



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
44
45
46
47
# File 'lib/shared/output.rb', line 9

def self.setup(uri, options)
  return if @setup

  @setup = true

  time = Time.new.to_i.to_s
  @file = options.output

  # get the absolute path
  @file = File.absolute_path @file

  # see if this is a file or directory
  if File.directory? @file
    # in this case, the user just gave us a directory, se we will create a file name
    @file = File.join(@file, uri.hostname + '_' + time + '.json')
  else
    # this means that it's a file, or doesn't exist
    # so, let's see if it exists, if so, warn
    puts 'WARNING: Output file already exists; it will be replaced.' if File.exist? @file
  end

  puts "Saving output to '#{@file}'"
  puts

  @data = {}

  # add the initial entries to the output
  log_value 'start_time', time
  log_value 'yawast_version', VERSION
  log_value 'ruby_version', "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"
  log_value 'openssl_version', OpenSSL::OPENSSL_VERSION
  log_value 'platform', RUBY_PLATFORM
  log_value 'options', options.__hash__
  log_value 'encoding', __ENCODING__

  # setup the data structure to capture info for individual targets
  @data['targets'] = {}
  set_current_uri uri
end

.write_fileObject



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/shared/output.rb', line 141

def self.write_file
  return unless @setup

  # note the ending time
  set_current_uri nil
  log_value 'end_time', Time.new.to_i.to_s

  begin
    json = JSON.pretty_generate @data
  rescue JSON::GeneratorError
    # this means that we don't have valid data to encode - need to perform some cleanup
    @data = escape_hash @data
    json = JSON.pretty_generate @data
  end

  File.open(@file, 'w') { |file| file.write(json) }
end