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
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
|
|
}
|