Module: Rudy::Utils

Extended by:
Utils
Includes:
Socket::Constants
Included in:
Utils
Defined in:
lib/rudy/utils.rb

Overview

A motley collection of methods that Rudy loves to call!

Defined Under Namespace

Modules: RSSReader

Instance Method Summary collapse

Instance Method Details

msg The message to return as a banner size One of: :normal (default), :huge colour a valid Returns a string with styling applying



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/rudy/utils.rb', line 172

def banner(msg, size = :normal, colour = :black)
  return unless msg
  banners = {
    :huge => Rudy::Utils.without_indent(%Q(
    =======================================================
    =======================================================
    !!!!!!!!!   %s   !!!!!!!!!
    =======================================================
    =======================================================)),
    :normal => %Q(============  %s  ============)
  }
  size = :normal unless banners.has_key?(size)
  #colour = :black unless Drydock::Console.valid_colour?(colour)
  size, colour = size.to_sym, colour.to_sym
  sprintf(banners[size], msg).bright.att(:reverse)
end

#bell(chimes = 1, logger = nil) ⇒ Object

Make a terminal bell chime



112
113
114
115
116
117
118
# File 'lib/rudy/utils.rb', line 112

def bell(chimes=1, logger=nil)
  chimes ||= 0
  return unless logger
  chimed = chimes.to_i
  logger.print "\a"*chimes if chimes > 0 && logger
  true # be like Rudy.bug()
end

#bug(bugid, logger = STDERR) ⇒ Object

Have you seen that episode of The Cosby Show where Dizzy Gillespie… ah nevermind.



121
122
123
124
125
126
# File 'lib/rudy/utils.rb', line 121

def bug(bugid, logger=STDERR)
  logger.puts "You have found a bug! If you want, you can email".color(:red)
  logger.puts '[email protected]'.color(:red).bright << " about it. It's bug ##{bugid}.".color(:red)          
  logger.puts "Continuing...".color(:red)
  true # so we can string it together like: bug('1') && next if ...
end

#capture(stream) ⇒ Object

Capture STDOUT or STDERR to prevent it from being printed.

capture(:stdout) do
  ...
end


237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/rudy/utils.rb', line 237

def capture(stream)
  #raise "We can only capture STDOUT or STDERR" unless stream == :stdout || stream == :stderr
  begin
    stream = stream.to_s
    eval "$#{stream} = StringIO.new"
    yield
    result = eval("$#{stream}").read
  ensure
    eval("$#{stream} = #{stream.upcase}")
  end

  result
end

#external_ip_addressObject

Return the external IP address (the one seen by the internet)



17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/rudy/utils.rb', line 17

def external_ip_address
  ip = nil
  begin
    %w{solutious.com/ip/ myip.dk/ whatismyip.com }.each do |sponge| # w/ backup
      ipstr = Net::HTTP.get(URI.parse("http://#{sponge}")) || ''
      ip = /([0-9]{1,3}\.){3}[0-9]{1,3}/.match(ipstr).to_s
      break if ip && !ip.empty?
    end
  rescue SocketError, Errno::ETIMEDOUT => ex
    STDERR.puts "Connection Error. Check your internets!"
  end
  ip += "/32" if ip
  ip
end

#generate_tag(revision = 1) ⇒ Object

Generates a canonical tag name in the form:

rudy-2009-12-31-01

where r1 refers to the revision number that day



48
49
50
51
52
53
54
# File 'lib/rudy/utils.rb', line 48

def generate_tag(revision=1)
  n = DateTime.now
  y = n.year.to_s.rjust(4, "20")
  m = n.month.to_s.rjust(2, "0")
  d = n.mday.to_s.rjust(2, "0")
  "rudy-%4s-%2s-%2s-r%s" % [y, m, d, revision.to_s.rjust(2, "0")] 
end

#id_type(str) ⇒ Object

Returns the object type associated to str or nil if unknown.

  • str is a string you’re investigating



140
141
142
143
144
# File 'lib/rudy/utils.rb', line 140

def id_type(str)
  return false unless str
  str &&= str.to_s.strip
  (Rudy::ID_MAP.detect { |n,v| v == str.split('-').first } || []).first
end

#identifier(key) ⇒ Object

Returns the string identifier associated to this key



154
155
156
157
158
# File 'lib/rudy/utils.rb', line 154

def identifier(key)
  key &&= key.to_sym
  return unless Rudy::ID_MAP.has_key?(key)
  Rudy::ID_MAP[key]
end

#internal_ip_addressObject

Return the local IP address which receives external traffic from: coderrr.wordpress.com/2008/05/28/get-your-local-ip-address/ NOTE: This does not open a connection to the IP address.



35
36
37
38
39
40
41
42
43
# File 'lib/rudy/utils.rb', line 35

def internal_ip_address
  # turn off reverse DNS resolution temporarily 
  orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true   
  ip = UDPSocket.open {|s| s.connect('75.101.137.7', 1); s.addr.last } # Solutious IP
  ip += "/24" if ip
  ip
ensure  
  Socket.do_not_reverse_lookup = orig
end

#is_id?(identifier, str) ⇒ Boolean

Is the given string str an ID of type identifier?

  • identifier is expected to be a key from ID_MAP

  • str is a string you’re investigating

Returns:

  • (Boolean)


131
132
133
134
135
136
# File 'lib/rudy/utils.rb', line 131

def is_id?(identifier, str)
  return false unless identifier && str && known_type?(identifier)
  identifier &&= identifier.to_sym
  str &&= str.to_s.strip
  str.split('-').first == Rudy::ID_MAP[identifier].to_s
end

#known_type?(key) ⇒ Boolean

Is the given key a known type of object?

Returns:

  • (Boolean)


147
148
149
150
151
# File 'lib/rudy/utils.rb', line 147

def known_type?(key)
  return false unless key
  key &&= key.to_s.to_sym
  Rudy::ID_MAP.has_key?(key)
end

#noid(str) ⇒ Object

Return a string ID without the identifier. i.e. key-stage-app-root => stage-app-root



161
162
163
164
165
# File 'lib/rudy/utils.rb', line 161

def noid(str)
  el = str.split('-')
  el.shift
  el.join('-')
end

#require_glob(*path) ⇒ Object

require a glob of files.

  • path is a list of path elements which is sent to File.join

and then to Dir.glob. The list of files found are sent to require. Nothing is returned but LoadError exceptions are caught. The message is printed to STDERR and the program exits with 7.



195
196
197
198
199
200
201
202
203
204
205
# File 'lib/rudy/utils.rb', line 195

def require_glob(*path)
  begin
    # TODO: Use autoload
    Dir.glob(File.join(*path.flatten)).each do |path|
      require path
    end
  rescue LoadError => ex
    puts "Error: #{ex.message}"
    exit 7
  end
end

#scp_command(host, keypair, user, paths, to_path, to_local = false, verbose = false, printonly = false) ⇒ Object

(TO BE REMOVED) TODO: This is old and nasty.



289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/rudy/utils.rb', line 289

def scp_command(host, keypair, user, paths, to_path, to_local=false, verbose=false, printonly=false)

  paths = [paths] unless paths.is_a?(Array)
  from_paths = ""
  if to_local
    paths.each do |path|
      from_paths << "#{user}@#{host}:#{path} "
    end  
    #puts "Copying FROM remote TO this machine", $/

  else
    to_path = "#{user}@#{host}:#{to_path}"
    from_paths = paths.join(' ')
    #puts "Copying FROM this machine TO remote", $/
  end


  cmd = "scp -r "
  cmd << "-i #{keypair}" if keypair
  cmd << " #{from_paths} #{to_path}"

  puts cmd if verbose
  printonly ? (puts cmd) : system(cmd)
end

#service_available?(host, port, wait = 3) ⇒ Boolean

Checks whether something is listening to a socket.

  • host A hostname

  • port The port to check

  • wait The number of seconds to wait for before timing out.

Returns true if host allows a socket connection on port. Returns false if one of the following exceptions is raised: Errno::EAFNOSUPPORT, Errno::ECONNREFUSED, SocketError, Timeout::Error

Returns:

  • (Boolean)


216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/rudy/utils.rb', line 216

def service_available?(host, port, wait=3)
  begin
    status = Timeout::timeout(wait) do
      socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
      sockaddr = Socket.pack_sockaddr_in( port, host )
      socket.connect( sockaddr )
    end
    true
  rescue Errno::EAFNOSUPPORT, Errno::ECONNREFUSED, SocketError, Timeout::Error => ex
    false
  end
end

#strand(len = 8, safe = true) ⇒ Object

Generates a string of random alphanumeric characters.

  • len is the length, an Integer. Default: 8

  • safe in safe-mode, ambiguous characters are removed (default: true):

    i l o 1 0
    


267
268
269
270
271
272
273
# File 'lib/rudy/utils.rb', line 267

def strand( len=8, safe=true )
   chars = ("a".."z").to_a + ("0".."9").to_a
   chars.delete_if { |v| %w(i l o 1 0).member?(v) } if safe
   str = ""
   1.upto(len) { |i| str << chars[rand(chars.size-1)] }
   str
end

#waiter(duration = 2, max = 120, logger = STDOUT, msg = nil, bells = 0, &check) ⇒ Object

Wait for something to happen.

  • duration seconds to wait between tries (default: 2).

  • max maximum time to wait (default: 120). Throws an exception when exceeded.

  • logger IO object to print dot to.

  • msg the message to print before executing the block.

  • bells number of terminal bells to ring. Set to nil or false to keep the waiter silent

The check block must return false while waiting. Once it returns true the waiter will return true too.



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/rudy/utils.rb', line 79

def waiter(duration=2, max=120, logger=STDOUT, msg=nil, bells=0, &check)
  # TODO: Move to Drydock. [ed-why?]
  raise "The waiter needs a block!" unless check
  duration = 1 if duration < 1
  max = duration*2 if max < duration
  dot = '.'
  begin
    if msg && logger
      logger.print msg 
      logger.flush
    end
    Timeout::timeout(max) do
      while !check.call
        sleep duration
        logger.print dot if logger.respond_to?(:print)
        logger.flush if logger.respond_to?(:flush)
      end
    end
  rescue Timeout::Error => ex
    retry if Annoy.pose_question(" Keep waiting?\a ", /yes|y|ya|sure|you bet!/i, logger)
    return false
  end
  
  if msg && logger
    logger.puts " done"
    logger.flush
  end
  
  Rudy::Utils.bell(bells, logger)
  true
end

#without_indent(str) ⇒ Object

Returns str with the leading indentation removed. Stolen from github.com/mynyml/unindent/ because it was better.



277
278
279
280
# File 'lib/rudy/utils.rb', line 277

def without_indent(str)
  indent = str.split($/).each {|line| !line.strip.empty? }.map {|line| line.index(/[^\s]/) }.compact.min
  str.gsub(/^[[:blank:]]{#{indent}}/, '')
end

#write_to_file(filename, content, mode, chmod = 600) ⇒ Object

A basic file writer



252
253
254
255
256
257
258
259
260
# File 'lib/rudy/utils.rb', line 252

def write_to_file(filename, content, mode, chmod=600)
  mode = (mode == :append) ? 'a' : 'w'
  f = File.open(filename,mode)
  f.puts content
  f.close
  return unless Rudy.sysinfo.os == :unix
  raise "Provided chmod is not a Fixnum (#{chmod})" unless chmod.is_a?(Fixnum)
  File.chmod(chmod, filename)
end