lib/rack/olark.rb in rack-olark-0.1 vs lib/rack/olark.rb in rack-olark-0.2.0

- old
+ new

@@ -1,67 +1,69 @@ +require 'erb' +require 'json' require 'rack' require 'rack/request' -require 'erb' module Rack class Olark - DEFAULTS = { - tag: '<script>', - paths: [] - } + TEMPLATE_PATH = ::File.expand_path( + ::File.join('..', 'templates', 'olark.erb'), + __FILE__ + ) def initialize(app, options = {}) - unless options[:id] && options[:id].length == 16 - raise ArgumentError, 'Need a valid Olark ID!' + @app = app + + # Validity check on Site-ID + site_id = (options.delete(:id) || '').gsub(/[^0-9-]/, '') + unless site_id.length == 16 + raise ArgumentError, 'rack-olark requires a valid Olark Site-ID!' end - @app, @options = app, DEFAULTS.merge(options) - @id, @tag, @paths = [@options.delete(:id), - @options.delete(:tag), - @options.delete(:paths)] + # Deprecation warnings + deprecation_warning('format') if options.delete(:format) + deprecation_warning('tag') if options.delete(:tag) - if @paths.is_a?(Array) - @paths.map! { |path| path.is_a?(Regexp) ? path : /^#{Regexp.escape(path.to_s)}$/ } - else - @paths = [] + # Is it a Regexp? No? Then escape it, and make it a Regexp. + @paths = (options.delete(:paths) || []).map do |path| + path.is_a?(Regexp) ? path : /^#{Regexp.escape(path.to_s)}$/ end + # Let's please not call Array#empty? on every request. + @inject_all = @paths.empty? - @option_js = "olark.identify('#{@id}');" - @options.each do |key, val| - val = [String, Symbol].include?(val.class) ? "'#{val.to_s}'" : val.to_s - @option_js << "olark.configure('#{key.to_s}', #{val});" - end + js = options.map { |k, v| olarkify(k, v) }.join + @html = ERB.new(::File.read(TEMPLATE_PATH)).result(binding) end - def call(env); dup._call(env); end + def call(env) + status, headers, body = @app.call(env) + request = Rack::Request.new(env) - def _call(env) - @status, @headers, @response = @app.call(env) - @request = Rack::Request.new(env) - valid_path = @paths.select { |path| @request.path_info =~ path }.length > 0 - - # Deprecation warning, repeated and annoying. Sorry about your log space. - if @options[:format] - logger = env['rack.errors'] - logger.write("[#{Time.now.strftime("%Y-%M-%d %H:%M:%S")}] WARNING ") - logger.write("Rack::Olark: The 'format' option no longer works! See README.md for details.\n") - end - - if html? && (@paths.empty? || valid_path) - response = Rack::Response.new([], @status, @headers) - @response.each { |fragment| response.write(inject(fragment)) } + if html?(headers) && (@inject_all || should_inject?(request)) + response = Rack::Response.new([], status, headers) + body.each do |fragment| + response.write(fragment.gsub('</body>', @html)) + end response.finish else - [@status, @headers, @response] + [status, headers, body] end end private - def html?; @headers['Content-Type'] =~ /html/; end + def olarkify(key, val) + "olark.configure(#{key.to_s.to_json}, #{val.to_json});" + end - def inject(response) - template_file = ::File.read(::File.expand_path('../templates/olark.erb', __FILE__)) - @template = ERB.new(template_file).result(binding) - response.gsub('</body>', @template) + def deprecation_warning(option) + STDOUT.puts("Rack::Olark: The '#{option}' option is deprecated and no longer functions! See README.md for details.") + end + + def html?(headers) + (Rack::Utils::HeaderHash.new(headers)['Content-Type'] || '').include?('html') + end + + def should_inject?(request) + @paths.select { |p| request.path_info =~ p }.length > 0 end end end