module Typingpool::Utility

Public Class Methods

app_dir() click to toggle source

Returns Typingpool's root dir, that is, the root dir of the gem from which this library is being loaded.

# File lib/typingpool/utility.rb, line 137
def app_dir
  File.dirname(File.dirname(lib_dir))
end
array_to_hash(array, headers) click to toggle source
==== Returns

Single hash, with keys corresponding to Headers and values corresponding to respective entries in Array.

# File lib/typingpool/utility.rb, line 64
def array_to_hash(array, headers)
  Hash[*headers.zip(array).flatten] 
end
fetch_url(url, max_redirects=6) click to toggle source

Makes one or more web requests to fetch a resource. Follows redirects by default.

==== Params
url

URL as a string.

max_redirects

Default 6. Maximum number of HTTP redirects to follow.

==== Exceptions

Raises Error::HTTP if it receives an HTTP response code indicating an error (after followinf redirects). Exception message will include the response code and response message.

==== Returns

A Net::HTTPResponse instance, if the request was successful.

# File lib/typingpool/utility.rb, line 180
def fetch_url(url, max_redirects=6)
  response = request_url_with(url, max_redirects) do |current_url, http|
    http.request_get(current_url.path)
  end
  if response.kind_of?(Net::HTTPSuccess)
    return response
  else
    raise Error::HTTP, "HTTP error fetching '#{url.to_s}': '#{response.code}: #{response.message}'"
  end #if response.kind_of?
end
in_temp_dir() { |dir| ... } click to toggle source

Takes a block and calls that block with a path to a temporary directory. Recursively deletes that directory when the block is finished.

# File lib/typingpool/utility.rb, line 120
def in_temp_dir
  dir = Dir.mktmpdir
  begin
    yield(dir)
  ensure
    FileUtils.remove_entry_secure(dir)
  end # begin
end
join_in_english(array, oxford_comma=false) click to toggle source

Takes an array, returns a string with the array elements joined with a comma, except for the last and second to last items, which are joined with ' and '. For example: ['foo','bar'] => “foo and bar”; ['foo','bar','baz'] => “foo, bar and baz”

Also takes an optional flag which specifies whether to use an oxford comma. Default is false. If set to true, the last and second to last items will be joined with ', and'

# File lib/typingpool/utility.rb, line 110
def join_in_english(array, oxford_comma=false)
  array = array.dup
  oxford_comma = (oxford_comma && array.count > 2) ? ',' : ''
  last = array.pop
  array.empty? ? last : [array.join(', '), last].join("#{oxford_comma} and ")
end
lib_dir() click to toggle source

Returns Typingpool's lib/typingpool/ root, usually for purposes of locating templates or test fixtures.

# File lib/typingpool/utility.rb, line 131
def lib_dir
  File.dirname(__FILE__)
end
newlines_to_html(text) click to toggle source

Does a natural-feeling conversion between plain text linebreaks and HTML P and BR tags, as typical with most web comment forms.

==== Returns

Text with double newlines converted to P tags, single newlines converted to BR tags, and the original newlines restored.

# File lib/typingpool/utility.rb, line 94
def newlines_to_html(text)
  text.gsub!(/\n\n+/, '<p>')
  text.gsub!(/\n/, '<br>')
  text.gsub!(/<p>/, "\n\n<p>")
  text.gsub!(/<br>/, "\n<br>")
  text
end
normalize_newlines(text) click to toggle source

Converts standard linefeed combos - CRLF, CR, LF - to whatever the system newline is, aka “n”.

==== Returns

String with normalized newlines

# File lib/typingpool/utility.rb, line 81
def normalize_newlines(text)
  text.gsub!("\r\n", "\n")
  text.gsub!("\r", "\n")
  text.gsub!("\f", "\n")
  text
end
os_x?() click to toggle source

Returns true if this Ruby was built on Mac OS X

# File lib/typingpool/utility.rb, line 142
def os_x?
  RUBY_PLATFORM.match(/\bdarwin/i)
end
request_url_with(url, max_redirects=6) { |url, http| ... } click to toggle source

protected

# File lib/typingpool/utility.rb, line 194
def request_url_with(url, max_redirects=6)
  seen = Set.new
  loop do
    url = URI.parse(url)
    if seen.include? url.to_s
      raise Error::HTTP, "Redirect infinite loop (at '#{url.to_s}')" 
    end
    if seen.count > max_redirects
      raise Error::HTTP, "Too many redirects (>#{max_redirects})" 
    end
    seen.add(url.to_s)
    #Die in a fire, net/http.
    http = Net::HTTP.new(url.host, url.port)
    http.use_ssl = true if url.scheme == 'https'
    response = yield(url, http)
    if response.kind_of?(Net::HTTPRedirection)
      url = response['location']
    else
      return response
    end #if response.kind_of?...
  end #loop do
end
stdin_has_content?() click to toggle source

Returns true if anything appears to be waiting on STDIN

# File lib/typingpool/utility.rb, line 147
def stdin_has_content?
  STDIN.fcntl(Fcntl::F_GETFL, 0) == 0
end
system_quietly(*cmd) click to toggle source

Much like Kernel#system, except it doesn't spew STDERR and STDOUT all over your screen (when called with multiple args, which with Kernel#systems kills the chance to do shell style stream redirects like 2>/dev/null). Even more like Open3.capture3, except it raises an exception on unsuccesful exit status.

==== Params
cmd

Commands to send to the shell, just as with Kernel#system.

==== Returns

On success: STDOUT, or true if STDOUT is empty On failure: Raises Typingpool::Error::Shell, with STDERR as error text if available.

# File lib/typingpool/utility.rb, line 25
def system_quietly(*cmd)
  out, err, status = Open3.capture3(*cmd)
  if status.success?
    return out ? out.chomp : true
  else
    if err
      raise Error::Shell, err.chomp
    else
      raise Error::Shell
    end
  end
end
timespec_to_seconds(timespec) click to toggle source

Convert config entries like '30s','2d','10h'. etc into number of seconds.

==== Params
timespec

string conforming to format outlined at

search.cpan.org/~markstos/CGI-Session-4.48/lib/CGI/Session.pm#expire($param,_$time)

==== Returns

Number of whole seconds corresponding to the timespec. Raises Typingpool::Error::Argument::Format on bad input.

# File lib/typingpool/utility.rb, line 46
def timespec_to_seconds(timespec)
  timespec or return
  suffix_to_time = {
    's'=>1,
    'm'=>60,
    'h'=>60*60,
    'd'=>60*60*24,
    'M'=>60*60*24*30,
    'y'=>60*60*24*365
  }
  match = timespec.to_s.match(/^\+?(\d+(\.\d+)?)\s*([#{suffix_to_time.keys.join}])?$/) or raise Error::Argument::Format, "Can't convert '#{timespec}' to time"
  suffix = match[3] || 's'
  return (match[1].to_f * suffix_to_time[suffix].to_i).to_i
end
url_basename(url) click to toggle source

The base file at the root of the URL path.

==== Params
url

string url

==== Returns

File name

# File lib/typingpool/utility.rb, line 73
def url_basename(url)
  File.basename(URI.parse(url).path)
end
working_url?(url, max_redirects=6) click to toggle source

Makes one or more HEAD requests to determine whether a particular web resource is available.

==== Params
url

URL as a string.

max_redirects

Default 6. Maximum number of HTTP redirects to follow.

==== Returns

True if the HTTP response code indicates success (after following redirects). False if the HTTP response code indicates an error (e.g. 4XX and 5XX response codes).

# File lib/typingpool/utility.rb, line 161
def working_url?(url, max_redirects=6)
  response = request_url_with(url, max_redirects) do |current_url, http|
    http.request_head(current_url.path)
  end #request_url_with... do |url|
  response.kind_of?(Net::HTTPSuccess)
end