require 'json'
module Logster
module Middleware
class Viewer
PATH_INFO = "PATH_INFO".freeze
SCRIPT_NAME = "SCRIPT_NAME".freeze
def initialize(app)
@app = app
@logs_path = Logster.config.subdirectory || "/logs"
@path_regex = Regexp.new("^(#{@logs_path}$)|^(#{@logs_path}(/.*))$")
@store = Logster.store or raise ArgumentError.new("store")
@assets_path = File.expand_path("../../../../assets", __FILE__)
@fileserver = Rack::File.new(@assets_path)
@authorize_callback = Logster.config.authorize_callback
end
def call(env)
path = env[PATH_INFO]
script_name = env[SCRIPT_NAME]
if script_name && script_name.length > 0
path = script_name + path
end
if resource = resolve_path(path)
return @app.call(env) if @authorize_callback && !@authorize_callback.call(env)
if resource =~ /\.js$|\.handlebars$|\.css$/
env[PATH_INFO] = resource
@fileserver.call(env)
elsif resource.start_with?("/messages.json")
serve_messages(Rack::Request.new(env))
elsif resource == "/"
[200, {"Content-Type" => "text/html; charset=utf-8"}, [body(preload_json)]]
else
[404, {}, ["Not found"]]
end
else
@app.call(env)
end
end
protected
def serve_messages(req)
opts = {
before: req["before"],
after: req["after"]
}
if(filter = req["filter"])
filter = filter.split("_").map{|s| s.to_i}
opts[:severity] = filter
end
if search = req["search"]
search = (parse_regex(search) || search) if req["regex_search"] == "true"
opts[:search] = search
end
payload = {
messages: @store.latest(opts),
total: @store.count
}
json = JSON.generate(payload)
[200, {"Content-Type" => "application/json"}, [json]]
end
def parse_regex(string)
if string =~ /\/(.+)\/(.*)/
s = $1
flags = Regexp::IGNORECASE if $2 && $2.include?("i")
Regexp.new(s, flags) rescue nil
end
end
def resolve_path(path)
if path =~ @path_regex
$3 || "/"
end
end
def preload_json
end
def css(name, attrs={})
attrs = attrs.map do |k,v|
"#{k}='#{v}'"
end.join(" ")
""
end
def script(prod, dev=nil)
name = ENV['DEBUG_JS'] == "1" && dev ? dev : prod
""
end
def component(name)
ember_template("components/#{name}", "components/" << name)
end
def handlebars(name)
ember_template("templates/#{name}", name)
end
def ember_template(location, name)
val = File.read("#{@assets_path}/javascript/#{location}.handlebars")
<
Ember.TEMPLATES[#{name.inspect}] = Ember.Handlebars.compile(#{val.inspect});
JS
end
def body(preload)
<
#{css("app.css")}
#{script("external/moment.min.js")}
#{script("external/jquery.min.js")}
#{script("external/handlebars.min.js")}
#{script("external/lodash.min.js")}
#{script("external/ember.min.js", "external/ember.js")}
#{handlebars("application")}
#{handlebars("index")}
#{handlebars("message")}
#{component("tabbed-section")}
#{component("tab-contents")}
#{script("app.js")}
HTML
end
end
end
end