lib/cachai.rb in cachai-0.0.1 vs lib/cachai.rb in cachai-0.0.2
- old
+ new
@@ -1,26 +1,35 @@
require 'sinatra/base'
+require 'redis'
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
+ # set :logging, nil
+
+ # use Rack::CommonLogger, LOGGER
+ # use Rack::Static, :urls => %w(/css /img /js /favicon.ico), :root => 'public'
use ActiveRecord::ConnectionAdapters::ConnectionManagement
def initialize(app, opts = nil)
opts = opts || {}
@domain = opts.delete(:domain) or raise 'Domain required.'
load_schema unless schema_loaded?
+ redis_host = opts.delete(:redis_host) || 'localhost'
+ @redis = Redis.new(:host => redis_host)
+
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
@@ -30,22 +39,21 @@
get '/comments.?:format?' do
check_domain!(params[:domain])
# puts "Comments for: #{params[:domain]}#{params[:path]}"
- list = get_comments(params[:path])
+ json_list = get_comments(params[:path])
if params[:callback]
content_type 'application/javascript'
- "#{params[:callback]}(#{list.to_json});"
+ "#{params[:callback]}(#{json_list});"
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']
@@ -60,10 +68,12 @@
:author_email => data['author_email'],
:author_url => data['author_url']
}
comment = Comment.create!(attrs)
+
+ @redis.del(redis_key(data['path']))
json({ :status => 'ok', :comment => comment })
rescue JSON::ParserError
status 400 and json({ :error => 'Invalid JSON.' })
rescue ActiveRecord::RecordInvalid => e
@@ -71,21 +81,31 @@
end
end
private
+ def set_cache(timestamp)
+ return if timestamp.nil?
+ last_modified timestamp
+ cache_control :public, :must_revalidate, :max_age => 60
+ end
+
+ def prevent_cache
+ cache_control :public, :no_cache, :no_store, :must_revalidate, :max_age => 0
+ # expires 1.year.ago
+ end
+
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
+ # SQLite3::SQLException => e
# return !e.message['no such table']
false
end
def check_domain!(domain)
@@ -96,14 +116,25 @@
halt(404, message || 'Not found.')
end
def json(obj)
content_type 'application/json'
- obj.to_json
+ return obj.is_a?(String) ? obj : obj.to_json
end
- def get_comments(document_path)
- Comment.where({ :path => document_path })
+ def get_comments(path)
+ key = redis_key(path)
+ unless json_list = @redis.get(key)
+ puts "Not cached. Getting from DB: #{path}"
+ json_list = Comment.where({ :path => path }).to_json
+ @redis.set(key, json_list)
+ @redis.expire(key, 60 * 60) # one hour
+ end
+ json_list
+ end
+
+ def redis_key(path)
+ "comments:#{@domain}:#{path}"
end
def is_spam?(data, link, request)
return false unless @akismet
# return true if blacklisted?(name, email, content)