Skip to content

Instantly share code, notes, and snippets.

@elyphas
Created May 28, 2019 11:44
Show Gist options
  • Save elyphas/2f3d13a52f4463fac5df64438500f2a3 to your computer and use it in GitHub Desktop.
Save elyphas/2f3d13a52f4463fac5df64438500f2a3 to your computer and use it in GitHub Desktop.
package myceliumHandler
import java.io.{File, FileInputStream, FileOutputStream}
import postg.{CDatosGralesPedido, CReportePedido, CTipoDocumento}
import spatutorial.shared.WebSocketEvent.{GetPedido, GetReporte, IncomingFile}
import scala.collection.mutable
import scala.concurrent.Future
/** for Mycelium**/
import mycelium.server._
import mycelium.core._
import mycelium.core.message._
import mycelium.core.AkkaMessageBuilder.AkkaMessageBuilderByteBuffer
import mycelium.server.{WebsocketServerConfig}
import boopickle.Default._
import java.nio.ByteBuffer
import chameleon._
import chameleon.ext.boopickle._
import akka.actor.ActorSystem
import akka.stream.{ActorMaterializer, OverflowStrategy}
/** */
object FullRequestHandler {
//case class MsgMycelium(msg: String)
implicit val system = ActorSystem()
implicit val materializer = ActorMaterializer()
implicit val executionContext = scala.concurrent.ExecutionContext.Implicits.global
type Payload = ByteBuffer //String //MsgMycelium //String
type Event = String
type Failure = String //Int
type State = String
val payloadValue = 1
val builder = implicitly[AkkaMessageBuilder[ByteBuffer]]
val serializer = implicitly[Serializer[ClientMessage[Payload], ByteBuffer]]
val deserializer = implicitly[Deserializer[ServerMessage[Payload, Event, Failure], ByteBuffer]]
val config = WebsocketServerConfig(bufferSize = 5, overflowStrategy = OverflowStrategy.fail)
//[PayLoad, Event, Failure, State]
val handler = new FullRequestHandler[ByteBuffer, String, String, Option[String]] {
var seqChunks: Seq[Array[Byte]] = Seq.empty
val clients = mutable.HashSet.empty[NotifiableClient[String, Option[String]]]
val events = mutable.ArrayBuffer.empty[String]
override val initialState = Future.successful(None)
//case class HandlerResponse[Payload, Event, Failure, State](state: Future[State], value: Future[HandlerReturnValue[Payload, Event, Failure]])
//def Response(state: Future[State], value: Future[ReturnValue]): Response = HandlerResponse(state, value)
//state: Future[Option[String]]
override def onRequest(client: NotifiableClient[String, Option[String]], state: Future[Option[String]], path: List[String], args: ByteBuffer) = {
def deserialize[S: Pickler](ts: ByteBuffer) = Unpickle[S].fromBytes(ts)
def serialize[S: Pickler](ts: S) = Right(Pickle.intoBytes[S](ts))
def value[S: Pickler](ts: S, events: List[String] = Nil) = Future.successful(ReturnValue(serialize(ts), events))
def valueFut[S: Pickler](ts: Future[S], events: List[String] = Nil) = ts.map(ts => ReturnValue(serialize(ts), events))
def error(ts: String, events: List[String] = Nil) = Future.successful(ReturnValue(Left(ts), events))
path match {
case "true" :: Nil =>
Response(state, value(true))
case "getAllOfic" :: Nil =>
val tpeDoctos = new CTipoDocumento()
val results = tpeDoctos.getAll()
Response(state, valueFut( results ))
case "getPedido" :: Nil =>
val idPed: GetPedido = Unpickle[GetPedido].fromBytes(args)
val pedido = new CDatosGralesPedido()
val results = pedido.ById(idPed.idPedido)
Response(state, valueFut( results ) )
case "getReporte" :: Nil =>
val condicion: GetReporte = Unpickle[GetReporte].fromBytes(args)
val reporte = new CReportePedido()
val results = reporte.getCondition(condicion.criteria)
Response(state, valueFut(results))
case "saveImage" :: Nil =>
//val f: IncomingFile = Unpickle[IncomingFile].fromBytes(args)
val f = deserialize[IncomingFile](args)
seqChunks = seqChunks ++: Seq(f.file)
if (f.eof) {
val fullFile = seqChunks.foldLeft(Array.empty[Byte])(_++_)
seqChunks = Seq.empty
val nameFile = "PEDIDO" + "-" + f.idPedido.ejercicio + "-" + f.idPedido.no_pedido + ".pdf"
val imgOutFile = new File("/home/elyphas/PrjsScalaWS/manik/archivos_escaneados/" + nameFile )
val fileOuputStream = new FileOutputStream(imgOutFile)
fileOuputStream.write(fullFile)
fileOuputStream.close()
}
Response(state, value("ok"))
/*case "api" :: Nil =>
Response(state, value( deserialize[MsgMycelium](args) ) )*/
case "event" :: Nil =>
val events = List("event")
Response(state, value(true, events))
case "state" :: Nil =>
Response(state, valueFut(state))
case "state" :: "change" :: Nil =>
val otherUser = Future.successful(Option("anon"))
Response(otherUser, value(true))
case "state" :: "fail" :: Nil =>
val failure = Future.failed(new Exception("minus"))
Response(failure, value(true))
case "broken" :: Nil => Response(state, error("an error"))
case _ => Response(state, error("path not found"))
}
}
override def onEvent(client: NotifiableClient[String, Option[String]], state: Future[Option[String]], newEvents: List[String]) = {
events ++= newEvents
val downstreamEvents = newEvents.map(event => s"${event}-ok")
Reaction(state, Future.successful(downstreamEvents))
}
override def onClientConnect(client: NotifiableClient[String, Option[String]], state: Future[Option[String]]): Unit = {
client.notify(_ => Future.successful("started" :: Nil))
clients += client
()
}
override def onClientDisconnect(client: NotifiableClient[String, Option[String]], state: Future[Option[String]], reason: DisconnectReason): Unit = {
clients -= client
()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment