missing parameter type on file upload with silhouette - scala

now implement file-uploading with silhouette.
got from the original
https://github.com/playframework/play-scala-fileupload-example/tree/2.5.x
silhouette
https://github.com/mohiva/play-silhouette-seed/tree/4.0.0/app
i want to fix def upload method with silhouette to indicate identity(user name) in fileUpload2.scala.html , so added following line;
silhouette.SecuredAction.async { implicit request =>
Future.successful(Ok(views.html.fileUpload2(request.identity,fileOption)))
}
refered to this link;
http://grokbase.com/p/gg/play-framework/133pt061br/2-1-0-scala-action-question
but not work well.
(FileUploadController.scala)
package controllers
import java.io.File
import java.nio.file.attribute.PosixFilePermission._
import java.nio.file.attribute.PosixFilePermissions
import java.nio.file.{ Files, Path }
import java.util
import javax.inject._
import com.mohiva.play.silhouette.api._
import com.mohiva.play.silhouette.api.repositories.AuthInfoRepository
import com.mohiva.play.silhouette.api.services.AvatarService
import com.mohiva.play.silhouette.api.util.PasswordHasherRegistry
import com.mohiva.play.silhouette.impl.providers._
import com.mohiva.play.silhouette.api.Authenticator.Implicits._
import com.mohiva.play.silhouette.api.util.{ Clock, Credentials }
import com.mohiva.play.silhouette.api.actions.SecuredRequest
import utils.auth.{ DefaultEnv, WithProvider }
import forms.{ FileUploadForm, FileUploadFormSupport }
import models.User
import models.services.{ AuthTokenService, UserService }
import net.ceedubs.ficus.Ficus._
import akka.stream.IOResult
import akka.stream.scaladsl._
import akka.util.ByteString
import play.api._
import play.api.data.Form
import play.api.data.Forms._
import play.api.i18n.{ I18nSupport, Messages, MessagesApi }
import play.api.libs.streams._
import play.api.libs.concurrent.Execution.Implicits._
import play.api.libs.mailer.{ Email, MailerClient }
import play.api.mvc.MultipartFormData.FilePart
import play.api.mvc._
import play.core.parsers.Multipart.FileInfo
import scala.concurrent.{ ExecutionContext, Future }
import scala.concurrent.duration._
import scala.language.postfixOps
class FileUploadController #Inject() (
val messagesApi: MessagesApi,
silhouette: Silhouette[DefaultEnv],
userService: UserService,
authInfoRepository: AuthInfoRepository,
authTokenService: AuthTokenService,
avatarService: AvatarService,
passwordHasherRegistry: PasswordHasherRegistry,
mailerClient: MailerClient,
implicit val webJarAssets: WebJarAssets,
socialProviderRegistry: SocialProviderRegistry,
ec: ExecutionContext,
credentialsProvider: CredentialsProvider
)
extends Controller with i18n.I18nSupport {
private val logger = org.slf4j.LoggerFactory.getLogger(this.getClass)
def fileuploadview = silhouette.SecuredAction.async { implicit request =>
Future.successful(Ok(views.html.fileUpload(request.identity, FileUploadForm.form)))
}
type FilePartHandler[A] = FileInfo => Accumulator[ByteString, FilePart[A]]
def handleFilePartAsFile: FilePartHandler[File] = {
case FileInfo(partName, filename, contentType) =>
val attr = PosixFilePermissions.asFileAttribute(util.EnumSet.of(OWNER_READ, OWNER_WRITE))
val path: Path = Files.createTempFile("multipartBody", "tempFile", attr)
val file = path.toFile
val fileSink: Sink[ByteString, Future[IOResult]] = FileIO.toPath(path)
val accumulator: Accumulator[ByteString, IOResult] = Accumulator(fileSink)
accumulator.map {
case IOResult(count, status) =>
logger.info(s"count = $count, status = $status")
FilePart(partName, filename, contentType, file)
}
}
def operateOnTempFile(file: File) = {
val size = Files.size(file.toPath)
logger.info(s"size = ${size}")
Files.deleteIfExists(file.toPath)
size
}
def upload = Action(parse.multipartFormData(handleFilePartAsFile)) { implicit request =>
val fileOption = request.body.file("picName").map {
case FilePart(key, filename, contentType, file) =>
logger.info(s"key = ${key}, filename = ${filename}, contentType = ${contentType}, file = $file")
val data = operateOnTempFile(file)
data
}
FileUploadFormSupport.picsave(_)
silhouette.SecuredAction.async { implicit request =>
Future.successful(Ok(views.html.fileUpload2(request.identity,fileOption)))
}
}
}
the problem is the last lines;
silhouette.SecuredAction.async { implicit request =>
Future.successful(Ok(views.html.fileUpload2(request.identity,fileOption)))
compile error;
missing parameter type
occured.

You use the Silhouette action at the wrong place. You should write:
def upload = silhouette.SecuredAction.async(parse.multipartFormData(handleFilePartAsFile)) {
implicit request =>
// Your upload code
}
A Silhouette action is a default Play action with the advantage that the request type is extended with the identity and the authenticator.

Related

Cannot cast scala.concurrent.impl.Promise$Transformation to scala.collection.immutable.Seq erro in akka http using mongodb?

Basically I trying to get data from database using akka http. if i pass (EmployeeRepo.findAll()) directly in api then it show all data but while using actor it shows cast error....
here problem for data fetching only please solve it
this is my EmployeeRepo-----------------------------------
package org.repo
import org.data.Employee
import org.db.DbConfig
import org.mongodb.scala.MongoCollection
import org.utils.JsonUtils
import org.mongodb.scala.bson.conversions.Bson
import org.mongodb.scala.model.Filters.equal
import org.mongodb.scala.model.FindOneAndUpdateOptions
import org.mongodb.scala.model.Updates.{combine, set}
import scala.concurrent.Future
object EmployeeRepo extends JsonUtils{
private val employeeDoc:MongoCollection[Employee]=DbConfig.employees
def createCollection()={
DbConfig.database.createCollection("employee").subscribe(
(result)=>println(s"$result"),
e=>println(e.getLocalizedMessage),
()=>println("complete")
)
}
def insertData(emp:Employee)={
employeeDoc.insertOne(emp).toFuture()
}
def findAll()= employeeDoc.find().toFuture()
def update(emp:Employee,id:String)=
employeeDoc
.findOneAndUpdate(equal("_id", id),
setBsonValue(emp),
FindOneAndUpdateOptions().upsert(true)).toFuture()
def delete(id:String)=
employeeDoc.deleteOne(equal("_id",id)).toFuture()
private def setBsonValue(emp:Employee)={
combine(
set("name",emp.name),
set("dateOfBirth",emp.dateOfBirth)
)
}
}
============EMployeeService------------
package org.service
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.UUID
import akka.NotUsed
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.Source
import org.data.Employee
import org.domain.EmployeeRequest
import org.repo.EmployeeRepo
import scala.concurrent.Future
class EmployeeService {
implicit val system=ActorSystem("Employeee")
implicit val materializer=ActorMaterializer
import system.dispatcher
def saveEmployeeData= (employeeRequest:EmployeeRequest) => {
val employeeDoc:Employee=employeeMapperWithNewId(employeeRequest)
EmployeeRepo.insertData(employeeDoc)
}
def findAll={
EmployeeRepo.findAll()
}
def update(employeeRequest: EmployeeRequest,id:String)={
val employeeDoc=employeeMapperWithNewId(employeeRequest)
EmployeeRepo.update(emp = employeeDoc,id)
}
def delete(id:String)=EmployeeRepo.delete(id)
private def employeeMapperWithNewId(employee:EmployeeRequest)={
Employee(name=employee.name,dateOfBirth = LocalDate.parse(employee.dateOfBirth, DateTimeFormatter.ISO_DATE),
_id=UUID.randomUUID.toString)
}
}
-----------------EmployeeActor------
package org.actor
import akka.actor.{Actor, ActorLogging}
import org.actor.EmployeeActor.{Delete, Save, SearchAll, Update}
import org.data.Employee
import org.domain.EmployeeRequest
import org.service.EmployeeService
object EmployeeActor {
case class Save(emp: EmployeeRequest)
case object SearchAll
case class Update(emp: EmployeeRequest, id: String)
case class Delete(id: String)
}
class
EmployeeActor extends Actor with ActorLogging {
private val employeeService: EmployeeService = new EmployeeService()
override def receive: Receive = {
case Save(emp) =>
log.info(s"recevied msg saved with employee :$emp")
sender() ! employeeService.saveEmployeeData(emp)
case SearchAll =>
log.info("received msg find ALL")
sender() ! employeeService.findAll
case Update(emp, id) =>
log.info(s"received update msg for id $id and employee $emp")
sender() ! employeeService.update(emp, id)
case Delete(id) =>
log.info(s"received msg for deleting employee of id $id")
sender() ! employeeService.delete(id)
case _ =>
log.debug("Unhandled msg")
}
}
---------------EmployeeRoute----
package org
import akka.actor.{ActorSystem, Props}
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, StatusCodes}
import akka.stream.ActorMaterializer
import org.actor.EmployeeActor
import org.utils.{JsonUtils, TimeUtils}
import akka.http.scaladsl.server.Directives._
import akka.{NotUsed, util}
import akka.util.{ByteString, Timeout}
import org.data.Employee
import org.domain.EmployeeRequest
import akka.pattern.{Patterns, ask}
import akka.stream.scaladsl.Source
import org.actor.EmployeeActor.{Delete, Save, SearchAll, Update}
import org.service.EmployeeService
import scala.concurrent.duration._
import spray.json._
import scala.concurrent.{Await, Future}
class EmployeeRoute extends JsonUtils{
implicit val system=ActorSystem("Employee")
implicit val materializer=ActorMaterializer
import system.dispatcher
val actor=system.actorOf(Props[EmployeeActor],"employeeActor")
val employeeService=new EmployeeService()
implicit val timeOut=Timeout(5.seconds)
val getRoute={
pathPrefix("employee"){
(pathEndOrSingleSlash & get){
complete((actor ? SearchAll).mapTo[Seq[EmployeeRequest]])
}~
( path("update") & put & parameter("id".as[String])){id=>
entity(as[EmployeeRequest]){employee=>
complete((actor ? Update(employee,id)).map(_=>StatusCodes.OK))
}
}~
post{
entity(as[EmployeeRequest]) { employee =>
complete((actor ? Save(employee)).map(_ => StatusCodes.OK))
}
}~
delete{
(path(Segment) |parameter("id".as[String])){id=>
complete((actor ? Delete(id)).map(_=>StatusCodes.OK))
}
}
}
}
}
=================Error===============
[ERROR] [09/09/2020 19:46:48.551] [web-app-akka.actor.default-dispatcher-4] [akka.actor.ActorSystemImpl(web-app)] Error during processing of request: 'Cannot cast scala.concurrent.impl.Promise$Transformation to scala.collection.immutable.Seq'. Completing with 500 Internal Server Error response. To change default exception handling behavior, provide a custom ExceptionHandler.
java.lang.ClassCastException: Cannot cast scala.concurrent.impl.Promise$Transformation to scala.collection.immutable.Seq
at java.base/java.lang.Class.cast(Class.java:3734)
at scala.concurrent.Future.$anonfun$mapTo$1(Future.scala:464)
at scala.concurrent.impl.Promise$Transformation.run(Promise.scala:430)
at scala.concurrent.ExecutionContext$parasitic$.execute(ExecutionContext.scala:164)
at scala.concurrent.impl.Promise$Transformation.submitWithValue(Promise.scala:392)
at scala.concurrent.impl.Promise$DefaultPromise.submitWithValue(Promise.scala:299)
at scala.concurrent.impl.Promise$DefaultPromise.tryComplete0(Promise.scala:249)
at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:242)
at akka.pattern.PromiseActorRef.$bang(AskSupport.scala:615)
at org.actor.EmployeeActor$$anonfun$receive$1.applyOrElse(EmployeeActor.scala:32)
at akka.actor.Actor.aroundReceive(Actor.scala:537)
at akka.actor.Actor.aroundReceive$(Actor.scala:535)
at org.actor.EmployeeActor.aroundReceive(EmployeeActor.scala:22)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:577)
at akka.actor.ActorCell.invoke(ActorCell.scala:547)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:270)
at akka.dispatch.Mailbox.run(Mailbox.scala:231)
at akka.dispatch.Mailbox.exec(Mailbox.scala:243)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1016)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1665)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1598)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
please help me out..
You analyzed almost everything. EmployeeRepo.findAll is your problem. You should not use Futures in akka actors. pipeTo should be used instead.
Please try to update EmployeeActor
case SearchAll =>
log.info("received msg find ALL")
employeeService.findAll.pipeTo(sender())

not found: value on controller to upload files

implementation for uploading files with akka stream
https://github.com/playframework/play-scala-fileupload-example/blob/2.5.x/app/controllers/HomeController.scala
but compile error occured.
not found value: filePicData which is located on controller support
file: FileUploadControllerSupport.scala
[controller: FileUploadController.scala]
package controllers
import java.util.UUID
import javax.inject.Inject
import java.io.File
import java.nio.file.attribute.PosixFilePermission._
import java.nio.file.attribute.PosixFilePermissions
import java.nio.file.{ Files, Path }
import java.util
import javax.inject._
//for silhouette
import com.mohiva.play.silhouette.api._
import com.mohiva.play.silhouette.api.actions.SecuredRequest
import com.mohiva.play.silhouette.api.repositories.AuthInfoRepository
import com.mohiva.play.silhouette.api.services.AvatarService
import com.mohiva.play.silhouette.api.util.PasswordHasherRegistry
import com.mohiva.play.silhouette.impl.providers._
import utils.auth.{ DefaultEnv, WithProvider }
import forms.{ FileUploadForm, FileUploadFormSupport }
import models.User
import models.services.{ AuthTokenService, UserService }
import play.api.i18n.{ I18nSupport, Messages, MessagesApi }
import play.api.libs.concurrent.Execution.Implicits._
import play.api.libs.mailer.{ Email, MailerClient }
import scala.concurrent.{ ExecutionContext, Future }
//for akka stream
import akka.stream.IOResult
import akka.stream.scaladsl._
import akka.util.ByteString
import play.api._
import play.api.data.Form
import play.api.data.Forms._
import play.api.i18n.MessagesApi
import play.api.libs.streams._
import play.api.mvc.MultipartFormData.FilePart
import play.api.mvc._
import play.core.parsers.Multipart.FileInfo
class FileUploadController #Inject() (
val messagesApi: MessagesApi,
silhouette: Silhouette[DefaultEnv],
userService: UserService,
authInfoRepository: AuthInfoRepository,
authTokenService: AuthTokenService,
avatarService: AvatarService,
credentialsProvider: CredentialsProvider,
passwordHasherRegistry: PasswordHasherRegistry,
mailerClient: MailerClient,
implicit val webJarAssets: WebJarAssets,
//SocialProviderRegistry
socialProviderRegistry: SocialProviderRegistry,
//future
ec: ExecutionContext
)
extends Controller with I18nSupport {
private val logger = org.slf4j.LoggerFactory.getLogger(this.getClass)
def fileuploadview = silhouette.SecuredAction.async { implicit request =>
Future.successful(Ok(views.html.fileUpload(request.identity, FileUploadForm.form)))
}
type FilePartHandler[A] = FileInfo => Accumulator[ByteString, FilePart[A]]
private def handleFilePartAsFile: FilePartHandler[File] = {
case FileInfo(partName, filename, contentType) =>
val perms = java.util.EnumSet.of(OWNER_READ, OWNER_WRITE)
val attr = PosixFilePermissions.asFileAttribute(util.EnumSet.of(OWNER_READ, OWNER_WRITE))
val path: Path = Files.createTempFile("multipartBody", "tempFile", attr)
val file = path.toFile
val fileSink: Sink[ByteString, Future[IOResult]] = FileIO.toPath(path)
val accumulator: Accumulator[ByteString, IOResult] = Accumulator(fileSink)
accumulator.map {
case IOResult(count, status) =>
logger.info(s"count = $count, status = $status")
FilePart(partName, filename, contentType, file)
}
}
private def operateOnTempFile(file: File) = {
val size = Files.size(file.toPath)
logger.info(s"size = ${size}")
Files.deleteIfExists(file.toPath)
size
}
def upload = Action(parse.multipartFormData(handleFilePartAsFile)) { implicit request =>
val fileOption = request.body.file("name").map {
case FilePart(key, filename, contentType, file) =>
logger.info(s"key = ${key}, filename = ${filename}, contentType = ${contentType}, file = $file")
val data2 = operateOnTempFile(file)
}
FileUploadFormSupport.picsave(picFormData)
Ok(s"file size = ${fileOption.getOrElse("no file")}")
}
}
[forms; FileUploadForm.scala]
package forms
import play.api.data.Form
import play.api.data.Forms._
object FileUploadForm {
val form = Form(
mapping(
"picName" -> nonEmptyText
)(PicFormData.apply)(PicFormData.unapply)
)
case class PicFormData(
picName: String
)
}
[FileUploadFormSupport.scala]
package forms
import...
(....)
import forms.FileUploadForm._
def picsave(picFormData: PicFormData): Unit = {
(....)

How to call poloniex trading api in scala

My code is following.
import org.apache.commons.codec.binary.Hex
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.headers.RawHeader
import akka.http.scaladsl.model._
import akka.stream.ActorMaterializer
import akka.util.ByteString
import javax.crypto.spec.SecretKeySpec
import javax.crypto.Mac
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
class Poloniex {
def post(postData: String): Future[HttpResponse] = {
val command = "returnBalances"
val nonce = (System.currentTimeMillis / 1000).toString
val postData = s"nonce=$nonce&command=$command"
val headers: scala.collection.immutable.Seq[HttpHeader] = scala.collection.immutable.Seq(
RawHeader("Key", API_KEY),
RawHeader("Sign", hmacSha512(postData))
)
val entity = HttpEntity(postData)
for {
r <- Http().singleRequest(HttpRequest(HttpMethods.POST, TRADING_URL, headers, entity))
} yield r
}
private def hmacSha512(postData: String): String = {
val secret = new SecretKeySpec(API_SECRET.getBytes, HMAC_SHA512)
val mac = Mac.getInstance(HMAC_SHA512)
mac.init(secret)
val result: Array[Byte] = mac.doFinal(postData.getBytes)
new String(Hex.encodeHex(result))
}
}
I get
{"error":"Invalid command."}
But I couldn't find why I get error.
Can you find the reason why it get error?
The api documentation is here.
https://poloniex.com/support/api/
Thanks.
The content type of the request must be application/x-www-form-urlencoded. To set this, use FormData:
val entity =
FormData(Map("nonce" -> nonce, "command" -> command)).toEntity(HttpCharsets.`UTF-8`)

Not able to broadcast the message to all users

package controllers
import javax.inject._
import play.api._
import play.api.mvc._
import play.api.libs.json._
import javax.inject._
import play.api.libs.streams._
import akka.stream._
import akka.actor._
import akka.actor.Actor
import akka.actor.ActorSystem
import akka.actor.ActorRef
import akka.actor.Props
import akka.pattern.ask
import akka.util.Timeout
import akka.actor.PoisonPill
import scala.concurrent.duration._
import akka.stream.Materializer
import play.api.cache._
import play.api.libs.iteratee._
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.libs.concurrent._
import play.api.libs.ws.WSClient
//import play.api.cache.
/**
* This controller creates an `Action` to handle HTTP requests to the
* application's home page.
*/
#Singleton
class HomeController #Inject() (cache:CacheApi) (implicit actorSystem:ActorSystem,materializer:Materializer) extends Controller {
/**
* Create an Action to render an HTML page with a welcome message.
* The configuration in the `routes` file means that this method
* will be called when the application receives a `GET` request with
* a path of `/`.
*/
class MyWebSocketActor(out:ActorRef) extends Actor {
def receive = {
case msg:JsValue => {
val (returnMsg,returnCode) = validate(msg)
if(returnCode==404) {
out ! returnMsg
out !PoisonPill
} else if (returnCode==200) {
//send to all
val (enumerator,outChannel) = Concurrent.broadcast[JsValue]
val iteratee:Iteratee[JsValue,Unit] = Iteratee.foreach[JsValue]{returnMsg =>
outChannel.push(returnMsg)
}
println(returnMsg)
}
}
}
}
def validate(msg:JsValue) = {
val user_key = (msg \ "username").get
val username = user_key.toString().stripSuffix("\"").stripPrefix("\"")
val validate_user: Option[String] = cache.get[String](username)
val valid_result = validate_user.toString()
if (valid_result.equals("None")) {
//cache is not set
// println(valid_result)
//add user
cache.set(username,username)
Ok.withSession(username->username)
//notify all users
val successMsg = Json.parse("""{"username":"Server","message":"A new user has been connected"}""")
(successMsg, 200)
}
else {
//cache is already set
//send error msg to new user
val errorMsg = Json.parse("""{"username":"Server","message":"This username is already taken"}""")
(errorMsg, 404)
}
}
object MyWebSocketActor {
def props(out: ActorRef) = Props(new MyWebSocketActor(out))
}
def socket = WebSocket.accept[JsValue, JsValue] { request =>
ActorFlow.actorRef(out => MyWebSocketActor.props(out))
}
}
I am new to Akka and play websocket. I am working in Play 2.5.3. In the above code in receive function i am trying to get all the channels connected by val (enumerator,outChannel) = Concurrent.broadcast[JsValue] so that I can broadcast a message to all connected users. But no message is passed to any user but the println(returnMsg) is executed. What am I doing wrong?

error getting files from gridfs

I'm trying to display images and files from gridfs. So I started with the save function and it's working well:
import javax.inject.Inject
import org.joda.time.DateTime
import scala.concurrent.Future
import play.api.Logger
import play.api.Play.current
import play.api.i18n.{ I18nSupport, MessagesApi }
import play.api.mvc.{ Action, Controller, Request }
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.libs.json.{ Json, JsObject, JsString }
import reactivemongo.api.gridfs.{ GridFS, ReadFile }
import play.modules.reactivemongo.{
MongoController, ReactiveMongoApi, ReactiveMongoComponents
}
import play.modules.reactivemongo.json._, ImplicitBSONHandlers._
import play.modules.reactivemongo.json.collection._
class griidfs #Inject() (
val messagesApi: MessagesApi,
val reactiveMongoApi: ReactiveMongoApi)
extends Controller with MongoController with ReactiveMongoComponents {
import java.util.UUID
import MongoController.readFileReads
type JSONReadFile = ReadFile[JSONSerializationPack.type, JsString]
// get the collection 'articles'
// a GridFS store named 'attachments'
//val gridFS = GridFS(db, "attachments")
private val gridFS = reactiveMongoApi.gridFS
// let's build an index on our gridfs chunks collection if none
gridFS.ensureIndex().onComplete {
case index =>
Logger.info(s"Checked index, result is $index")
}
def saveAttachment =
Action.async(gridFSBodyParser(gridFS)) { request =>
// here is the future file!
val futureFile = request.body.files.head.ref
futureFile.onFailure {
case err => err.printStackTrace()
}
// when the upload is complete, we add the article id to the file entry (in order to find the attachments of the article)
val futureUpdate = for {
file <- { println("_0"); futureFile }
// here, the file is completely uploaded, so it is time to update the article
updateResult <- {
println("_1"); futureFile
}
} yield updateResult
futureUpdate.map { _ =>
Redirect(routes.Application.index())
}.recover {
case e => InternalServerError(e.getMessage())
}
}
but when I try to get files from gridfs to display them in my browser with this code:
import reactivemongo.api.gridfs.Implicits.DefaultReadFileReader
def getAttachment = Action.async { request =>
// find the matching attachment, if any, and streams it to the client
val file = gridFS.find[JsObject, JSONReadFile](Json.obj("_id" -> id))
request.getQueryString("inline") match {
case Some("true") =>
serve[JsString, JSONReadFile](gridFS)(file, CONTENT_DISPOSITION_INLINE)
case _ => serve[JsString, JSONReadFile](gridFS)(file)
}
}
I get this error:
type arguments [play.api.libs.json.JsObject,griidfs.this.JSONReadFile]
do not conform to method find's type parameter bounds
[S,T <:
reactivemongo.api.gridfs.ReadFile[reactivemongo.play.json.JSONSerializationPack.type, _]]
in this line:
val file = gridFS.find[JsObject, JSONReadFile](Json.obj("_id" -> id))
Any help please?
I have been battling the same issue most of the day and finally have it up and running. I think it has something to do with the imports I will check in my work then begin to remove them one by one to check which one causes the issue. In the meantime here is a list of my imports. Hope this helps
import javax.inject.Inject
import forms._
import models._
import org.joda.time.DateTime
import play.modules.reactivemongo.json.JSONSerializationPack
import services._
import play.api.data._
import play.api.data.Forms._
import scala.async.Async._
import play.api.i18n.{ I18nSupport, MessagesApi }
import play.api.mvc.{ Action, Controller, Request }
import play.api.libs.json.{ Json, JsObject, JsString }
import reactivemongo.api.gridfs.{ GridFS, ReadFile }
import play.modules.reactivemongo.{
MongoController, ReactiveMongoApi, ReactiveMongoComponents
}
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import scala.concurrent.Future
import play.modules.reactivemongo.json._
import com.mohiva.play.silhouette.api.{ Environment, LogoutEvent, Silhouette }
import com.mohiva.play.silhouette.impl.authenticators.CookieAuthenticator
import com.mohiva.play.silhouette.impl.providers.SocialProviderRegistry
import MongoController._
Edit Answer:
I have narrowed it down to this one: "import MongoController._"
add it and you should be ok :)