Skip to content

Instantly share code, notes, and snippets.

@alari
Created September 13, 2013 08:20
Show Gist options
  • Save alari/6548013 to your computer and use it in GitHub Desktop.
Save alari/6548013 to your computer and use it in GitHub Desktop.
FileStorage class to move gridFS from ReactiveMongo to service layer
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.{BSONDocument, BSONObjectID}
import java.io.{InputStream, FileInputStream}
import scala.concurrent.ExecutionContext
import ExecutionContext.Implicits.global
import reactivemongo.api.indexes.IndexType
import reactivemongo.core.commands._
import reactivemongo.core.commands.Match
import reactivemongo.api.gridfs.DefaultFileToSave
import reactivemongo.api.indexes.Index
import play.modules.reactivemongo.json.collection.JSONCollection
import reactivemongo.core.commands.GroupField
import reactivemongo.bson.BSONString
import play.api.Play.current
/**
* @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
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
}
}
// TODO: make it work!
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.headOption.map(_.getAs[Long]("total")).getOrElse(None)
}
}
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