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



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/rudy/utils.rb', line 158

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



98
99
100
101
102
103
104
# File 'lib/rudy/utils.rb', line 98

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.



107
108
109
110
111
112
# File 'lib/rudy/utils.rb', line 107

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


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

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
# File 'lib/rudy/utils.rb', line 17

def external_ip_address
  ip = nil
  begin
    %w{solutious.heroku.com/ip}.each do |sponge|
      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
    Rudy::Huxtable.le "Connection Error. Check your internets!"
  end
  ip
end

#generate_tag(suffix = nil) ⇒ Object

Generates a canonical tag name in the form:

2009-12-31-USER-SUFFIX

where USER is equal to the user executing the Rudy process and SUFFIX is equal to suffix (optional)



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

def generate_tag(suffix=nil)
  n = DateTime.now
  y, m = n.year.to_s.rjust(4, "20"), n.month.to_s.rjust(2, "0")
  d, u = n.mday.to_s.rjust(2, "0"), Rudy.sysinfo.user
  criteria = [y, m, d, u]
  criteria << suffix unless suffix.nil? || suffix.empty?
  criteria.join Rudy::DELIM 
end

#id_type(str) ⇒ Object

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

  • str is a string you’re investigating



126
127
128
129
130
# File 'lib/rudy/utils.rb', line 126

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



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

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.



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

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
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)


117
118
119
120
121
122
# File 'lib/rudy/utils.rb', line 117

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)


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

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. e.g. key-stage-app-root => stage-app-root



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

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.



181
182
183
184
185
186
187
188
189
190
191
# File 'lib/rudy/utils.rb', line 181

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

#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)


202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/rudy/utils.rb', line 202

def service_available?(host, port, wait=3)
  if Rudy.sysinfo.vm == :java
    begin
      iadd = Java::InetSocketAddress.new host, port      
      socket = Java::Socket.new
      socket.connect iadd, wait * 1000  # milliseconds
      success = !socket.isClosed && socket.isConnected
    rescue NativeException => ex
      puts ex.message, ex.backtrace if Rudy.debug?
      false
    end
  else 
    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
      puts ex.class, ex.message, ex.backtrace if Rudy.debug?
      false
    end
  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
    


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

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 = 240, 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: 240). 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.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/rudy/utils.rb', line 65

def waiter(duration=2, max=240, 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
    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.



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

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



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

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