aboutsummaryrefslogtreecommitdiff
path: root/src/guff.cr
diff options
context:
space:
mode:
Diffstat (limited to 'src/guff.cr')
-rw-r--r--src/guff.cr194
1 files changed, 189 insertions, 5 deletions
diff --git a/src/guff.cr b/src/guff.cr
index 2147c33..b36abc4 100644
--- a/src/guff.cr
+++ b/src/guff.cr
@@ -267,6 +267,88 @@ module Guff
end
end
+ class BlogModel < Model
+ SQL = {
+ get_ids: "
+ SELECT b.post_id
+
+ FROM sites a
+ JOIN posts b
+ ON (b.site_id = a.site_id)
+ JOIN blogs c
+ ON (c.post_id = b.post_id)
+ JOIN states d
+ ON (d.state_id = b.state_id)
+
+ WHERE a.site_id = ?
+ AND %s
+ AND d.state = 'posted'
+ -- TODO: handle posted_at and expired_at
+
+ ORDER BY COALESCE(b.posted_at, b.created_at) DESC
+ ",
+ }
+
+ def get_id(
+ site_id : Int64,
+ year : Int32,
+ month : Int32,
+ day : Int32,
+ slug : String
+ ) : Int64?
+ ids = get_ids(site_id, year, month, day, slug)
+ (ids.size > 0) ? ids.first : nil
+ end
+
+ def get_ids(
+ site_id : Int64,
+ year : Int32? = nil,
+ month : Int32? = nil,
+ day : Int32? = nil,
+ slug : String? = nil
+ ) : Array(Int64)
+ sql = [] of String
+ args = [site_id.to_s]
+
+ STDERR.puts "DEBUG: site_id = #{site_id}, year = #{year}, month = #{month}, day = #{day}, slug = \"#{slug}\""
+
+ if year
+ # add year filter
+ sql << "strftime('%Y', b.posted_at) + 0 = ? + 0"
+ args << year.to_s
+
+ if month
+ # add month filter
+ sql << "strftime('%m', b.posted_at) + 0 = ? + 0"
+ args << month.to_s
+
+ if day
+ # add day filter
+ sql << "strftime('%d', b.posted_at) + 0 = ? + 0"
+ args << day.to_s
+ end
+ end
+ end
+
+ if slug
+ # add slug filter
+ sql << "b.slug = ?"
+ args << slug
+ end
+
+ STDERR.puts "DEBUG: args = #{args.to_json}"
+
+ # exec query, build result
+ r = [] of Int64
+ @context.dbs.ro.all(SQL[:get_ids] % sql.join(" AND "), args) do |row|
+ p row
+ r << row["post_id"] as Int64
+ end
+
+ # return results
+ r
+ end
+ end
class UserModel < Model
def login(user : String, pass : String) : String?
@@ -465,6 +547,7 @@ module Guff
csrf: Models::CSRFModel,
page: Models::PageModel,
project: Models::ProjectModel,
+ blog: Models::BlogModel,
site: Models::SiteModel,
})
end
@@ -1057,8 +1140,6 @@ module Guff
if request.method == "GET"
if md = PATH_RE.match(request.path.not_nil!)
if site_id = get_site_id(request.headers["host"]?)
- STDERR.puts "DEBUG: searching for slug \"#{md["slug"]}\""
-
r = @context.models.page.get_id(
site_id: site_id,
slug: md["slug"],
@@ -1101,8 +1182,6 @@ module Guff
if request.method == "GET"
if md = PATH_RE.match(request.path.not_nil!)
if site_id = get_site_id(request.headers["host"]?)
- STDERR.puts "DEBUG: searching for slug \"#{md["slug"]}\""
-
r = @context.models.project.get_id(
site_id: site_id,
slug: md["slug"],
@@ -1116,6 +1195,90 @@ module Guff
end
end
+ class BlogPostHandler < Handler
+ PATH_RE = %r{^
+ /(?<year>\d{4})
+ /(?<month>\d{2})
+ /(?<day>\d{2})
+ /(?<slug>[^/]+)\.html
+ $}x
+
+ def call(context : HTTP::Server::Context)
+ if id = get_id(context.request)
+ # TODO: render page
+ context.response.content_type = "text/html; charset=utf-8"
+ context.response.status_code = 200
+ context.response << "blog post id: #{id}"
+ else
+ # unknown page
+ call_next(context)
+ end
+ end
+
+ private def get_id(request : HTTP::Request) : Int64?
+ r = nil
+
+ if request.method == "GET"
+ if md = PATH_RE.match(request.path.not_nil!)
+ if site_id = get_site_id(request.headers["host"]?)
+ r = @context.models.blog.get_id(
+ site_id: site_id,
+ year: md["year"].to_i,
+ month: md["month"].to_i,
+ day: md["day"].to_i,
+ slug: md["slug"],
+ )
+ end
+ end
+ end
+
+ # return result
+ r
+ end
+ end
+
+ class BlogListHandler < Handler
+ PATH_RE = %r{^
+ /(?<year>\d{4})/
+ (
+ (?<month>\d{2})/
+ ((?<day>\d{2})/)?
+ )?
+ $}x
+
+ def call(context : HTTP::Server::Context)
+ if ids = get_ids(context.request)
+ # TODO: render page
+ context.response.content_type = "text/html; charset=utf-8"
+ context.response.status_code = 200
+ context.response << "blog list: ids = #{ids.join(", ")}"
+ else
+ # unknown page
+ call_next(context)
+ end
+ end
+
+ private def get_ids(request : HTTP::Request) : Array(Int64)?
+ r = nil
+
+ if request.method == "GET"
+ if md = PATH_RE.match(request.path.not_nil!)
+ if site_id = get_site_id(request.headers["host"]?)
+ r = @context.models.blog.get_ids(
+ site_id: site_id,
+ year: md["year"].to_i,
+ month: md["month"]? ? md["month"].to_i : nil,
+ day: md["day"]? ? md["day"].to_i : nil,
+ )
+ end
+ end
+ end
+
+ # return result
+ r
+ end
+ end
+
HANDLERS = [{
dev: true,
id: :error,
@@ -1149,6 +1312,12 @@ module Guff
}, {
dev: false,
id: :project,
+ }, {
+ dev: false,
+ id: :blog_post,
+ }, {
+ dev: false,
+ id: :blog_list,
}]
def self.get(context : Context) : Array(HTTP::Handler)
@@ -1186,6 +1355,10 @@ module Guff
PageHandler.new(context)
when :project
ProjectHandler.new(context)
+ when :blog_post
+ BlogPostHandler.new(context)
+ when :blog_list
+ BlogListHandler.new(context)
else
raise "unknown handler id: #{handler_id}"
end
@@ -1319,7 +1492,7 @@ module Guff
}, %{
CREATE INDEX in_posts_site_id ON posts(site_id)
}, %{
- CREATE TABLE blog_posts (
+ CREATE TABLE blogs (
post_id INTEGER PRIMARY KEY
REFERENCES posts(post_id)
)
@@ -1437,6 +1610,15 @@ module Guff
'Test Project',
'test-project',
'This is the body of a test project.'
+ ), (
+ 3,
+ 1,
+ 1,
+ (SELECT state_id FROM states WHERE state = 'posted'),
+ CURRENT_TIMESTAMP,
+ 'Test Blog',
+ 'test-blog',
+ 'This is the body of a test blog entry.'
)
}, %{
INSERT INTO pages(post_id, layout_id) VALUES (
@@ -1445,6 +1627,8 @@ module Guff
)
}, %{
INSERT INTO projects(post_id) VALUES (2)
+ }, %{
+ INSERT INTO blogs(post_id) VALUES (3)
}]
private def add_test_data(db)