This repository was archived by the owner on Apr 23, 2019. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathHomeController.scala
More file actions
93 lines (79 loc) · 2.63 KB
/
HomeController.scala
File metadata and controls
93 lines (79 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package controllers
import java.io.File
import java.nio.file.{Files, Path}
import javax.inject._
import akka.stream.IOResult
import akka.stream.scaladsl._
import akka.util.ByteString
import play.api._
import play.api.data.Form
import play.api.data.Forms._
import play.api.libs.streams._
import play.api.mvc.MultipartFormData.FilePart
import play.api.mvc._
import play.core.parsers.Multipart.FileInfo
import scala.concurrent.{ExecutionContext, Future}
case class FormData(name: String)
/**
* This controller handles a file upload.
*/
@Singleton
class HomeController @Inject() (cc:MessagesControllerComponents)
(implicit executionContext: ExecutionContext)
extends MessagesAbstractController(cc) {
private val logger = Logger(this.getClass)
val form = Form(
mapping(
"name" -> text
)(FormData.apply)(FormData.unapply)
)
/**
* Renders a start page.
*/
def index = Action { implicit request =>
Ok(views.html.index(form))
}
type FilePartHandler[A] = FileInfo => Accumulator[ByteString, FilePart[A]]
/**
* Uses a custom FilePartHandler to return a type of "File" rather than
* using Play's TemporaryFile class. Deletion must happen explicitly on
* completion, rather than TemporaryFile (which uses finalization to
* delete temporary files).
*
* @return
*/
private def handleFilePartAsFile: FilePartHandler[File] = {
case FileInfo(partName, filename, contentType) =>
val path: Path = Files.createTempFile("multipartBody", "tempFile")
val fileSink: Sink[ByteString, Future[IOResult]] = FileIO.toPath(path)
val accumulator: Accumulator[ByteString, IOResult] = Accumulator(fileSink)
accumulator.map {
case IOResult(count, status) =>
logger.info(s"count = $count, status = $status")
FilePart(partName, filename, contentType, path.toFile)
}
}
/**
* A generic operation on the temporary file that deletes the temp file after completion.
*/
private def operateOnTempFile(file: File) = {
val size = Files.size(file.toPath)
logger.info(s"size = ${size}")
Files.deleteIfExists(file.toPath)
size
}
/**
* Uploads a multipart file as a POST request.
*
* @return
*/
def upload = Action(parse.multipartFormData(handleFilePartAsFile)) { implicit request =>
val fileOption = request.body.file("name").map {
case FilePart(key, filename, contentType, file) =>
logger.info(s"key = ${key}, filename = ${filename}, contentType = ${contentType}, file = $file")
val data = operateOnTempFile(file)
data
}
Ok(s"file size = ${fileOption.getOrElse("no file")}")
}
}