Skip to content

Instantly share code, notes, and snippets.

@alari
Created September 17, 2013 17:09
Show Gist options
  • Save alari/6597372 to your computer and use it in GitHub Desktop.
Save alari/6597372 to your computer and use it in GitHub Desktop.
A FileStorage object using ReactiveMongo and not available to test
package content
import play.api.mvc.MultipartFormData
import play.api.libs.Files
import play.modules.reactivemongo.ReactiveMongoPlugin
import reactivemongo.api.gridfs.GridFS
import user.ProfileId
import scala.concurrent.Future
import reactivemongo.bson._
import java.io.{InputStream, FileInputStream}
import scala.concurrent.ExecutionContext
import ExecutionContext.Implicits.global
import reactivemongo.api.indexes.IndexType
import reactivemongo.core.commands._
import play.api.Play.current
import util.controller.ProfileIdAwareRequest
import reactivemongo.core.commands.Match
import reactivemongo.bson.BSONInteger
import reactivemongo.api.gridfs.DefaultFileToSave
import reactivemongo.api.indexes.Index
import play.modules.reactivemongo.json.collection.JSONCollection
import reactivemongo.core.commands.SumField
import reactivemongo.core.commands.GroupField
import scala.Some
import reactivemongo.bson.BSONString
/**
* @author alari (name.alari@gmail.com)
* @since 11.09.13 21:52
*/
object FileStorage {
type F = MultipartFormData.FilePart[Files.TemporaryFile]
lazy val db = ReactiveMongoPlugin.db
val gridFS = GridFS(db, "file")
val collection = db.collection[JSONCollection]("file.files")
collection.indexesManager.ensure(Index(Seq("metadata.profileId" -> IndexType.Ascending)))
implicit val reader = reactivemongo.api.gridfs.Implicits.DefaultReadFileReader
// TODO: make real
def canUpload(implicit request: ProfileIdAwareRequest) = request.profileIdOpt match {
case Some(pid) =>
FileStorage.getFilesSize(pid).map(println)
true
case None => false
}
def store(file: F, profileId: ProfileId): Future[String] =
store(new FileInputStream(file.ref.file), file.filename, file.contentType, profileId)
def store(stream: InputStream, filename: String, contentType: Option[String], profileId: ProfileId): Future[String] = {
val newId = BSONObjectID.generate
val metadata = BSONDocument("profileId" -> profileId.id)
val saveFile = DefaultFileToSave(filename, contentType, metadata = metadata, id = newId)
gridFS.writeFromInputStream(saveFile, stream).map {
readFile =>
newId.stringify
}
}
def getFilesSize(profileId: ProfileId): Future[Option[Long]] = {
db.command(Aggregate("file.files", Seq(
Match(BSONDocument("metadata.profileId" -> BSONString(profileId.stringId))),
GroupField("metadata.profileId")("total" -> SumField("length"))
))).map {
stream =>
stream.head.get("total").map {
case i: BSONInteger => i.value
case l: BSONLong => l.value
case _ => 0
}
}
}
def remove(fileId: String) = gridFS.remove(BSONObjectID(fileId))
def find(fileId: String) = gridFS.find(BSONDocument("_id" -> BSONObjectID(fileId)))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment