porom/apps/threads.lua

173 lines
5.2 KiB
Lua

local app = require("lapis").Application()
local lapis_util = require("lapis.util")
local constants = require("constants")
local db = require("lapis.db")
local util = require("util")
local models = require("models")
local Topics = models.Topics
local Threads = models.Threads
local Posts = models.Posts
local POSTS_PER_PAGE = 10
app:get("thread_create", "/create", function(self)
local user = util.get_logged_in_user(self)
if not user then
util.inject_err_infobox(self, "You must be logged in to perform this action.")
return {redirect_to = self:url_for("user_login")}
end
local all_topics = db.query("select * from topics limit 25;")
if #all_topics == 0 then
return "how did you get here?"
end
self.all_topics = all_topics
self.page_title = "drafting a thread"
self.me = user
return {render = "threads.create"}
end)
app:post("thread_create", "/create", function(self)
local user = util.get_logged_in_user(self)
if not user then
util.inject_err_infobox(self, "You must be logged in to perform this action.")
return {redirect_to = self:url_for("user_login")}
end
local topic = Topics:find(self.params.topic_id)
if not topic then
return {redirect_to = self:url_for("all_topics")}
end
if util.is_topic_locked(topic) and not user:is_mod() then
return {redirect_to = self:url_for("all_topics")}
end
local title = lapis_util.trim(self.params.title)
local time = os.time()
local slug = lapis_util.slugify(title) .. "-" .. time
local post_content = self.params.initial_post
local thread = Threads:create({
topic_id = topic.id,
user_id = user.id,
title = title,
slug = slug,
created_at = time,
})
local post = util.create_post(thread.id, user.id, post_content)
if not post then
return {redirect_to = self:url_for("all_topics")}
end
return {redirect_to = self:url_for("thread", {slug = slug})}
end)
app:get("thread", "/:slug", function(self)
local thread = Threads:find({
slug = self.params.slug
})
if not thread then
return {status = 404}
end
self.thread = thread
local post_count = Posts:count(db.clause({
thread_id = thread.id
}))
self.pages = math.max(math.ceil(post_count / POSTS_PER_PAGE), 1)
if self.params.after then
local after_id = tonumber(self.params.after)
local post_position = Posts:count(db.clause({
thread_id = thread.id,
{"id <= ?", after_id},
}))
self.page = math.floor((post_position - 1) / POSTS_PER_PAGE) + 1
else
self.page = math.max(1, math.min(tonumber(self.params.page) or 1, self.pages))
end
-- self.page = math.max(1, math.min(self.page, self.pages))
local query = (constants.FULL_POSTS_QUERY ..
"WHERE posts.thread_id = ? ORDER BY posts.created_at ASC LIMIT ? OFFSET ?")
local posts = db.query(query, thread.id, POSTS_PER_PAGE, (self.page - 1) * POSTS_PER_PAGE)
self.topic = Topics:find(thread.topic_id)
self.me = util.get_logged_in_user_or_transient(self)
self.posts = posts
self.page_title = thread.title
return {render = "threads.thread"}
end)
app:post("thread", "/:slug", function(self)
local thread = Threads:find({
slug = self.params.slug
})
if not thread then
return {redirect_to = self:url_for("all_topics")}
end
local user = util.get_logged_in_user(self)
if not user then
return {redirect_to = self:url_for("all_topics")}
end
if user:is_guest() then
return {redirect_to = self:url_for("thread", {slug = thread.slug})}
end
if util.is_thread_locked(thread) and not user:is_mod() then
return {redirect_to = self:url_for("thread", {slug = thread.slug})}
end
local post_content = self.params.post_content
local post = util.create_post(thread.id, user.id, post_content)
local post_count = Posts:count(db.clause({
thread_id = thread.id
}))
local last_page = math.ceil(post_count / POSTS_PER_PAGE)
if not post then
return {redirect_to = self:url_for("thread", {slug = thread.slug}, {page = last_page}) .. "#latest-post"}
end
return {redirect_to = self:url_for("thread", {slug = thread.slug}, {page = last_page}) .. "#latest-post"}
end)
app:post("thread_lock", "/:slug/lock", function(self)
local user = util.get_logged_in_user(self)
if not user then
return {redirect_to = self:url_for("thread", {slug = self.params.slug})}
end
local thread = Threads:find({slug = self.params.slug})
if not ((thread.user_id == user.id) or user:is_mod()) then
return {redirect_to = self:url_for("thread", {slug = self.params.slug})}
end
local target_op = util.form_bool_to_sqlite(self.params.target_op)
thread:update({
is_locked = target_op,
})
return {redirect_to = self:url_for("thread", {slug = self.params.slug})}
end)
app:post("thread_sticky", "/:slug/sticky", function(self)
local user = util.get_logged_in_user(self)
if not user then
return {redirect_to = self:url_for("thread", {slug = self.params.slug})}
end
if not user:is_mod() then
return {redirect_to = self:url_for("thread", {slug = self.params.slug})}
end
local thread = Threads:find({slug = self.params.slug})
local target_op = util.form_bool_to_sqlite(self.params.target_op)
thread:update({
is_stickied = target_op,
})
return {redirect_to = self:url_for("thread", {slug = self.params.slug})}
end)
return app