scala-news-reader
rss/atom news reader in scala
git clone https://9o.is/git/scala-news-reader.git
commit 160b24bfe22718a68353a93b8f771240cd14b334 parent 57948c291425200c43a0cb48b4c949b0e547f12a Author: Jul <jul@9o.is> Date: Fri, 2 Aug 2013 12:59:47 -0400 fixed many imageupload bugs Diffstat:
| M | src/main/less/styles.less | | | 5 | ++--- |
| M | src/main/scala/com/joereader/lib/ImageUpload.scala | | | 70 | ++++++++++++++++++++++++++++++++++++++++------------------------------ |
| M | src/main/scala/com/joereader/snippet/BackgroundSnip.scala | | | 73 | ++++++++++++++++++++++++++++++++++++++++++------------------------------- |
| M | src/main/scala/com/joereader/snippet/BlogSnipEdit.scala | | | 3 | ++- |
| M | src/main/scala/com/joereader/snippet/LiftExtras.scala | | | 10 | +++++----- |
| M | src/main/scala/com/joereader/snippet/UserReaderSnipEdit.scala | | | 3 | ++- |
| M | src/main/webapp/settings/account.html | | | 2 | +- |
| M | src/main/webapp/settings/blog.html | | | 2 | +- |
| M | src/main/webapp/signup/blog.html | | | 2 | +- |
| M | src/main/webapp/templates-hidden/parts/user-profile.html | | | 2 | +- |
10 files changed, 97 insertions(+), 75 deletions(-)
diff --git a/src/main/less/styles.less b/src/main/less/styles.less @@ -1084,11 +1084,10 @@ body { } - - - /* MY FIXES ----------------------------------------------------------*/ + + #bg-fileupload { margin-top: 10px; } .btn:hover, .btn:focus { color: @white; } diff --git a/src/main/scala/com/joereader/lib/ImageUpload.scala b/src/main/scala/com/joereader/lib/ImageUpload.scala @@ -16,22 +16,30 @@ import scala.concurrent.duration._ object ImageUpload extends RestHelper with Logger { + val nameLength = 32 val acceptedImages = "image/jpeg" :: "image/png" :: "image/svg+xml" :: Nil val s3 = new S3(s3_access_key.get, s3_secret_key.get, s3_bucket.get) - // string params to indicate what kind of image - val background = "bg" - val profile = "pic" - - def userUrl = - "/api/image/upload/user" + includeImgType(profile) + // indicates what kind of image + // "bg" is background and "pic" is profile picture + object ImageType extends Enumeration { + type ImageType = Value + val bg, pic = Value + } + import ImageType._ + + // avoids accidently removing files like default backgrounds + def deleteFile(fn: String) { + if(fn.length == ImageUpload.nameLength) + s3.deleteFile(fn) + } - def blogUrl(blog: Blog) = - "/api/image/upload/blog/" + blog.id.get + includeImgType(background) + def userUrl(imgType: ImageType) = + "/api/image/upload/user?type=" + imgType - def includeImgType(imgType: String) = - if (imgType.nonEmpty) "?type=" + imgType else "" + def blogUrl(blog: Blog, imgType: ImageType) = + "/api/image/upload/blog/" + blog.id.get + "?type=" + imgType // 2 MB max def imgTooLarge(req: Req) = @@ -47,9 +55,9 @@ object ImageUpload extends RestHelper with Logger { def errorCheck(req: Req, imgType: String) = { if (inValidImg(req)) (false, "Only JPEG, PNG and SVG are allowed.") - else if (imgType == background && bgTooLarge(req)) + else if (imgType == bg.toString && bgTooLarge(req)) (false, "Image is too big. Must be 5MB or smaller.") - else if (imgType == profile && imgTooLarge(req)) + else if (imgType == pic.toString && imgTooLarge(req)) (false, "Image is too big. Must be 2MB or smaller.") else if (imgType.isEmpty) (false, "Image type is missing") @@ -63,26 +71,24 @@ object ImageUpload extends RestHelper with Logger { for { user <- User.currentUser ?~ "Must be logged in" ~> 400 - imgType <- S.param("type") ?~ s"Missing image type ($background or $profile)" + imgType <- S.param("type") ?~ s"Missing image type (${bg.toString} or ${pic.toString})" file <- Box(req.uploadedFiles) ?~ "File not found" } yield { - val (valid, error) = errorCheck(req, imgType) + val (valid, err) = errorCheck(req, imgType) if (valid) { - val fn = StringHelpers.randomString(32) + val fn = StringHelpers.randomString(nameLength) val res = s3.createFile(fn, file.file, file.mimeType) map { n => val img = s3.fileUrl(fn) val id: String = - if (imgType == background) { - if (user.bgImg.get != "") - s3.deleteFile(user.bgImg.get) + if (imgType == bg.toString) { + deleteFile(user.bgImg.get) user.bgImg(fn).update imgBgId } else { - if (user.img.get != "") - s3.deleteFile(user.img.get) + deleteFile(user.img.get) user.img(fn).update imgProfileId } @@ -94,7 +100,10 @@ object ImageUpload extends RestHelper with Logger { Await.result[LiftResponse](res, 1 minute) } - else ResponseWithReason(BadResponse(), error) + else { + error(err) + ResponseWithReason(BadResponse(), err) + } } case "blog" :: id :: Nil Post req => @@ -102,26 +111,24 @@ object ImageUpload extends RestHelper with Logger { for { blog <- Blog.findByStringId(id) ?~ "Blog does not exist" ~> 400 user <- User.currentUser ?~ "Must be logged in" - imgType <- S.param("type") ?~ s"Missing image type ($background or $profile)" + imgType <- S.param("type") ?~ s"Missing image type (${bg.toString} or ${pic.toString})" file <- Box(req.uploadedFiles) ?~ "File not found" } yield { - val (valid, error) = errorCheck(req, imgType) + val (valid, err) = errorCheck(req, imgType) if (valid) { - val fn = StringHelpers.randomString(32) + val fn = StringHelpers.randomString(nameLength) val res = s3.createFile(fn, file.file, file.mimeType) map { n => val img = s3.fileUrl(fn) val id: String = - if (imgType == background) { - if (blog.bgImg.get != "") - s3.deleteFile(blog.bgImg.get) + if (imgType == bg.toString) { + deleteFile(blog.bgImg.get) blog.bgImg(fn).update imgBgId } else { - if (blog.img.get != "") - s3.deleteFile(blog.img.get) + deleteFile(blog.img.get) blog.img(fn).update imgProfileId } @@ -134,7 +141,10 @@ object ImageUpload extends RestHelper with Logger { info("Successfully saved: " + file.fileName + " for " + blog.name.get) Await.result[LiftResponse](res, 1 minute) } - else ResponseWithReason(BadResponse(), error) + else { + error(err) + ResponseWithReason(BadResponse(), err) + } } }) } diff --git a/src/main/scala/com/joereader/snippet/BackgroundSnip.scala b/src/main/scala/com/joereader/snippet/BackgroundSnip.scala @@ -12,6 +12,7 @@ import snippet.SnipHelpers._ import config._, S3Config._ import model._ import lib._ +import ImageUpload.ImageType._ /** * Handles profile backgrounds @@ -24,29 +25,40 @@ trait BackgroundSnip { "orangey", "breen-gloss", "rainbow-landscape", - "water-wave" - ) + "water-wave") def listBackgrounds(currentDefault: String, bwu: BlogWriterUser) = ajaxRadio[String]( - backgrounds, - backgrounds.find(_ == currentDefault), - { - s => - bwu.user.map(_.bgImg(s).update) - bwu.blog.map(_.bgImg(s).update) - UpdateImage(imgBgId, S3Config.s3.fileUrl(s)) - } - ).backgroundChoices + backgrounds, + backgrounds.find(_ == currentDefault), + { + s => + for { + user <- bwu.user + u <- User.find(user.id.get) + } { + ImageUpload.deleteFile(u.bgImg.get) + u.bgImg(s).update + } + + for { + blog <- bwu.blog + b <- Blog.find(blog.id.get) + } { + ImageUpload.deleteFile(b.bgImg.get) + b.bgImg(s).update + } + + UpdateImage(imgBgId, s3.fileUrl(s)) + }).backgroundChoices def radios = ajaxRadio[Boolean]( - Seq(true, false), - Full(true), - { - bool => - if(bool) Show("backgrounds-list") & Hide("bg-fileupload") - else Show("bg-fileupload") & Hide("backgrounds-list") - } - ) + Seq(true, false), + Full(true), + { + bool => + if (bool) Show("backgrounds-list") & Hide("bg-fileupload-container") + else Show("bg-fileupload-container") & Hide("backgrounds-list") + }) def defaultBackground: String = s3.fileUrl(backgrounds.head) @@ -62,33 +74,32 @@ trait BackgroundSnip { val radios = this.radios - "#bg-fileupload *" #> - insertFileUpload(ImageUpload.background, ImageUpload.userUrl) & - "#backgrounds-list *" #> + "#bg-fileupload-container *" #> + insertFileUpload(bg, ImageUpload.userUrl(bg)) & + "#backgrounds-list *" #> listBackgrounds(user.bgImg.get, BlogWriterUser(Some(user))) & - "#backgrounds-q-yes" #> radios(0) & - "#backgrounds-q-no" #> radios(1) + "#backgrounds-q-yes" #> radios(0) & + "#backgrounds-q-no" #> radios(1) } def uploadBgImg(blog: Blog): CssSel = { val radios = this.radios - "#bg-fileupload *" #> - insertFileUpload(ImageUpload.background, ImageUpload.blogUrl(blog)) & - "#backgrounds-list *" #> + "#bg-fileupload-container *" #> + insertFileUpload(bg, ImageUpload.blogUrl(blog, bg)) & + "#backgrounds-list *" #> listBackgrounds(blog.bgImg.get, BlogWriterUser(None, Some(blog))) & - "#backgrounds-q-yes" #> radios(0) & - "#backgrounds-q-no" #> radios(1) + "#backgrounds-q-yes" #> radios(0) & + "#backgrounds-q-no" #> radios(1) } - implicit class BackgroundsRadioDesign2Implicit(choices: ChoiceHolder[String]) { def backgroundChoices: NodeSeq = { for (i <- 0 until choices.items.size) yield { val bg = backgrounds(i) val item = choices.items(i) - <label>{item.xhtml}<img src={S3Config.s3.fileUrl(bg)}/></label> + <label>{ item.xhtml }<img src={ s3.fileUrl(bg) }/></label> } } } diff --git a/src/main/scala/com/joereader/snippet/BlogSnipEdit.scala b/src/main/scala/com/joereader/snippet/BlogSnipEdit.scala @@ -9,6 +9,7 @@ import com.joereader._ import model._ import config._ import lib._ +import ImageUpload.ImageType._ import snippet.SnipHelpers._ import scala.xml._ @@ -40,7 +41,7 @@ trait BlogSnipEdit extends BlogSnipView with BackgroundSnip { def uploadImg(html: NodeSeq) = serve(html) { blog => - "*" #> insertFileUpload(ImageUpload.profile, ImageUpload.blogUrl(blog)) + "*" #> insertFileUpload(pic, ImageUpload.blogUrl(blog, pic)) }(test, NodeSeq.Empty) def uploadBgImg(html: NodeSeq): NodeSeq = serve(html) { diff --git a/src/main/scala/com/joereader/snippet/LiftExtras.scala b/src/main/scala/com/joereader/snippet/LiftExtras.scala @@ -6,7 +6,7 @@ import http.js._ import com.joereader.model._ import com.joereader.config._, S3Config._ -import com.joereader.lib._ +import com.joereader.lib._, ImageUpload.ImageType._ import net.liftmodules.extras._, snippet._ import scala.xml._ @@ -49,11 +49,11 @@ object SnipHelpers { else s3.fileUrl("mr_noblog_color") - def insertFileUpload(id: String, path: String): NodeSeq = { - <input id={id + "-fileupload"} type="file" name="files2[]" data-url={ + def insertFileUpload(id: ImageType, path: String): NodeSeq = { + <input id={id.toString + "-fileupload"} type="file" name="files2[]" data-url={ path} accept={ImageUpload.acceptedImages.mkString(",")}/> - <div id={id + "-progress"} style="width:20em; border: 1pt solid silver; display: none; margin: 10px 0"> - <div id={id + "-progress-bar"} style="background: green; height: 1em; width:0%"></div> + <div id={id.toString + "-progress"} style="width:20em; border: 1pt solid silver; display: none; margin: 10px 0"> + <div id={id.toString + "-progress-bar"} style="background: green; height: 1em; width:0%"></div> </div> } diff --git a/src/main/scala/com/joereader/snippet/UserReaderSnipEdit.scala b/src/main/scala/com/joereader/snippet/UserReaderSnipEdit.scala @@ -3,6 +3,7 @@ package com.joereader.snippet import com.joereader._ import model._ import lib._, Helper._ +import ImageUpload.ImageType._ import config._ import SnipHelpers._ @@ -83,7 +84,7 @@ trait UserReaderSnipEdit extends UserReaderSnipView with UserPassword { def uploadImg(html: NodeSeq) = serve(html) { user => - "*" #> insertFileUpload(ImageUpload.profile, ImageUpload.userUrl) + "*" #> insertFileUpload(pic, ImageUpload.userUrl(pic)) }(test, NodeSeq.Empty) /* diff --git a/src/main/webapp/settings/account.html b/src/main/webapp/settings/account.html @@ -50,7 +50,7 @@ <input id="backgrounds-q-no" class="radio" style="margin-left: 20px" /> <span>No</span> </div> - <div id="bg-fileupload" class="hide"></div> + <div id="bg-fileupload-container" class="hide"></div> <div id="backgrounds-list"></div> </div> </div> diff --git a/src/main/webapp/settings/blog.html b/src/main/webapp/settings/blog.html @@ -32,7 +32,7 @@ <input id="backgrounds-q-no" class="radio" style="margin-left: 20px" /> <span>No</span> </div> - <div id="bg-fileupload" class="hide"></div> + <div id="bg-fileupload-container" class="hide"></div> <div id="backgrounds-list"></div> </div> diff --git a/src/main/webapp/signup/blog.html b/src/main/webapp/signup/blog.html @@ -57,7 +57,7 @@ <input id="backgrounds-q-no" class="radio" style="margin-left: 20px" /> <span>No</span> </div> - <div id="bg-fileupload" class="hide"></div> + <div id="bg-fileupload-container" class="hide"></div> <div id="backgrounds-list"></div> </div> diff --git a/src/main/webapp/templates-hidden/parts/user-profile.html b/src/main/webapp/templates-hidden/parts/user-profile.html @@ -145,7 +145,7 @@ <input id="backgrounds-q-no" class="radio" style="margin-left: 20px" /> <span>No</span> </div> - <div id="bg-fileupload" class="hide"></div> + <div id="bg-fileupload-container" class="hide"></div> <div id="backgrounds-list"></div> </div> <hr>