module Wunderbar

explicit request types

Wrapper class that understands HTML

run command/block as a background daemon

Convert Wunderbar html syntax into JQuery calls

support for excluding files/directories from triggering restart.

Usage:

module Wunderbar::Listen
  EXCLUDE = ['file', 'dir']
end

convert script blocks to JavaScript. If binding_of_caller is available, full access to all variables defined in the callers scope may be made by execute strings (“ or %x()).

rack.rubyforge.org/doc/classes/Rack/Request.html rubydoc.info/gems/sinatra/Sinatra/Application www.ruby-doc.org/stdlib-1.9.3/libdoc/cgi/rdoc/CGI.html#public-class-method-details

Constants

CALLERS_TO_IGNORE

Public Class Methods

data() click to toggle source

Extract data from the script (after __END__)

# File lib/wunderbar/installation.rb, line 3
def self.data
  data = DATA.read 

  # process argument overrides
  data.scan(/^\s*([A-Z]\w*)\s*=\s*(['"]).*\2$/).each do |name, q|
    override = ARGV.find {|arg| arg =~ /--#{name}=(.*)/i}
    data[/^\s*#{name}\s*=\s*(.*)/,1] = $1.inspect if override
  end

  data
end
debug(*args, &block) click to toggle source

convenience methods

# File lib/wunderbar/logger.rb, line 46
def self.debug(*args, &block)
  logger.debug(*args, &block)
end
default_log_level=(level) click to toggle source
# File lib/wunderbar/logger.rb, line 33
def self.default_log_level=(level)
  self.log_level = level unless @logger
end
error(*args, &block) click to toggle source
# File lib/wunderbar/logger.rb, line 58
def self.error(*args, &block)
  logger.error(*args, &block)
end
fatal(*args, &block) click to toggle source
# File lib/wunderbar/logger.rb, line 62
def self.fatal(*args, &block)
  logger.fatal(*args, &block)
end
files() click to toggle source
# File lib/wunderbar/environment.rb, line 22
def self.files
  @@files
end
html(*args, &block) click to toggle source

canonical interface

# File lib/wunderbar/cgi-methods.rb, line 213
def self.html(*args, &block)
  @queue << [:html, args, block]
end
info(*args, &block) click to toggle source
# File lib/wunderbar/logger.rb, line 50
def self.info(*args, &block)
  logger.info(*args, &block)
end
json(*args, &block) click to toggle source
# File lib/wunderbar/cgi-methods.rb, line 221
def self.json(*args, &block)
  @queue << [:json, args, block]
end
log_level() click to toggle source
# File lib/wunderbar/logger.rb, line 37
def self.log_level
  return 'debug' if logger.level == Logger::DEBUG
  return 'info'  if logger.level == Logger::INFO
  return 'warn'  if logger.level == Logger::WARN
  return 'error' if logger.level == Logger::ERROR
  return 'fatal' if logger.level == Logger::FATAL
end
log_level=(level) click to toggle source
# File lib/wunderbar/logger.rb, line 19
def self.log_level=(level)
  return unless level

  case level.to_s.downcase
  when 'debug'; logger.level = Logger::DEBUG
  when 'info';  logger.level = Logger::INFO
  when 'warn';  logger.level = Logger::WARN
  when 'error'; logger.level = Logger::ERROR
  when 'fatal'; logger.level = Logger::FATAL
  else
    warn "Invalid log_level specified: #{level}"
  end
end
logger() click to toggle source
# File lib/wunderbar/logger.rb, line 4
def self.logger
  @logger ||= nil
  return @logger if @logger
  @logger = Logger.new($stderr)
  @logger.level = Logger::WARN
  @logger.formatter = proc { |severity, datetime, progname, msg|
    "_#{severity} #{msg}\n"
  }
  @logger
end
logger=(new_logger) click to toggle source
# File lib/wunderbar/logger.rb, line 15
def self.logger= new_logger
  @logger = new_logger
end
option(values={}) click to toggle source
# File lib/wunderbar/builder.rb, line 6
def self.option(values={})
  @@options.merge!(values)
  @@options
end
polymer_element(*args, &block) click to toggle source
# File lib/wunderbar/polymer.rb, line 16
def self.polymer_element(*args, &block)
  callback = Proc.new do |scope, args, block| 
    polymer_element(scope, *args, &block)
  end
  @queue << [callback, args, block]
end
queue() click to toggle source
# File lib/wunderbar/cgi-methods.rb, line 229
def self.queue
  @queue
end
ruby2js(*args, &block) click to toggle source
# File lib/wunderbar/script.rb, line 50
def self.ruby2js(*args, &block)
  callback = Proc.new do |scope, callback_args, callback_block| 
    ruby2js(scope, *callback_args, &callback_block)
  end
  @queue << [callback, args, block]
end
submit(cmd=nil) { || ... } click to toggle source
# File lib/wunderbar/job-control.rb, line 6
def self.submit(cmd=nil)
  fork do
    # detach from tty
    Process.setsid
    fork and exit

    # clear working directory and mask
    Dir.chdir '/'
    File.umask 0000

    # close open files
    STDIN.reopen '/dev/null'
    if RbConfig::CONFIG['host_os'] =~ /darwin|mac os/
      STDOUT.reopen '/dev/null'
    else
      STDOUT.reopen '/dev/null', 'a'
    end
    STDERR.reopen STDOUT

    # clear environment of cgi cruft
    require 'cgi'
    ENV.keys.select {|key| key =~ /^HTTP_/}.each do |key|
      ENV.delete key
    end
    ::CGI::QueryExtension.public_instance_methods.each do |method|
      ENV.delete method.to_s.upcase
    end

    # run cmd and/or block
    system({'USER' => $USER, 'HOME' => $HOME}, cmd) if cmd
    yield if block_given?
  end
end
templates() click to toggle source
# File lib/wunderbar/environment.rb, line 18
def self.templates
  @@templates
end
text(*args, &block) click to toggle source
# File lib/wunderbar/cgi-methods.rb, line 225
def self.text(*args, &block)
  @queue << [:text, args, block]
end
warn(*args, &block) click to toggle source
# File lib/wunderbar/logger.rb, line 54
def self.warn(*args, &block)
  logger.warn(*args, &block)
end
websocket(opts={}, &block) click to toggle source
# File lib/wunderbar/websocket.rb, line 171
def self.websocket(opts={}, &block)
  opts = {:port => opts} if Fixnum === opts
  port = opts[:port]
  buffer = opts.fetch(:buffer,1)

  if not port
    socket = TCPServer.new(0)
    port = Socket.unpack_sockaddr_in(socket.getsockname).first
    socket.close
  end

  sock1 = nil

  proc = Proc.new do
    begin
      channel = Wunderbar::Channel.new(port, buffer, opts[:locals])
      if sock1
        sock1.send('x',0)
        sock1.close
      end
      channel.instance_eval(&block)
    rescue Exception => exception
      channel._ :type=>:stderr, :line=>exception.inspect
      exception.backtrace.each do |frame| 
        next if Wunderbar::CALLERS_TO_IGNORE.any? {|re| frame =~ re}
        channel._ :type=>:stderr, :line=>"  #{frame}"
      end
    ensure
      if channel
        channel.complete = true
        sleep 5
        sleep 60 unless channel.connected or opts[:sync]
        channel.close
      end
    end
  end

  if opts[:sync]
    instance_eval &proc
  else
    sock1, sock2 = UNIXSocket.pair
    submit(&proc)
    sleep 0.3 while sock2.recv(1) != 'x'
    sock2.close
  end

  port
end
xhtml(*args, &block) click to toggle source
# File lib/wunderbar/cgi-methods.rb, line 217
def self.xhtml(*args, &block)
  @queue << [:xhtml, args, block]
end