Module: Hell::Helpers

Defined in:
lib/hell/lib/helpers.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.ansi_escape(message) ⇒ Object



52
53
54
# File 'lib/hell/lib/helpers.rb', line 52

def ansi_escape(message)
  Hell::Helpers::escape_to_html(Hell::Helpers::utf8_dammit(message))
end

.escape_to_html(data) ⇒ 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
48
49
50
# File 'lib/hell/lib/helpers.rb', line 9

def escape_to_html(data)
  {
    1  => {:color => :none,     :class => "bold",           :type => :special},
    2  => {:color => :none,     :class => "low-intensity",  :type => :special},
    3  => {:color => :none,     :class => "italic",         :type => :special},
    4  => {:color => :none,     :class => "underline",      :type => :special},
    5  => {:color => :none,     :class => "blink-slow",     :type => :special},
    5  => {:color => :none,     :class => "blink-rapid",    :type => :special},
    7  => {:color => :none,     :class => "reverse",        :type => :special},
    8  => {:color => :none,     :class => "conceal",        :type => :special},
    9  => {:color => :none,     :class => "crossed-out",    :type => :special},
    30 => {:color => "000000",  :class => "color-black",    :type => :color},
    31 => {:color => "7F0000",  :class => "color-red",      :type => :color},
    32 => {:color => "007F05",  :class => "color-green",    :type => :color},
    33 => {:color => "807F00",  :class => "color-yellow",   :type => :color},
    34 => {:color => "0D0080",  :class => "color-blue",     :type => :color},
    35 => {:color => "800080",  :class => "color-magenta",  :type => :color},
    36 => {:color => "00807F",  :class => "color-cyan",     :type => :color},
    37 => {:color => "C0C0C0",  :class => "color-white",    :type => :color},
    40 => :nothing,
    41 => :nothing,
    43 => :nothing,
    44 => :nothing,
    45 => :nothing,
    46 => :nothing,
    47 => :nothing,
  }.each do |key, value|
    if value == :nothing
      data.gsub!(/\e\[#{key}m/,"<span>")
    elsif value.is_a? Hash
      if value[:class] == 'conceal'
        data.gsub!(/.[\b]/, '')
      else
        data.gsub!(/\e\[#{key}m/, "<span class=\"#{value[:class]}\">")
      end
    end
  end
  data.gsub!(/\e\[0m/, '</span>')
  data.gsub!(/\e\[0/, '</span>')
  # data.gsub!(' ', '&nbsp;')
  data
end

.push_line(task_id, line, io) ⇒ Object



70
71
72
73
74
75
76
77
# File 'lib/hell/lib/helpers.rb', line 70

def push_line(task_id, line, io)
  begin
    Pusher[task_id].trigger('message', MultiJson.dump(Hell::Helpers::ws_message(line)))
    raise TailDone if HELL_SENTINEL_STRINGS.any? { |w| line =~ /#{w}/ }
  rescue StandardError => e
    Process.kill("KILL", io.pid)
  end
end

.pusher_error(task_id, message) ⇒ Object



151
152
153
154
155
# File 'lib/hell/lib/helpers.rb', line 151

def pusher_error(task_id, message)
  Pusher[task_id].trigger('start', MultiJson.dump(Hell::Helpers::ws_message("<p>start</p>")))
  Pusher[task_id].trigger('message', MultiJson.dump(Hell::Helpers::ws_message("<p>#{message}</p>")))
  Pusher[task_id].trigger('end', MultiJson.dump(Hell::Helpers::ws_message("<p>end</p>")))
end

.pusher_success(task_id, command, opts = {}) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/hell/lib/helpers.rb', line 157

def pusher_success(task_id, command, opts = {})
  out = nil
  opts = {:prepend => false}.merge(opts)
  Pusher[task_id].trigger('start', MultiJson.dump(Hell::Helpers::ws_message("<p>start</p>")))
  Pusher[task_id].trigger('message', MultiJson.dump(Hell::Helpers::ws_message("<p>#{command}</p>"))) unless opts[:prepend] == false
  IO.popen(command, 'rb') do |io|
    io.each do |line|
      Hell::Helpers::push_line(task_id, line, io)
    end
  end
  Pusher[task_id].trigger('end', MultiJson.dump(Hell::Helpers::ws_message("<p>end</p>")))
end

.utf8_dammit(s) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/hell/lib/helpers.rb', line 128

def utf8_dammit(s)
  # Converting ASCII-8BIT to UTF-8 based domain-specific guesses
  if s.is_a? String
    begin
      # Try it as UTF-8 directly
      cleaned = s.dup.force_encoding('UTF-8')
      unless cleaned.valid_encoding?
        # Some of it might be old Windows code page
        cleaned = s.encode( 'UTF-8', 'Windows-1252' )
      end
      s = cleaned
    rescue EncodingError
      # Force it to UTF-8, throwing out invalid bits
      s.encode!('UTF-8', :invalid => :replace, :undef => :replace)
    end
    s
  end
end

.valid_log(id) ⇒ Object



124
125
126
# File 'lib/hell/lib/helpers.rb', line 124

def valid_log(id)
  File.exists?(File.join(HELL_LOG_PATH, id + ".log"))
end

.ws_message(message) ⇒ Object



56
57
58
# File 'lib/hell/lib/helpers.rb', line 56

def ws_message(message)
  {:message => Hell::Helpers::ansi_escape(message)}
end

Instance Method Details

#close_stream(out) ⇒ Object



79
80
81
82
# File 'lib/hell/lib/helpers.rb', line 79

def close_stream(out)
  out << "event: end\ndata:\n\n" unless out.closed?
  out.close
end

#json_encode(data) ⇒ Object



147
148
149
# File 'lib/hell/lib/helpers.rb', line 147

def json_encode(data)
  MultiJson.dump(data)
end

#random_idObject



84
85
86
# File 'lib/hell/lib/helpers.rb', line 84

def random_id
  Time.now.to_i.to_s + '.' + SecureRandom.hex(2)
end

#run_in_background!(background_cmd) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/hell/lib/helpers.rb', line 88

def run_in_background!(background_cmd)
  log_file = random_id
  task_end = HELL_SENTINEL_STRINGS.first
  cmd = [
    "cd #{HELL_APP_ROOT} && echo '#{background_cmd}' >> #{HELL_LOG_PATH}/#{log_file}.log 2>&1",
    "cd #{HELL_APP_ROOT} && #{background_cmd} >> #{HELL_LOG_PATH}/#{log_file}.log 2>&1",
    "cd #{HELL_APP_ROOT} && echo '#{task_end}' >> #{HELL_LOG_PATH}/#{log_file}.log 2>&1",
  ].join(" ; ")
  system("sh -c \"#{cmd}\" &")

  # Wait up to three seconds in case of server load
  i = 0
  while i < 3
    i += 1
    break if File.exists?(File.join(HELL_LOG_PATH, log_file + ".log"))
    sleep 1
  end

  log_file
end

#stream_line(task_id, line, out, io) ⇒ Object



60
61
62
63
64
65
66
67
68
# File 'lib/hell/lib/helpers.rb', line 60

def stream_line(task_id, line, out, io)
  begin
    out << "data: " + ws_message(line) + "\n\n" unless out.closed?
    raise TailDone if HELL_SENTINEL_STRINGS.any? { |w| line =~ /#{w}/ }
  rescue
    logger.info "kill " + io.pid
    Process.kill("KILL", io.pid)
  end
end

#tail_in_background!(task_id) ⇒ Object



109
110
111
112
# File 'lib/hell/lib/helpers.rb', line 109

def tail_in_background!(task_id)
  cmd = "cd #{HELL_LOG_PATH} && HELL_TASK_ID='#{task_id}' HELL_SENTINEL_STRINGS='#{HELL_SENTINEL_STRINGS.join(',')}' bundle exec hell-pusher"
  system("sh -c \"#{cmd}\" &")
end

#verify_task(cap, name) ⇒ Object



114
115
116
117
118
119
120
121
122
# File 'lib/hell/lib/helpers.rb', line 114

def verify_task(cap, name)
  original_cmd = name.gsub('+', ' ').gsub!(/\s+/, ' ').strip
  cmd = original_cmd.split(' ')
  cmd.shift if cap.environments.include?(cmd.first)
  cmd = cmd.join(' ')

  tasks = cap.tasks(cmd, {:exact => true})
  return tasks, original_cmd
end