74 lines
2.7 KiB
Scala
74 lines
2.7 KiB
Scala
package controllers
|
|
|
|
import actors.auctions.AuctionPublisher
|
|
import controllers.authentication.AuthenticatedAction
|
|
import dao.{AuctionsDAO, AuthTokensDAO}
|
|
import org.apache.pekko.actor.typed.ActorRef
|
|
import play.api.libs.json.*
|
|
import play.api.mvc.{BaseController, ControllerComponents}
|
|
|
|
import javax.inject.{Inject, Singleton}
|
|
import scala.concurrent.{ExecutionContext, Future}
|
|
import models.Auction
|
|
import caching.{CheckFresh, DigestEtagable, Etagable}
|
|
|
|
import java.io.DataOutputStream
|
|
|
|
@Singleton
|
|
class AuctionsController @Inject()(val controllerComponents: ControllerComponents,
|
|
val auctionsDAO: AuctionsDAO,
|
|
val authTokensDAO: AuthTokensDAO,
|
|
authenticatedAction: AuthenticatedAction,
|
|
val auctionPublisher: ActorRef[AuctionPublisher.Command])
|
|
(implicit val ec: ExecutionContext)
|
|
extends BaseController with CheckFresh {
|
|
def index = authenticatedAction.async { request =>
|
|
for {
|
|
auctions <- auctionsDAO.list_available(request.user)
|
|
json = Json.toJson(auctions)
|
|
} yield Ok(json)
|
|
}
|
|
|
|
def show(id: Long) = authenticatedAction.async { implicit request =>
|
|
auctionsDAO.showAvailable(request.user, id).map { auctionOpt =>
|
|
auctionOpt.fold(NotFound) { auction =>
|
|
checkFresh(auction) {
|
|
Ok(Json.toJson(auction)).withHeaders("etag" -> auction.etag)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
def create = authenticatedAction.async(parse.json) { implicit request =>
|
|
val auctionCreateDataResult = request.body.validate[AuctionCreateData]
|
|
auctionCreateDataResult.fold(
|
|
errors => Future.successful(BadRequest(JsError.toJson(errors))),
|
|
auctionCreateData => {
|
|
for {
|
|
auction <- auctionsDAO.create(auctionCreateData.name, auctionCreateData.startingPrice, request.user)
|
|
json = Json.toJson(auction)
|
|
_ = auctionPublisher ! AuctionPublisher.Publish(auction, request.user)
|
|
} yield Created(json)
|
|
}
|
|
)
|
|
}
|
|
|
|
private case class AuctionCreateData(name: String, startingPrice: BigDecimal)
|
|
|
|
private given Reads[AuctionCreateData] = Json.reads[AuctionCreateData]
|
|
|
|
private given DigestEtagable[Auction] with {
|
|
override protected def writeDigestData(a: Auction, s: DataOutputStream): Unit = {
|
|
s.writeLong(a.id.getOrElse(0))
|
|
s.writeLong(a.authorId)
|
|
s.writeUTF(a.gid)
|
|
s.writeUTF(a.name)
|
|
s.writeLong(a.createdAt.getEpochSecond)
|
|
|
|
s.writeLong(a.currentBidderId.getOrElse(0))
|
|
a.currentBid.foreach(b => s.writeLong((b * 1000).toLong))
|
|
a.currentBidAt.foreach(ba => s.writeLong(ba.getEpochSecond))
|
|
}
|
|
}
|
|
}
|