upload ublog images towards picfit (yay!)
parent
1fc9315ad3
commit
266f03945b
|
@ -8,7 +8,7 @@ import lila.ublog.UblogPost
|
|||
|
||||
final class Ublog(env: Env) extends LilaController(env) {
|
||||
|
||||
import views.html.ublog.post.urlOf
|
||||
import views.html.ublog.post.{ editUrlOf, urlOf }
|
||||
|
||||
def index(username: String, page: Int) = Open { implicit ctx =>
|
||||
OptionFuOk(env.user.repo named username) { user =>
|
||||
|
@ -80,43 +80,17 @@ final class Ublog(env: Env) extends LilaController(env) {
|
|||
}
|
||||
}
|
||||
|
||||
// private val handleFilePartAsFile: play.core.parsers.Multipart.FilePartHandler[java.io.File] = {
|
||||
// case Multipart.FileInfo(partName, filename, contentType, dispositionType) =>
|
||||
// val perms = java.util.EnumSet.of(OWNER_READ, OWNER_WRITE)
|
||||
// val attr = PosixFilePermissions.asFileAttribute(perms)
|
||||
// val path = JFiles.createTempFile("multipartBody", "tempFile", attr)
|
||||
// val file = path.toFile
|
||||
// val fileSink = FileIO.toPath(path)
|
||||
// val accumulator = Accumulator(fileSink)
|
||||
// accumulator.map { case IOResult(count, status) =>
|
||||
// FilePart(partName, filename, contentType, file, count, dispositionType)
|
||||
// }(ec)
|
||||
// }
|
||||
import play.api.mvc.BodyParser
|
||||
import akka.stream.scaladsl.Source
|
||||
import akka.util.ByteString
|
||||
import play.api.libs.streams.Accumulator
|
||||
def verbatimBodyParser: BodyParser[Source[ByteString, _]] = BodyParser { _ =>
|
||||
// Return the source directly. We need to return
|
||||
// an Accumulator[Either[Result, T]], so if we were
|
||||
// handling any errors we could map to something like
|
||||
// a Left(BadRequest("error")). Since we're not
|
||||
// we just wrap the source in a Right(...)
|
||||
Accumulator.source[ByteString].map(Right.apply)
|
||||
}
|
||||
|
||||
def image(unusedUsername: String, id: String) =
|
||||
AuthBody(parse.multipartFormData(handleFilePartAsFile)) { implicit ctx => me =>
|
||||
AuthBody(parse.multipartFormData) { implicit ctx => me =>
|
||||
env.ublog.api.findByAuthor(UblogPost.Id(id), me) flatMap {
|
||||
_ ?? { post =>
|
||||
ctx.body.body.file("image") match {
|
||||
case FilePart(key, filename, contentType, file, fileSize, dispositionType) =>
|
||||
case Some(image) =>
|
||||
env.ublog.api.uploadImage(post, image) recover { case e: Exception =>
|
||||
BadRequest(html.ublog.form.edit(me, post, env.ublog.form.edit(post)))
|
||||
.flashFailure(e.getMessage)
|
||||
} inject Redirect(routes.Streamer.edit)
|
||||
case None => fuccess(Redirect(routes.Streamer.edit))
|
||||
} inject Redirect(editUrlOf(post))
|
||||
case None => fuccess(Redirect(editUrlOf(post)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ import lila.user.User
|
|||
|
||||
object form {
|
||||
|
||||
import views.html.ublog.{ post => postView }
|
||||
|
||||
def create(user: User, f: Form[UblogPostData])(implicit ctx: Context) =
|
||||
views.html.base.layout(
|
||||
moreCss = frag(cssTag("ublog")),
|
||||
|
@ -33,10 +35,29 @@ object form {
|
|||
div(cls := "ublog-post-form__publish")(
|
||||
p(if (post.live) "This post is published" else "This is a draft")
|
||||
),
|
||||
imageForm(user, post),
|
||||
inner(user, f, post.some)
|
||||
)
|
||||
}
|
||||
|
||||
private def imageForm(user: User, post: UblogPost)(implicit ctx: Context) =
|
||||
postForm(
|
||||
cls := "ublog-post-form__image",
|
||||
action := routes.Ublog.image(user.username, post.id.value),
|
||||
enctype := "multipart/form-data"
|
||||
)(
|
||||
form3.split(
|
||||
div(cls := "form-group form-half")(
|
||||
postView.imageOf(post)
|
||||
),
|
||||
div(cls := "form-group form-half")(
|
||||
p(trans.streamer.maxSize(s"${lila.memo.PicfitApi.uploadMaxMb}MB.")),
|
||||
form3.file.image("image"),
|
||||
submitButton(cls := "button")(trans.streamer.uploadPicture())
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
private def inner(user: User, form: Form[UblogPostData], post: Option[UblogPost])(implicit
|
||||
ctx: Context
|
||||
) =
|
||||
|
|
|
@ -57,4 +57,24 @@ object post {
|
|||
def urlOf(post: UblogPost) = routes.Ublog.post(usernameOrId(post.user), post.slug, post.id.value)
|
||||
|
||||
def editUrlOf(post: UblogPost) = routes.Ublog.edit(usernameOrId(post.user), post.id.value)
|
||||
|
||||
def imageOf(post: UblogPost, size: Int = 300) =
|
||||
post.image match {
|
||||
// case Some(image) =>
|
||||
// img(
|
||||
// width := size,
|
||||
// height := size,
|
||||
// cls := "picture",
|
||||
// src := dbImageUrl(path.value),
|
||||
// alt := s"${u.titleUsername} Lichess streamer picture"
|
||||
// )
|
||||
case _ =>
|
||||
img(
|
||||
width := size,
|
||||
height := size,
|
||||
cls := "default image",
|
||||
src := assetUrl("images/placeholder.png"),
|
||||
alt := "Default blog post image"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -387,7 +387,7 @@ memo {
|
|||
}
|
||||
picfit {
|
||||
collection = picfit_image
|
||||
endpoint = "127.0.0.1:3001"
|
||||
endpoint = "http://127.0.0.1:3001"
|
||||
}
|
||||
}
|
||||
redis {
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package lila.memo
|
||||
|
||||
import java.nio.file.Path
|
||||
import akka.stream.scaladsl.{ FileIO, Source }
|
||||
import akka.util.ByteString
|
||||
import org.joda.time.DateTime
|
||||
import play.api.libs.ws.StandaloneWSClient
|
||||
import play.api.mvc.MultipartFormData
|
||||
import reactivemongo.api.bson.Macros
|
||||
import scala.concurrent.ExecutionContext
|
||||
import play.api.libs.ws.StandaloneWSClient
|
||||
|
||||
import lila.db.dsl._
|
||||
|
||||
|
@ -38,8 +40,9 @@ final class PicfitApi(coll: Coll, ws: StandaloneWSClient, endpoint: String)(impl
|
|||
if (uploaded.fileSize > uploadMaxBytes)
|
||||
fufail(s"File size must not exceed ${uploadMaxMb}MB.")
|
||||
else {
|
||||
import WSBodyWritables._
|
||||
val image = PicfitImage(
|
||||
_id = PicfitImage.Id(lila.common.ThreadLocalRandom nextString 8),
|
||||
_id = PicfitImage.Id(lila.common.ThreadLocalRandom nextString 10),
|
||||
user = userId,
|
||||
scope = scope,
|
||||
name = sanitizeName(uploaded.filename),
|
||||
|
@ -47,23 +50,20 @@ final class PicfitApi(coll: Coll, ws: StandaloneWSClient, endpoint: String)(impl
|
|||
size = uploaded.fileSize.toInt,
|
||||
createdAt = DateTime.now
|
||||
)
|
||||
// ws.url(s"$endpoint/upload")
|
||||
// .post(
|
||||
// Source(
|
||||
// FilePart(
|
||||
// "File",
|
||||
// fileName,
|
||||
// Option("application/pdf"),
|
||||
// FileIO.fromPath(Paths.get(pathToFile))
|
||||
// ) :: List()
|
||||
// )
|
||||
// )
|
||||
// .post(body(source)) flatMap {
|
||||
// case res if res.status != 200 =>
|
||||
// fufail(res.statusText)
|
||||
// case res => funit
|
||||
// } >>
|
||||
coll.insert.one(image) inject image
|
||||
type Part = MultipartFormData.FilePart[Source[ByteString, _]]
|
||||
val part: Part = MultipartFormData.FilePart(
|
||||
key = "data",
|
||||
filename = image.id.value,
|
||||
contentType = uploaded.contentType,
|
||||
ref = FileIO.fromPath(uploaded.ref.path),
|
||||
fileSize = uploaded.fileSize
|
||||
)
|
||||
val source: Source[Part, _] = Source(part :: List())
|
||||
ws.url(s"$endpoint/upload").post(source).flatMap {
|
||||
case res if res.status != 200 => fufail(res.statusText)
|
||||
case _ => funit
|
||||
} >>
|
||||
coll.insert.one(image) inject image
|
||||
}
|
||||
|
||||
private def sanitizeName(name: String) = {
|
||||
|
@ -77,4 +77,17 @@ object PicfitApi {
|
|||
val uploadMaxMb = 4
|
||||
|
||||
type Uploaded = play.api.mvc.MultipartFormData.FilePart[play.api.libs.Files.TemporaryFile]
|
||||
|
||||
// from playframework/transport/client/play-ws/src/main/scala/play/api/libs/ws/WSBodyWritables.scala
|
||||
object WSBodyWritables {
|
||||
import play.api.libs.ws.BodyWritable
|
||||
import play.api.libs.ws.SourceBody
|
||||
import play.core.formatters.Multipart
|
||||
implicit val bodyWritableOf_Multipart
|
||||
: BodyWritable[Source[MultipartFormData.Part[Source[ByteString, _]], _]] = {
|
||||
val boundary = Multipart.randomBoundary()
|
||||
val contentType = s"multipart/form-data; boundary=$boundary"
|
||||
BodyWritable(b => SourceBody(Multipart.transform(b, boundary)), contentType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
@import '../../../common/css/plugin';
|
||||
@import '../../../common/css/form/form3';
|
||||
@import '../ublog/ublog';
|
||||
@import '../ublog/form';
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
.ublog-post-form {
|
||||
&__publish {
|
||||
margin: 3vh 0;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue