prepare for rebuilding
This is in preparation of remodeling the blog in go.
This commit is contained in:
parent
5570b0b568
commit
2bea1df808
9
Gemfile
9
Gemfile
|
@ -1,9 +0,0 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem 'sequel'
|
||||
gem 'pg'
|
||||
gem 'zero', :git => 'https://github.com/libzero/zero.git'
|
||||
gem 'slim'
|
||||
gem 'sass'
|
||||
gem 'kramdown'
|
||||
gem 'puma'
|
34
Gemfile.lock
34
Gemfile.lock
|
@ -1,34 +0,0 @@
|
|||
GIT
|
||||
remote: https://github.com/libzero/zero.git
|
||||
revision: dde9fc410fb50bc44b128fb1032b15f09c53e0f7
|
||||
specs:
|
||||
zero (0.2.0)
|
||||
tilt
|
||||
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
kramdown (1.3.2)
|
||||
pg (0.17.1)
|
||||
puma (2.7.1)
|
||||
rack (>= 1.1, < 2.0)
|
||||
rack (1.5.2)
|
||||
sass (3.2.14)
|
||||
sequel (4.7.0)
|
||||
slim (2.0.2)
|
||||
temple (~> 0.6.6)
|
||||
tilt (>= 1.3.3, < 2.1)
|
||||
temple (0.6.7)
|
||||
tilt (2.0.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
kramdown
|
||||
pg
|
||||
puma
|
||||
sass
|
||||
sequel
|
||||
slim
|
||||
zero!
|
|
@ -1,8 +0,0 @@
|
|||
#!/usr/bin/env rackup
|
||||
require File.expand_path('../lib/boot.rb', __FILE__)
|
||||
|
||||
Renderer.find_templates('templates')
|
||||
run Application.new(Router, {
|
||||
:renderer => Renderer,
|
||||
:query => {}
|
||||
})
|
|
@ -1 +0,0 @@
|
|||
:db: "postgres://localhost/blogdb"
|
|
@ -1,7 +0,0 @@
|
|||
module Routes
|
||||
class Atom
|
||||
def self.call(session)
|
||||
Post
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,11 +0,0 @@
|
|||
module Routes
|
||||
class Images
|
||||
def self.call(session)
|
||||
file = "images/#{session.request.path.gsub(/images/, '')}"
|
||||
return RouteNotFound unless File.exist?(file)
|
||||
session.response.body = File.read(file)
|
||||
session.response.content_type = 'image/png'
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,10 +0,0 @@
|
|||
module Routes
|
||||
class MethodNotAllowed
|
||||
def self.call(session)
|
||||
session.response.status = 405
|
||||
session.response.content_type = 'text/html'
|
||||
session.response.body = 'Method not supported by this resource!'
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,63 +0,0 @@
|
|||
module Routes
|
||||
class Post < Controller
|
||||
PREV_AND_NEXT_QUERY = <<SQL
|
||||
select (
|
||||
select id from posts where written < ? and released order by written desc limit 1
|
||||
) older,
|
||||
(
|
||||
select id from posts where written > ? and released order by written limit 1
|
||||
) younger
|
||||
SQL
|
||||
|
||||
def self.get(session)
|
||||
posts = define_posts_query(session)
|
||||
if session.options[:id]
|
||||
posts = posts.filter(:posts__id => session.options[:id].to_i)
|
||||
return RouteNotFound if posts.empty?
|
||||
set_previous_and_next_post(session, posts)
|
||||
else
|
||||
if session.request.params['search']
|
||||
posts = load_fulltextsearch(session, posts)
|
||||
end
|
||||
page = session.request.params['page'].to_i
|
||||
per_page = session.request.params['per_page'].to_i
|
||||
per_page = 10 if per_page && per_page < 1
|
||||
set_page_information(session, posts, page, per_page)
|
||||
posts = posts.limit(per_page).offset(page * per_page)
|
||||
end
|
||||
session.options[:posts] = posts
|
||||
session.options[:render] = 'posts/index'
|
||||
end
|
||||
|
||||
def self.define_posts_query(session)
|
||||
posts = DB[:posts].
|
||||
filter(:released => true).
|
||||
select(:posts__id___post_id, :written, :title, :content, :username).
|
||||
join(:accounts, :id___account_id => :account_id).
|
||||
reverse_order(:written, :posts__id)
|
||||
end
|
||||
|
||||
# load posts depending on the pagination
|
||||
def self.set_page_information(session, posts, page, per_page)
|
||||
# compute pages
|
||||
session.options[:page] = page if page
|
||||
session.options[:query][:per_page] = per_page if per_page
|
||||
session.options[:pages] = posts.count / per_page
|
||||
end
|
||||
|
||||
# load a single posts and the ids of the next and previous posts
|
||||
def self.set_previous_and_next_post(session, posts)
|
||||
written = posts.first[:written]
|
||||
session.options[:post_ids_pn] = DB[PREV_AND_NEXT_QUERY, written, written].first
|
||||
end
|
||||
|
||||
# adjust query to use fulltext search
|
||||
def self.load_fulltextsearch(session, posts)
|
||||
session.options[:query][:search] = session.request.params['search']
|
||||
posts.filter(
|
||||
'posts.search_field @@ to_tsquery(\'english\', ?)',
|
||||
session.request.params['search'].tr(' ', '&')
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,8 +0,0 @@
|
|||
module Routes
|
||||
class RouteNotFound < Controller
|
||||
def self.get(session)
|
||||
session.options[:render] = 'error/route_not_found'
|
||||
session.response.status = 404
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,8 +0,0 @@
|
|||
module Routes
|
||||
class Stylesheet
|
||||
def self.call(session)
|
||||
session.options[:render] = 'stylesheet/index'
|
||||
session.options[:renderer]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,7 +0,0 @@
|
|||
module Routes
|
||||
class Welcome
|
||||
def self.call(session)
|
||||
Post
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,19 +0,0 @@
|
|||
class Application
|
||||
def initialize(start, defaults = {})
|
||||
@start = start
|
||||
@defaults = defaults
|
||||
end
|
||||
|
||||
def call(env)
|
||||
session = Session.new(
|
||||
::Zero::Request.new(env),
|
||||
::Zero::Response.new,
|
||||
Render.new(@defaults.clone)
|
||||
)
|
||||
worker = @start
|
||||
while not worker.nil?
|
||||
worker = worker.call(session)
|
||||
end
|
||||
session.response.to_a
|
||||
end
|
||||
end
|
16
lib/boot.rb
16
lib/boot.rb
|
@ -1,16 +0,0 @@
|
|||
$LOAD_PATH << File.expand_path('..', __FILE__)
|
||||
|
||||
require 'libraries'
|
||||
require 'session'
|
||||
require 'application'
|
||||
require 'controller'
|
||||
require 'renderer'
|
||||
require 'render'
|
||||
require 'router'
|
||||
|
||||
config = YAML.load_file(File.expand_path('../../config.yml', __FILE__))
|
||||
DB = Sequel.connect(config[:db])
|
||||
|
||||
Dir[File.expand_path('../../controller', __FILE__) + '/**'].each do |controller|
|
||||
require controller
|
||||
end
|
|
@ -1,12 +0,0 @@
|
|||
class Controller
|
||||
def self.call(session)
|
||||
return call_method(session) if respond_to? session.request.method
|
||||
Routes::MethodNotAllowed.call(session)
|
||||
end
|
||||
|
||||
def self.call_method(session)
|
||||
result = send(session.request.method, session)
|
||||
return result if result.kind_of?(Class)
|
||||
session.options[:renderer]
|
||||
end
|
||||
end
|
|
@ -1,9 +0,0 @@
|
|||
require 'bundler/setup'
|
||||
require 'yaml'
|
||||
require 'sass'
|
||||
require 'tilt'
|
||||
require 'tilt/sass'
|
||||
require 'sequel'
|
||||
require 'zero'
|
||||
require 'slim'
|
||||
require 'kramdown'
|
|
@ -1,46 +0,0 @@
|
|||
# defines a render container with some helper functions to keep the templates
|
||||
# small
|
||||
class Render
|
||||
SLASH = '/'
|
||||
|
||||
def initialize(options)
|
||||
@options = options
|
||||
end
|
||||
|
||||
def [](key)
|
||||
fetch(key)
|
||||
end
|
||||
|
||||
def []=(key, value)
|
||||
@options[key] = value
|
||||
end
|
||||
|
||||
def fetch(key)
|
||||
@options[key]
|
||||
end
|
||||
|
||||
def has_key?(key)
|
||||
@options.has_key?(key)
|
||||
end
|
||||
|
||||
def options
|
||||
@options
|
||||
end
|
||||
|
||||
def link_to(*params)
|
||||
query = []
|
||||
while params.last.kind_of? Hash
|
||||
query.push params.pop
|
||||
end
|
||||
return path(params) if query.empty?
|
||||
path(params) + '?' + query_string(query)
|
||||
end
|
||||
|
||||
def path(params)
|
||||
SLASH + params.join(SLASH)
|
||||
end
|
||||
|
||||
def query_string(query)
|
||||
URI.encode_www_form(query.inject(:merge))
|
||||
end
|
||||
end
|
|
@ -1,84 +0,0 @@
|
|||
class Renderer
|
||||
COMPONENT_MATCHER = %r{/?(?<template>[^\.]+)\.(?<type>[^\.]+)\.(?<engine>.+)}
|
||||
DEFAULT_TYPE = :default_type
|
||||
|
||||
def self.call(session)
|
||||
template = do_checks(session)
|
||||
return nil unless template
|
||||
type = get_type(session, template)
|
||||
session.response.body = render(template, type, session.options)
|
||||
session.response.content_type = type_map[type]
|
||||
nil
|
||||
end
|
||||
|
||||
def self.render(template, type, object)
|
||||
layout = templates['layout']
|
||||
if layout && layout.has_key?(type)
|
||||
return layout[type].render(object) do
|
||||
template[type].render(object)
|
||||
end
|
||||
end
|
||||
template[type].render(object)
|
||||
end
|
||||
|
||||
def self.do_checks(session)
|
||||
unless session.options.has_key? :render
|
||||
session.response.body = ':render not set!'
|
||||
return nil
|
||||
end
|
||||
to_render = session.options[:render]
|
||||
unless templates.has_key? to_render
|
||||
session.response.body = 'Template does not exist!'
|
||||
return nil
|
||||
end
|
||||
return templates[to_render]
|
||||
end
|
||||
|
||||
# initialize the template cache
|
||||
def self.find_templates(path)
|
||||
templates = {}
|
||||
Dir[path + '/**/*'].each do |file|
|
||||
parts = file.gsub(path, '').match(COMPONENT_MATCHER)
|
||||
next unless File.file?(file) && parts
|
||||
templates[parts[:template]] ||= {}
|
||||
templates[parts[:template]].merge!({parts[:type].to_sym => Tilt.new(file)})
|
||||
end
|
||||
templates
|
||||
end
|
||||
|
||||
def self.templates
|
||||
@@templates ||= find_templates 'templates'
|
||||
end
|
||||
|
||||
def self.set_types(types)
|
||||
@@type_map = types.invert
|
||||
@@types = types
|
||||
end
|
||||
|
||||
def self.types
|
||||
@@types ||= {
|
||||
'*/*' => DEFAULT_TYPE,
|
||||
'text/css' => :css,
|
||||
'text/html' => :html,
|
||||
'application/atom+xml' => :atom
|
||||
}
|
||||
end
|
||||
|
||||
def self.type_map
|
||||
@@type_map ||= types.invert
|
||||
end
|
||||
|
||||
def self.get_type(session, template)
|
||||
type = get_preferred_type(session.request, template)
|
||||
return template.first[0] if type == DEFAULT_TYPE
|
||||
type
|
||||
end
|
||||
|
||||
def self.get_preferred_type(request, template)
|
||||
request.accept.types.each do |type|
|
||||
next unless types.has_key? type
|
||||
return types[type] if template.has_key? types[type]
|
||||
return DEFAULT_TYPE if types[type] == DEFAULT_TYPE
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,38 +0,0 @@
|
|||
class Router
|
||||
ROUTE_REGEX = %r{\A(/(?<controller>[a-zA-Z]+)\.?(?<extension>[a-zA-Z]+)?(/(?<id>[^/]+)?)?)?\Z}
|
||||
# get the controller handling the request
|
||||
def self.call(session)
|
||||
variables = session.request.path.match(ROUTE_REGEX)
|
||||
return default_route unless variables && variables[:controller]
|
||||
session.options[:id] = variables[:id]
|
||||
find(variables[:controller])
|
||||
end
|
||||
|
||||
# the namespace of all routes
|
||||
def self.namespace
|
||||
@@namespace ||= ::Routes
|
||||
end
|
||||
|
||||
# set the namespace to a module or class which holds all controllers
|
||||
def self.set_namespace(namespace)
|
||||
@@namespace = namespace
|
||||
end
|
||||
|
||||
# the default route to take when no path is given
|
||||
def self.default_route
|
||||
@@default ||= namespace.const_get(:Welcome)
|
||||
end
|
||||
|
||||
# set the default route to take when no path is given
|
||||
def self.set_default_route(default)
|
||||
@@default = default
|
||||
end
|
||||
|
||||
# check for the controller name and return 404 when not found
|
||||
def self.find(ctrl)
|
||||
ctrl = ctrl.capitalize
|
||||
# make constant lookup without ancestors
|
||||
return namespace.const_get(ctrl, false) if namespace.const_defined?(ctrl, false)
|
||||
namespace::RouteNotFound
|
||||
end
|
||||
end
|
|
@ -1 +0,0 @@
|
|||
Session = Struct.new(:request, :response, :options)
|
Loading…
Reference in New Issue