view src/lib/Post.luan @ 11:3ed1e3f3a53a

use bbcode_to_html
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 30 Jun 2022 20:05:11 -0600
parents de0cbf515ef5
children bff178656073
line wrap: on
line source

local Luan = require "luan:Luan.luan"
local error = Luan.error
local ipairs = Luan.ipairs or error()
local set_metatable = Luan.set_metatable or error()
local Time = require "luan:Time.luan"
local time_now = Time.now or error()
local Html = require "luan:Html.luan"
local html_encode = Html.encode or error()
local Db = require "site:/lib/Db.luan"


local Post = {}

local function from_doc(doc)
	doc.type == "post" or error "wrong type"
	return Post.new {
		id = doc.id
		content = doc.content
		date = doc.date
		author_name = doc.post_author_name
		root_id = doc.post_root_id

		-- root only
		subject = doc.subject
		is_root = doc.post_is_root == "true"

		-- replies only
		parent_id = doc.parent_id
	}
end

local function to_doc(post)
	return {
		type = "post"
		id = post.id
		content = post.content or error()
		date = post.date or time_now()
		post_author_name = post.author_name or error()
		post_root_id = post.root_id

		-- root only
		subject = post.subject
		post_is_root = post.is_root and "true" or nil

		-- replies only
		parent_id = post.parent_id
	}
end

local metatable = {}
function metatable.__index(post,key)
	if key == "author" then
		local User = require "site:/lib/User.luan"
		return User.get_by_name(post.author_name)
	end
	if key == "subject_html" then
		return post.subject and html_encode(post.subject)
	end
	if key == "root" then
		return post.is_root and post or Post.get_by_id(post.root_id)
	end
	return nil
end

function Post.new(post)

	function post.save()
		local doc = to_doc(post)
		Db.save(doc)
		post.id = doc.id
	end

	function post.reply(author,content)
		return Db.run_in_transaction( function()
			local post = Post.new{
				root_id = post.root_id
				parent_id = post.id
				content = content
				author_name = author.name
			}
			post.save()
			return post
		end )
	end

	set_metatable(post,metatable)
	return post
end

function Post.get_by_id(id)
	local doc = Db.get_document("id:"..id)
	return doc and from_doc(doc)
end

function Post.new_thread(author,subject,content)
	return Db.run_in_transaction( function()
		local post = Post.new{
			subject = subject or error()
			content = content
			author_name = author.name
			is_root = true
		}
		post.save()
		post.root_id = post.id or error()
		post.save()
		return post
	end )
end

function Post.from_docs(docs)
	local posts = {}
	for _, doc in ipairs(docs) do
		local post = from_doc(doc)
		posts[#posts+1] = post
	end
	return posts
end

return Post