Skip to content

Instantly share code, notes, and snippets.

@adamretter
Created September 26, 2015 14:58
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save adamretter/f6d1b7bdb4b694c0c6b5 to your computer and use it in GitHub Desktop.
extract file from multipart-form-data
def storeUploadedFile(data: Source[ByteString, Any]): \/[Seq[Throwable], Future[DefaultPath]] = {
val tmpUpload = Path.createTempFile(prefix = "uploaded", dir = settings.TempDir, deleteOnExit = true)
try {
val os = new FileOutputStream(tmpUpload.jfile)
val sink = OutputStreamSink(() => os)
val f = data.runWith(sink).map(_ => tmpUpload)
f.onComplete { _ =>
info(s"Stored temporary uploaded PDF ${tmpUpload.path}")
os.close
}
f.right
} catch {
case e: IOException =>
Seq(e).left
}
//TODO(AR) delete the temp file after we process it and have a new file
}
entity(as[Multipart.FormData]).flatMap { (formdata: Multipart.FormData) =>
val extractedParts = formdata.parts.mapAsync(Runtime.getRuntime.availableProcessors) { part =>
val reqParamValue = part.filename match {
case Some(filename) =>
storeUploadedFile(part.entity.dataBytes) match {
case \/-(tmpPath) =>
tmpPath.map(ReqParamFileValue(filename, part.entity.contentType, _))
case -\/(throwables) =>
//TODO(AR) log all errors
throw throwables.head
}
case None =>
part.entity.dataBytes
.runFold("")((a,b) => a + b.decodeString(StandardCharsets.UTF_8.name))
.map(ReqParamStringValue(_))
}
reqParamValue.map(ReqParam(part.name, _))
}.runFold(Map.empty[String, ReqParam])((m, b) => m + (b.name -> b))
val futureMaybeStampPdfRequest: Future[\/[Rejection, StampPdfRequest]] = extractedParts.map(parts =>
for {
pdfStamp <- extractPdfStamp(parts)
pdf <- extractFile(parts, "pdf")
coverPage <- extractCoverPageOpt(parts)
} yield StampPdfRequest(pdfStamp, coverPage, pdf)
)
Await.result(
futureMaybeStampPdfRequest.map {
case -\/(rejection) =>
reject(rejection)
case \/-(stampPdfRequest) =>
provide(stampPdfRequest)
},
5 minutes //TODO(AR) make configurable
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment