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`)
Related
I have this 2 methods
import org.h2.store.fs.FilePath
import zio.*
import zio.Console.printLine
import zio.http.Client
import zio.nio.file.*
import zio.nio.charset.Charset
import zio.stream.*
import java.io.IOException
object FileStorage:
def saveToFile(data: String = "", filePath: String = "src/main/resources/data.json"): Unit =
lazy val logic = for {
encoded <- Charset.Standard.utf8.encodeString(data)
path = Path(filePath.split("/").head, filePath.split("/").tail: _*)
notExists <- Files.notExists(path)
- <- if (notExists) Files.createFile(path) else ZIO.attempt(())
_ <- Files.writeBytes(path, encoded)
_ <- Console.printLine(s"written to $path")
} yield ()
def unsafeF = (unsafeVal: Unsafe) => {
implicit val unsafe: Unsafe = unsafeVal
Runtime.default.unsafe.run(logic)
}
Unsafe.unsafe(unsafeF)
def readFromFile: ZIO[Any, Throwable, String] = {
val path = Path("src", "main", "resources", "data.json")
val bool = for bool <- Files.isReadable(path) yield bool
val zioStr = bool.flatMap(bool =>
if (bool) Files.readAllLines(path, Charset.Standard.utf8).map(fileLines => fileLines.head)
else {
saveToFile()
readFromFile})
zioStr
}
In def readFromFile i try to make empty an empty file if file don't exists
File generation working fine
then I'm trying to read that empty file and return it like a ZIO Response like that
import zio.http.{Client, *}
import zio.json.*
import zio.http.model.Method
import zio.{Scope, Task, ZIO, ZIOAppDefault}
import zio.http.Client
import zhttp.http.Status.NotFound
import zhttp.http.Status
import scala.language.postfixOps
import zio._
import scala.collection.immutable.List
import zio.{ExitCode, URIO, ZIO}
object ClientServer extends ZIOAppDefault {
val app: Http[Client, Throwable, Request, Response] = Http.collectZIO[Request]
case Method.GET -> !! / "readLeagues" =>
FileStorage.readFromFile.map(str => Response.json(str))
BUT in this case I getting Internal Server Error 500 on postman in http://localhost:8080/readLeagues
If at first I feed prefilled json file to
def readFromFile
It works fine Status: 200
And I getting a nice looking json as a body
Maybe I should set another default strings for data to prefill
def saveToFile
so json can be parsable?
or smth else
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.
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 = {
(....)
I am trying to insert data into MongoDB using Play-scala and ReactiveMongo.
Here is my DbimpService.scala:
package services
import models.Post
import reactivemongo.bson.BSONDocument
import reactivemongo.api.MongoDriver
import reactivemongo.api.collections.bson.BSONCollection
import scala.concurrent.ExecutionContext
import javax.inject.Inject
import play.api.libs.json.Json
import reactivemongo.play.json.collection.JSONCollection
import reactivemongo.api.commands.WriteResult
import scala.concurrent.Future
import org.apache.xerces.util.DatatypeMessageFormatter
class Dbimpservice #Inject() (implicit ec:ExecutionContext) extends Dbservice {
def create(p:Post):String={
var status = "Not Saved"
val driver = new MongoDriver
val connection = driver.connection(List("localhost"))
val db = connection("application")
val collection = db[BSONCollection]("post")
val futureList = collection.insert[Post](p)
futureList.onComplete { case sucess => println(sucess) }
return status
}
}
Here is my HomeController.scala:
package controllers
import javax.inject._
import play.api._
import play.api.mvc._
import models._
import scala.util.{ Failure, Success }
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import reactivemongo.api.{ MongoDriver, MongoConnection }
import reactivemongo.play.json.collection.JSONCollection
import reactivemongo.bson.BSONDocument
import reactivemongo.api.commands.WriteResult
import reactivemongo.api.collections.bson.BSONCollection
import play.api.libs.json.Json
import services.Dbservice
import services.Dbimpservice
import services.Dbservice
import scala.concurrent.ExecutionContext
import scala.concurrent.Await
import scala.concurrent.duration.Duration
/**
* This controller creates an `Action` to handle HTTP requests to the
* application's home page.
*/
#Singleton
class HomeController #Inject() (implicit ec:ExecutionContext,val Dbservice : Dbimpservice)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 `/`.
*/
def index = Action{
Ok("Hai")
}
def read = Action.async {
val query = BSONDocument()
val driver = new MongoDriver
val connection = driver.connection(List("localhost:27017"))
val db = connection("application")
val collection = db[BSONCollection]("post")
val futureList = collection.find(query).cursor[Post]().collect[List]()
futureList.map { list =>
Ok(list.toString())
}
}
def create = Action(BodyParsers.parse.json) { request =>
val personResult = request.body.validate[Post]
personResult.fold(
errors => {
BadRequest(Json.obj("status " ->"ERROR"))
},
valid = fun
)
}
def fun:Post => Result= { post =>
var ans = Dbservice.create(post)
Ok(ans)
}
}
I am trying to insert the data but not getting inserted and the error which i am getting is
Failure(reactivemongo.core.errors.ConnectionNotInitialized: MongoError['Connection is missing metadata (like protocol version, etc.) The connection pool is probably being initialized.'])
Some one please help me, I even referred the link
http://stackoverflow.com/questions/31456517/embedmongo-with-reactivemongo-process-does-not-exit
but did not get
Guessing that you are using a recent version of ReactiveMongo (0.11.7+), you are using a deprecated DB resolution code (connection(dbName) aka connection.apply(dbName).
See also
You need to use the asynchronous resolution, which benefit from the failover (to handle possible network latency/incident). The following code must so be refactored.
val db = connection("application")
val collection = db[BSONCollection]("post")
val futureList = collection.insert[Post](p)
Using the new DB resolution:
for {
db <- connection.database("application")
collection = db("post")
res <- collection.insert(p)
} yield res
I am trying to save an attachment using reactivemongo in Play 2.1 using the following code:
def upload = Action(parse.multipartFormData) { request =>
request.body.file("carPicture").map { picture =>
val filename = picture.filename
val contentType = picture.contentType
val gridFS = new GridFS(db, "attachments")
val fileToSave = DefaultFileToSave(filename, contentType)
val futureResult: Future[ReadFile[BSONValue]] = gridFS.writeFromInputStream(fileToSave, new FileInputStream(new File(filename)))
Ok(Json.obj("e" -> 0))
}.getOrElse {
Redirect(routes.Application.index).flashing(
"error" -> "Missing file"
)
}
}
I am getting the following error:
could not find implicit value for parameter readFileReader: reactivemongo.bson.BSONDocumentReader[reactivemongo.api.gridfs.ReadFile[reactivemongo.bson.BSONValue]]
[error] val futureResult: Future[ReadFile[BSONValue]] = gridFS.writeFromInputStream(fileToSave, new FileInputStream(new File(filename)))
What am I missing?
Thanks,
GA
Most likely you don't have the DefaultReadFileReader implicit object in scope, which you can fix by adding an import:
import reactivemongo.api.gridfs.Implicits._
The following compiles fine for me (using the Play 2.1 reactivemongo module, version 0.9):
package controllers
import java.io.{ File, FileInputStream }
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import play.api._
import play.api.mvc._
import play.api.libs.json._
import reactivemongo.api._
import reactivemongo.bson._
import reactivemongo.api.gridfs._
import reactivemongo.api.gridfs.Implicits._
import play.modules.reactivemongo.MongoController
object Application extends Controller with MongoController {
def index = Action {
Ok(views.html.index("Hello, world..."))
}
def upload = Action(parse.multipartFormData) { request =>
request.body.file("carPicture").map { picture =>
val filename = picture.filename
val contentType = picture.contentType
val gridFS = new GridFS(db, "attachments")
val fileToSave = DefaultFileToSave(filename, contentType)
val futureResult: Future[ReadFile[BSONValue]] = gridFS.writeFromInputStream(fileToSave, new FileInputStream(new File(filename)))
Ok(Json.obj("e" -> 0))
}.getOrElse {
Redirect(routes.Application.index).flashing(
"error" -> "Missing file"
)
}
}
}