You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

243 lines
7.4 KiB
Lua

local assert_error = require("lapis.application").assert_error
local assert_valid = require("lapis.validate").assert_valid
local csrf = require "lapis.csrf"
local capture = require "utils.capture"
local format = require "utils.text_formatter"
local generate = require "utils.generate"
local process = require "utils.request_processor"
local Posts = require "models.posts"
return {
before = function(self)
-- Get board
for _, board in ipairs(self.boards) do
if board.name == self.params.uri_name then
self.board = board
break
end
end
-- Board not found
if not self.board or self.params.page and not tonumber(self.params.page) then
return self:write({ redirect_to = self:url_for("web.pages.index") })
end
-- Get announcements
-- TODO: Consolidate these into a single call
self.announcements = assert_error(capture.get(self:url_for("api.announcements.announcement", { uri_id="global" })))
local board_announcements = assert_error(capture.get(self:url_for("api.boards.announcements", { uri_name=self.params.uri_name })))
for _, announcement in ipairs(board_announcements) do
table.insert(self.announcements, announcement)
end
-- Page title
self.page_title = string.format(
"/%s/ - %s",
self.board.name,
self.board.title
)
-- Flag comments as required or not
self.comment_flag = self.board.thread_comment
-- Generate CSRF token
self.csrf_token = csrf.generate_token(self)
-- Current page
self.params.page = self.params.page or 1
-- Get threads
local response = assert_error(capture.get(self:url_for("api.boards.threads", { uri_name=self.params.uri_name, uri_page=self.params.page })))
self.threads = response.threads
self.pages = response.pages
-- Get posts
for _, thread in ipairs(self.threads) do
-- Get posts visible on the board index
thread.posts = Posts:get_index_posts(thread.id)
-- Get hidden posts
thread.hidden = Posts:count_hidden_posts(thread.id)
-- Get op
local op = thread.posts[#thread.posts]
if not op then
assert_error(false, { "err_orphaned", { thread.id } })
end
thread.url = self:url_for("web.boards.thread", { uri_name=self.board.name, thread=op.post_id })
-- Format comments
for _, post in ipairs(thread.posts) do
-- OP gets a thread tag
if post.post_id == op.post_id then
post.thread = post.post_id
end
post.name = post.name or self.board.anon_name
post.reply = self:url_for("web.boards.thread", { uri_name=self.board.name, thread=op.post_id, anchor="q", id=post.post_id })
post.link = self:url_for("web.boards.thread", { uri_name=self.board.name, thread=op.post_id, anchor="p", id=post.post_id })
post.remix = self:url_for("web.boards.thread", { uri_name=self.board.name, thread=op.post_id, anchor="r", id=post.post_id })
post.timestamp = os.date("%Y-%m-%d (%a) %H:%M:%S", post.timestamp)
post.file_size = math.floor(post.file_size / 1024)
post.file_dimensions = ""
if post.file_width > 0 and post.file_height > 0 then
post.file_dimensions = string.format(", %dx%d", post.file_width, post.file_height)
end
if not post.file_duration or post.file_duration == "0" then
post.file_duration = ""
else
post.file_duration = string.format(", %s", post.file_duration)
end
if post.file_path then
local name, ext = post.file_path:match("^(.+)(%..+)$")
ext = string.lower(ext)
-- Get thumbnail URL
if post.file_type == "audio" then
if post == thread.posts[#thread.posts] then
post.thumb = self:format_url(self.static_url, "op_audio.png")
else
post.thumb = self:format_url(self.static_url, "post_audio.png")
end
elseif post.file_type == "image" then
if post.file_spoiler then
if post == thread.posts[#thread.posts] then
post.thumb = self:format_url(self.static_url, "op_spoiler.png")
else
post.thumb = self:format_url(self.static_url, "post_spoiler.png")
end
else
if ext == ".webm" or ext == ".svg" then
post.thumb = self:format_url(self.files_url, self.board.name, 's' .. name .. '.png')
else
post.thumb = self:format_url(self.files_url, self.board.name, 's' .. post.file_path)
end
end
end
post.file_path = self:format_url(self.files_url, self.board.name, post.file_path)
end
-- Process comment
if post.comment then
local comment = post.comment
comment = format.sanitize(comment)
comment = format.quote(comment, self, self.board, post)
comment = format.green_text(comment)
comment = format.blue_text(comment)
comment = format.spoiler(comment)
comment = format.new_lines(comment)
post.comment = comment
else
post.comment = ""
end
end
end
end,
on_error = function(self)
self.errors = generate.errors(self.i18n, self.errors)
return { render = "board"}
end,
GET = function()
return { render = "board" }
end,
POST = function(self)
-- Validate CSRF token
csrf.assert_token(self)
local board_url = self:url_for("web.boards.board", { uri_name=self.board.name })
-- Submit new thread
if self.params.submit then
-- Validate user input
assert_valid(self.params, {
{ "name", max_length=255 },
{ "subject", max_length=255 },
{ "options", max_length=255 },
{ "comment", max_length=self.text_size }
})
-- Validate post
local post = assert_error(process.create_thread(self.params, self.session, self.board))
return { redirect_to = self:url_for("web.boards.thread", { uri_name=self.board.name, thread=post.post_id, anchor="p", id=post.post_id }) }
end
-- Delete thread
if self.params.delete and self.params.thread_id then
-- Validate user input
assert_valid(self.params, {
{ "post_id", exists=true }
})
-- Validate deletion
assert_error(process.delete_thread(self.params, self.session, self.board))
return { redirect_to = board_url }
end
-- Delete post
if self.params.delete and not self.params.thread_id then
-- Validate user input
assert_valid(self.params, {
{ "post_id", exists=true }
})
-- Validate deletion
assert_error(process.delete_post(self.params, self.session, self.board))
return { redirect_to = board_url }
end
-- Report post
if self.params.report then
-- Validate user input
assert_valid(self.params, {
{ "board", exists=true },
{ "post_id", exists=true }
})
-- Validate report
assert_error(process.report_post(self.params, self.board))
return { redirect_to = board_url }
end
-- Admin commands
if self.session.admin or self.session.mod then
-- Sticky thread
if self.params.sticky then
assert_error(process.sticky_thread(self.params, self.board))
return { redirect_to = board_url }
end
-- Lock thread
if self.params.lock then
assert_error(process.lock_thread(self.params, self.board))
return { redirect_to = board_url }
end
-- Save thread
if self.params.save then
assert_error(process.save_thread(self.params, self.board))
return { redirect_to = board_url }
end
-- Override thread
if self.params.override then
assert_error(process.override_thread(self.params, self.board))
return { redirect_to = board_url }
end
-- Ban user
if self.params.ban then
assert_error(process.ban_user(self.params, self.board))
return { redirect_to = board_url }
end
end
return { redirect_to = board_url }
end
}