1 package net.pterodactylus.sone.web.pages
3 import freenet.support.api.Bucket
4 import net.pterodactylus.sone.data.Sone
5 import net.pterodactylus.sone.main.*
6 import net.pterodactylus.sone.text.TextFilter
7 import net.pterodactylus.sone.utils.emptyToNull
8 import net.pterodactylus.sone.utils.headers
9 import net.pterodactylus.sone.utils.isPOST
10 import net.pterodactylus.sone.utils.parameters
11 import net.pterodactylus.sone.utils.use
12 import net.pterodactylus.sone.web.WebInterface
13 import net.pterodactylus.sone.web.page.*
14 import net.pterodactylus.util.template.Template
15 import net.pterodactylus.util.template.TemplateContext
16 import java.awt.image.BufferedImage
17 import java.io.ByteArrayInputStream
18 import java.io.ByteArrayOutputStream
19 import javax.imageio.ImageIO
20 import javax.inject.Inject
23 * Page implementation that lets the user upload an image.
25 @TemplatePath("/templates/invalid.html")
26 class UploadImagePage @Inject constructor(template: Template, webInterface: WebInterface, loaders: Loaders, templateRenderer: TemplateRenderer):
27 LoggedInPage("uploadImage.html", template, "Page.UploadImage.Title", webInterface, loaders, templateRenderer) {
29 override fun handleRequest(soneRequest: SoneRequest, currentSone: Sone, templateContext: TemplateContext) {
30 if (soneRequest.isPOST) {
31 val parentAlbum = soneRequest.parameters["parent"]!!.let(soneRequest.core::getAlbum) ?: throw RedirectException("noPermission.html")
32 if (parentAlbum.sone != currentSone) {
33 throw RedirectException("noPermission.html")
35 val title = soneRequest.parameters["title", 200].emptyToNull ?: throw RedirectException("emptyImageTitle.html")
37 val uploadedFile = soneRequest.httpRequest.getUploadedFile("image")
38 val bytes = uploadedFile.data.use { it.toByteArray() }
39 val bufferedImage = bytes.toImage()
40 if (bufferedImage == null) {
41 templateContext["messages"] = soneRequest.l10n.getString("Page.UploadImage.Error.InvalidImage")
45 val temporaryImage = soneRequest.core.createTemporaryImage(bytes.mimeType, bytes)
46 soneRequest.core.createImage(currentSone, parentAlbum, temporaryImage).modify().apply {
47 setWidth(bufferedImage.width)
48 setHeight(bufferedImage.height)
50 setDescription(TextFilter.filter(soneRequest.headers["Host"], soneRequest.parameters["description", 4000]))
52 throw RedirectException("imageBrowser.html?album=${parentAlbum.id}")
56 private fun Bucket.toByteArray(): ByteArray = ByteArrayOutputStream(size().toInt()).use { outputStream ->
57 inputStream.copyTo(outputStream)
58 outputStream.toByteArray()
61 private fun ByteArray.toImage(): BufferedImage? = ByteArrayInputStream(this).use {
65 private val ByteArray.mimeType get() = ByteArrayInputStream(this).use {
66 ImageIO.createImageInputStream(it).use {
67 ImageIO.getImageReaders(it).asSequence()
68 .firstOrNull()?.originatingProvider?.mimeTypes?.firstOrNull()
75 private const val UNKNOWN_MIME_TYPE = "application/octet-stream"