diff options
Diffstat (limited to 'src/guff.cr')
-rw-r--r-- | src/guff.cr | 194 |
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) |