aboutsummaryrefslogtreecommitdiff
path: root/src/guff.cr
diff options
context:
space:
mode:
Diffstat (limited to 'src/guff.cr')
-rw-r--r--src/guff.cr160
1 files changed, 160 insertions, 0 deletions
diff --git a/src/guff.cr b/src/guff.cr
new file mode 100644
index 0000000..7e32bfc
--- /dev/null
+++ b/src/guff.cr
@@ -0,0 +1,160 @@
+require "sqlite3"
+require "http/server"
+require "./guff/*"
+
+module Guff
+ class Database < ::SQLite3::Database
+ # TODO (add table_exists?)
+ end
+
+ class Model
+ getter :db
+
+ def initialize(@config : Config)
+ # create site database
+ db_path = "%s/site.db" % [config["data"]]
+ @db = Database.new(db_path)
+ end
+ end
+
+ class Handler < ::HTTP::Handler
+ getter :model
+ getter :config
+
+ def initialize(@model : Model, @config : Config)
+ end
+
+ def call(context : HTTP::Server::Context)
+ # do nothing by default
+ call_next(context)
+ end
+ end
+
+
+ class BlogHandler < Handler
+ MATCHES = [%r{
+ ^/
+
+ # match YYYY/MM/DD/SLUG.html
+ (?<year>\d{4})
+ /
+ (?<month>\d{2})
+ /
+ (?<day>\d{2})
+ /
+ (?<slug>[a-z0-9._-]+)
+ \.html
+
+ $
+ }x, %r{
+ ^/
+
+ # match YYYY/MM/DD
+ (?<year>\d{4})
+ /
+ (?<month>\d{2})
+ /
+ (?<day>\d{2})
+ /?
+
+ $
+ }x, %r{
+ ^/
+
+ # match YYYY/MM
+ (?<year>\d{4})
+ /
+ (?<month>\d{2})
+ /?
+
+ $
+ }x, %r{
+ ^/
+
+ # match YYYY
+ (?<year>\d{4})
+ /?
+
+ $
+ }x, %r{
+ ^/
+
+ # match index
+ blog/?
+ |
+
+ $
+ }x]
+
+ def call(context : HTTP::Server::Context)
+ path = context.request.path || ""
+ if md = MATCHES.reduce(nil) { |r, m| r || m.match(path) }
+ context.response.puts "blog match: %s" % [md.to_s]
+ else
+ call_next(context)
+ end
+ end
+ end
+
+ class SlugHandler < Handler
+ MOCK_SLUGS = {
+ "foo": "test slug foo",
+ "bar": "test slug bar",
+ "baz": "test slug baz",
+ }
+
+ def call(context : HTTP::Server::Context)
+ puts "SlugHandler: path = %s" % [context.request.path]
+ call_next(context)
+ end
+ end
+
+ class Server
+ def self.run(model : Model, config : Config)
+ new(model, config).run
+ end
+
+ def initialize(@model : Model, @config : Config)
+ # create server
+ @server = HTTP::Server.new(
+ config["host"],
+ config["port"].to_i,
+ get_handlers(model, config)
+ ) do |context|
+ context.response.puts "asdf"
+ end
+ end
+
+ def run
+ puts "listening on %s:%s" % %w{host port}.map { |k| @config[k] }
+ @server.listen
+ end
+
+ private def get_handlers(
+ model : Model,
+ config : Config
+ ) : Array(HTTP::Handler)
+ @handlers ||= [
+ HTTP::ErrorHandler.new,
+ HTTP::LogHandler.new,
+ HTTP::DeflateHandler.new,
+ BlogHandler.new(model, config),
+ SlugHandler.new(model, config),
+ HTTP::StaticFileHandler.new(config["public"]),
+ ]
+ end
+ end
+
+ def self.run(app, args)
+ # parse env and cli options
+ config = Config.new(app, args)
+
+ # create model
+ model = Model.new(config)
+
+ # create server
+ Server.run(model, config)
+ end
+end
+
+Guff.run($0, ARGV)