local app = require("lapis").Application() local lapis_util = require("lapis.util") 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 = "creating 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("topics")} end if util.is_topic_locked(topic) then return {redirect_to = self:url_for("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("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 posts = db.query([[ SELECT posts.id, posts.created_at, post_history.content, post_history.edited_at, users.username, users.status, avatars.file_path AS avatar_path FROM posts JOIN post_history ON posts.current_revision_id = post_history.id JOIN users ON posts.user_id = users.id LEFT JOIN avatars ON users.avatar_id = avatars.id WHERE posts.thread_id = ? ORDER BY posts.created_at ASC LIMIT ? OFFSET ? ]], 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) return app