Application.scala 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package controllers
  2. import java.util.concurrent.ThreadLocalRandom
  3. import scala.concurrent.{Future, ExecutionContext}
  4. import play.api.libs.json.{JsObject, Json, JsValue}
  5. import play.api.mvc._
  6. import play.mvc.Http
  7. import reactivemongo.api.ReadPreference
  8. import reactivemongo.play.json.collection.JSONCollection
  9. import play.modules.reactivemongo.{
  10. ReactiveMongoApi, ReactiveMongoComponents, MongoController
  11. }
  12. import play.modules.reactivemongo.json._
  13. class Application (val controllerComponents: ControllerComponents, reactiveMongoApi: ReactiveMongoApi)(implicit ec: ExecutionContext)
  14. extends BaseController {
  15. private def worldCollection: JSONCollection = reactiveMongoApi.db.collection[JSONCollection]("world")
  16. private def fortuneCollection: JSONCollection = reactiveMongoApi.db.collection[JSONCollection]("fortune")
  17. private val projection = Json.obj("_id" -> 0)
  18. def getRandomWorlds(queries: Int): Future[Seq[Option[JsObject]]] = {
  19. val futureWorlds: Seq[Future[Option[JsObject]]] = for {
  20. _ <- 1 to queries
  21. } yield { worldCollection
  22. .find(Json.obj("_id" -> getNextRandom), projection)
  23. .one[JsObject]
  24. }
  25. Future.sequence(futureWorlds)
  26. }
  27. def getRandomWorld = {
  28. val futureWorld = worldCollection
  29. .find(Json.obj("id" -> getNextRandom), projection)
  30. .one[JsValue]
  31. futureWorld
  32. }
  33. def getFortunes: Future[List[JsObject]] = {
  34. val futureFortunes: Future[List[JsObject]] =
  35. fortuneCollection.find(Json.obj())
  36. .cursor[JsObject](ReadPreference.primaryPreferred, false).collect[List]()
  37. futureFortunes
  38. }
  39. def updateWorlds(queries: Int): Future[Seq[JsObject]] = {
  40. getRandomWorlds(queries)
  41. .map(_.flatten)
  42. .map(_.map(oldWorld => {
  43. val newWorld = oldWorld ++ Json.obj("randomNumber" -> getNextRandom)
  44. worldCollection.update(oldWorld, newWorld).map(result => newWorld)
  45. }))
  46. .map(Future.sequence(_))
  47. .flatten
  48. }
  49. def getNextRandom: Int = {
  50. ThreadLocalRandom.current().nextInt(TestDatabaseRows) + 1
  51. }
  52. // Semi-Common code between Scala database code
  53. protected val TestDatabaseRows = 10000
  54. def db = Action.async {
  55. getRandomWorld.map { worlds =>
  56. Ok(Json.toJson(worlds.head))
  57. }
  58. }
  59. def queries(countString: String) = Action.async {
  60. val n = parseCount(countString)
  61. getRandomWorlds(n).map { worlds =>
  62. Ok(Json.toJson(worlds))
  63. }
  64. }
  65. private def byMessage(item: JsValue): String = {
  66. (item \ "message").as[String]
  67. }
  68. def fortunes() = Action.async {
  69. getFortunes.map { dbFortunes =>
  70. val appendedFortunes = Json.obj("_id" -> 0, "message" -> "Additional fortune added at request time.") :: dbFortunes
  71. val sorted = appendedFortunes.sortBy(byMessage(_))
  72. Ok(views.html.fortune(sorted))
  73. }
  74. }
  75. def update(queries: String) = Action.async {
  76. val n = parseCount(queries)
  77. updateWorlds(n).map { worlds =>
  78. Ok(Json.toJson(worlds))
  79. }
  80. }
  81. private def parseCount(s: String): Int = {
  82. try {
  83. val parsed = java.lang.Integer.parseInt(s, 10)
  84. parsed match {
  85. case i if i < 1 => 1
  86. case i if i > 500 => 500
  87. case i => i
  88. }
  89. } catch {
  90. case _: NumberFormatException => 1
  91. }
  92. }
  93. }