require 'sinatra/base' require 'json' require 'rake' require_relative 'comment' require_relative 'akismet' module Cachai class Middleware < Sinatra::Base # set :database_file, "config/database.yml" # set :public_folder, File.join(settings.root, 'public') # set :protection, true use ActiveRecord::ConnectionAdapters::ConnectionManagement def initialize(app, opts = nil) opts = opts || {} @domain = opts.delete(:domain) or raise 'Domain required.' load_schema unless schema_loaded? if key = opts.delete(:akismet_key) @akismet = Akismet.new(:api_key => key, :blog => "http://#{@domain}") else puts "No Akismet key found! Will not check comments for spam." end super(app) end get '/comments.?:format?' do check_domain!(params[:domain]) # puts "Comments for: #{params[:domain]}#{params[:path]}" list = get_comments(params[:path]) if params[:callback] content_type 'application/javascript' "#{params[:callback]}(#{list.to_json});" else json(list) end end post '/comments.?:format?' do begin data = JSON.parse(request.body.read) check_domain!(data['domain']) headers['Access-Control-Allow-Origin'] = data['protocol'] + '//' + data['domain'] permalink = 'http://' + data['domain'] + data['path'] halt(400, "No spam allowed") if is_spam?(data, permalink, request) attrs = { :path => data['path'], :content => data['content'], :author_name => data['author_name'], :author_email => data['author_email'], :author_url => data['author_url'] } comment = Comment.create!(attrs) json({ :status => 'ok', :comment => comment }) rescue JSON::ParserError status 400 and json({ :error => 'Invalid JSON.' }) rescue ActiveRecord::RecordInvalid => e status 422 and json({ :error => e.message }) end end private def load_schema require 'sinatra/activerecord/rake' # Rake::Task['db:schema:load'].invoke require_relative '../db/schema.rb' end def schema_loaded? Comment.first true rescue ActiveRecord::StatementInvalid => e # SQLite3::SQLException => e # return !e.message['no such table'] false end def check_domain!(domain) halt(400, 'Invalid domain.') unless domain == @domain end def not_found(message = nil) halt(404, message || 'Not found.') end def json(obj) content_type 'application/json' obj.to_json end def get_comments(document_path) Comment.where({ :path => document_path }) end def is_spam?(data, link, request) return false unless @akismet # return true if blacklisted?(name, email, content) comment = { :user_ip => request.ip, :referrer => request.referrer, :user_agent => request.user_agent, :permalink => link, :comment_type => 'comment', :comment_content => data['content'], :comment_author => data['author_name'], :comment_author_url => data['author_url'], :comment_author_email => data['author_email'] } if resp = @akismet.check_comment(comment) # puts resp.inspect return resp[:spam] end false end end end