Auctions show
This commit is contained in:
@@ -3,23 +3,25 @@ package controllers
|
||||
import actors.auctions.AuctionPublisher
|
||||
import controllers.authentication.AuthenticatedAction
|
||||
import dao.{AuctionsDAO, AuthTokensDAO}
|
||||
import models.AuctionStatus.Ready
|
||||
import models.{Auction, User}
|
||||
import org.apache.pekko.actor.typed.ActorRef
|
||||
import play.api.libs.functional.syntax.toFunctionalBuilderOps
|
||||
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 {
|
||||
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)
|
||||
@@ -27,6 +29,16 @@ class AuctionsController @Inject()(val controllerComponents: ControllerComponent
|
||||
} 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(
|
||||
@@ -44,4 +56,18 @@ class AuctionsController @Inject()(val controllerComponents: ControllerComponent
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,35 @@
|
||||
package dao
|
||||
|
||||
import models.{Auction, AuctionStatus}
|
||||
import schemas.Auctions
|
||||
import schemas.given
|
||||
import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider}
|
||||
import slick.jdbc.PostgresProfile
|
||||
import slick.jdbc.PostgresProfile.api.*
|
||||
|
||||
import java.time.Instant
|
||||
import javax.inject.Inject
|
||||
import scala.concurrent.{ExecutionContext, Future}
|
||||
import scala.util.Random
|
||||
|
||||
import models.{Auction, AuctionStatus, User}
|
||||
import schemas.Auctions
|
||||
import schemas.given
|
||||
|
||||
class AuctionsDAO @Inject()(protected val dbConfigProvider: DatabaseConfigProvider)(implicit val ec: ExecutionContext)
|
||||
extends HasDatabaseConfigProvider[PostgresProfile] {
|
||||
|
||||
def list_available(user: models.User): Future[Seq[Auction]] = {
|
||||
def list_available(user: User): Future[Seq[Auction]] = {
|
||||
db.run(availableScope(user).result)
|
||||
}
|
||||
|
||||
def showAvailable(user: User, id: Long): Future[Option[Auction]] = {
|
||||
db.run {
|
||||
Auctions.filter(row => (row.status === AuctionStatus.Ready) && (row.authorId =!= user.id.get)).result
|
||||
availableScope(user).filter(_.id === id).take(1).result.headOption
|
||||
}
|
||||
}
|
||||
|
||||
def list_created_by(user: models.User): Future[Seq[Auction]] = {
|
||||
def list_created_by(user: User): Future[Seq[Auction]] = {
|
||||
db.run(Auctions.filter(_.authorId === user.id).result)
|
||||
}
|
||||
|
||||
def create(name: String, startingPrice: BigDecimal, author: models.User): Future[Auction] = {
|
||||
def create(name: String, startingPrice: BigDecimal, author: User): Future[Auction] = {
|
||||
val auction = Auction(
|
||||
id = None, name = name,
|
||||
gid = Random.alphanumeric.take(24).mkString,
|
||||
@@ -45,6 +49,10 @@ class AuctionsDAO @Inject()(protected val dbConfigProvider: DatabaseConfigProvid
|
||||
|
||||
def changeStatus(auctionId: Long, status: AuctionStatus): Future[Boolean] = {
|
||||
db.run(Auctions.filter(_.id === auctionId).map(_.status).update(status))
|
||||
.map(_ == 1)
|
||||
.map(_ == 1)
|
||||
}
|
||||
|
||||
private def availableScope(user: User) = {
|
||||
Auctions.filter(row => (row.status === AuctionStatus.Ready) && (row.authorId =!= user.id.get))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ GET /user_data controllers.HomeController.userData()
|
||||
GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset)
|
||||
|
||||
GET /auctions controllers.AuctionsController.index()
|
||||
GET /auctions/:id controllers.AuctionsController.show(id: Long)
|
||||
POST /auctions controllers.AuctionsController.create()
|
||||
|
||||
-> /-devel controllers.devel.DevRouter
|
||||
Reference in New Issue
Block a user