module(..., package.seeall) require("mime") require("ltn12") local base64_wrap = ltn12.filter.chain(mime.encode("base64"), mime.wrap("base64")) actions = {} function actions.mimetype(node, request, sputnik) local type = node.file_type local ext = sputnik.config.MIME_TYPES[type] if ext == request.action then return mime.unb64(node.content), type else node:post_error("Requested action does not match file content: " .. tostring(node.type)) return node.wrappers.default(node, request, sputnik) end end local TPL_FILE_INFO = [=[

File information

$if_image[[]]
Filename$filename
Size$size
Content-type$type

Download this file

]=] function actions.show(node, request, sputnik) local ext = sputnik.config.MIME_TYPES[node.file_type or ""] node.inner_html = cosmo.f(TPL_FILE_INFO){ filename = node.file_name, size = node.file_size, type = node.file_type, link = sputnik:make_link(node.name, "download"), if_image = cosmo.c(node.file_type:match("image")){ url = sputnik:make_url(node.name, ext, {version=request.params.version}) } } return node.wrappers.default(node, request, sputnik) end function actions.download(node, request, sputnik) local filename = node.file_name local mime_type = node.file_type -- Set the Content-disposition header, and suggest a filename node:add_header("Content-Disposition", "attachment; filename=\""..node.file_name.."\"") return mime.unb64(node.content), mime_type end function actions.save(node, request, sputnik) local info = request.params.file_upload if info then local type = info["content-type"] local name = info.name local size = info.size local file = info.contents -- Clear out the file_upload parameter request.params.file_update = nil -- Check to see if we're editing fields, rather than uploading -- a new file by checking filename and filesize. if name and name:match("%S") and size > 0 then -- A file was uploaded request.params.content = base64_wrap(info.contents) request.params.file_type = type request.params.file_name = tostring(name) request.params.file_size = tostring(size) -- Set the correct action local ext = sputnik.config.MIME_TYPES[type] if not ext and sputnik.auth:get_metadata(request.user, "is_admin") ~= "true" then node:post_error("The file you uploaded did not match a known file type: " .. tostring(type)) request.try_again = true elseif ext then request.params.actions = string.format([[%s = "binaryfile.mimetype"]], ext, ext) end elseif node.content:match("%S") then -- Do nothing else request.try_again = true end else node:post_error("Did not receive a file in the request") request.try_again = true end -- Was something incomplete? if request.try_again then request.params.content = nil request.params.file_type = nil request.params.file_name = nil request.params.file_size = nil return node.actions.edit(node, request, sputnik) else -- Actually try to store the node local new_node = sputnik:update_node_with_params(node, request.params) new_node = sputnik:activate_node(new_node) new_node = sputnik:save_node(new_node, request, request.user, request.params.summary or "", {minor=request.params.minor}) request.redirect = sputnik:make_url(new_node.name) return end end