lib/rewritten/server.rb
require 'sinatra/base'
require 'erb'
require 'rewritten'
require 'rewritten/version'
require 'time'
module Rewritten
class Server < Sinatra::Base
dir = File.dirname(File.expand_path(__FILE__))
set :views, "#{dir}/server/views"
set :public_folder, "#{dir}/server/public"
set :static, true
helpers do
include Rack::Utils
alias_method :h, :escape_html
def current_section
url_path request.path_info.sub('/', '').split('/')[0].downcase
end
def current_page
url_path request.path_info.sub('/', '')
end
def url_path(*path_parts)
[path_prefix, path_parts].join('/').squeeze('/')
end
alias_method :u, :url_path
def path_prefix
request.env['SCRIPT_NAME']
end
def class_if_current(path = '')
'class="current"' if current_page[0, path.size] == path
end
def tab(name)
dname = name.to_s.downcase
path = url_path(dname)
"<li #{class_if_current(path)}><a href='#{path}'>#{name}</a></li>"
end
def tabs
Rewritten::Server.tabs
end
def redis_get_size(key)
case Resque.redis.type(key)
when 'none'
[]
when 'list'
Resque.redis.llen(key)
when 'set'
Resque.redis.scard(key)
when 'string'
Resque.redis.get(key).length
when 'zset'
Resque.redis.zcard(key)
end
end
def redis_get_value_as_array(key, start = 0)
case Resque.redis.type(key)
when 'none'
[]
when 'list'
Resque.redis.lrange(key, start, start + 20)
when 'set'
Resque.redis.smembers(key)[start..(start + 20)]
when 'string'
[Resque.redis.get(key)]
when 'zset'
Resque.redis.zrange(key, start, start + 20)
end
end
def extract_translations
text = params[:translations] || ''
text.split("\n").map(&:strip).reject(&:empty?)
end
def show_args(args)
Array(args).map(&:inspect).join("\n")
end
def worker_hosts
@worker_hosts ||= worker_hosts!
end
def worker_hosts!
hosts = Hash.new { [] }
Resque.workers.each do |worker|
host, = worker.to_s.split(':')
hosts[host] += [worker.to_s]
end
hosts
end
def partial?
@partial
end
def partial(template, local_vars = {})
@partial = true
erb(template.to_sym, { layout: false }, local_vars)
ensure
@partial = false
end
def poll
if @polling
text = "Last Updated: #{Time.now.strftime('%H:%M:%S')}"
else
text = "<a href='#{u(request.path_info)}.poll' rel='poll'>Live Poll</a>"
end
"<p class='poll'>#{text}</p>"
end
end # enf of helpers
def show(page, layout = true)
erb page.to_sym, { layout: layout }, rewritten: Rewritten
rescue Errno::ECONNREFUSED
erb :error, { layout: false }, error: "Can't connect to Redis! (#{Rewritten.redis_id})"
end
def show_for_polling(page)
content_type 'text/html'
@polling = true
show(page.to_sym, false).gsub(/\s{1,}/, ' ')
end
################################################################################
get '/?' do
redirect url_path(:translations)
end
get '/translations' do
@size = 0
@start = params[:start].to_i
filter = params[:f]
if filter && filter != ''
@translations = []
keys = Rewritten.redis.keys("from:#{filter}") +
Rewritten.redis.keys("to:#{filter}")
keys.each do |key|
prefix, url = key.split(':')
if prefix == 'from'
to = Rewritten.translate(url)
@translations << [url, to]
elsif prefix == 'to'
from = Rewritten.get_current_translation(url)
@translations << [from, url]
end
end
@size = @translations.size
@translations = @translations[params[:start].to_i..params[:start].to_i + Rewritten.per_page - 1]
else
@size = Rewritten.num_froms
froms = Rewritten.all_froms[@start, @start + Rewritten.per_page - 1]
@translations = froms.map { |f| [f, Rewritten.translate(f)] }
end
show 'translations'
end
get '/new' do
@translations = []
show 'new'
end
get '/edit' do
@old_to = @to = params[:to]
@translations = Rewritten.get_all_translations(@to).map { |t| Rewritten.full_line(t) }
show 'edit'
end
post '/edit' do
@old_to = params[:old].strip
@to = params[:to].strip
@translations = extract_translations
if @to != '' and @translations.size > 0
# delete old translations
Rewritten.remove_all_translations(@old_to)
# create new translations
Rewritten.add_translations(@to, @translations)
redirect u("/to?to=#{escape(@to)}")
else
show 'edit'
end
end
post '/translations' do
@to = params[:to].strip
@translations = extract_translations
if @to != '' && @translations.size > 0
Rewritten.add_translations(@to, @translations)
redirect u('translations')
else
show 'new'
end
end
get '/to' do
@translations = Rewritten.get_all_translations(params[:to])
show 'to'
end
get '/cleanup' do
# find keys that have no target
@from_without_tos = []
Rewritten.all_froms.each do |from|
@from_without_tos << from if Rewritten.redis.get("from:#{from}").empty?
end
show 'cleanup'
end
get '/delete' do
@from = params[:from]
@to = params[:to]
show 'delete'
end
post '/delete' do
from = params[:from]
to = params[:to]
Rewritten.remove_translation(from, to)
redirect u('/')
end
get '/delete_all' do
@to = params[:to]
show 'delete_all'
end
post '/delete_all' do
Rewritten.remove_all_translations(params[:to])
redirect u('/')
end
get '/hits' do
show 'hits'
end
get '/hits/clear' do
show 'clear_hits'
end
post '/hits/clear' do
Rewritten.redis.del('hits')
redirect u('/hits')
end
def self.tabs
@tabs ||= %w(Translations Hits)
end
end
end