lila/modules/gameSearch/src/main/GameSearchForm.scala

143 lines
4.8 KiB
Scala
Raw Permalink Normal View History

2013-03-27 18:07:08 -06:00
package lila.gameSearch
2020-08-16 07:06:40 -06:00
import chess.Mode
2012-09-05 17:26:09 -06:00
import org.joda.time.DateTime
2013-05-24 11:04:49 -06:00
import play.api.data._
import play.api.data.Forms._
2012-09-05 17:26:09 -06:00
2013-05-24 11:04:49 -06:00
import lila.common.Form._
import lila.search.Range
2012-09-04 15:54:42 -06:00
2020-08-21 14:40:37 -06:00
final private[gameSearch] class GameSearchForm {
2012-09-04 15:54:42 -06:00
2019-12-13 07:30:20 -07:00
val search = Form(
mapping(
"players" -> mapping(
"a" -> optional(nonEmptyText),
"b" -> optional(nonEmptyText),
"winner" -> optional(nonEmptyText),
"loser" -> optional(nonEmptyText),
"white" -> optional(nonEmptyText),
"black" -> optional(nonEmptyText)
)(SearchPlayer.apply)(SearchPlayer.unapply),
"winnerColor" -> optional(numberIn(Query.winnerColors)),
2020-02-15 09:27:34 -07:00
"perf" -> optional(numberIn(lila.rating.PerfType.nonPuzzle.map(_.id))),
2019-12-13 07:30:20 -07:00
"source" -> optional(numberIn(Query.sources)),
"mode" -> optional(numberIn(Query.modes)),
"turnsMin" -> optional(numberIn(Query.turns)),
"turnsMax" -> optional(numberIn(Query.turns)),
"ratingMin" -> optional(numberIn(Query.averageRatings)),
"ratingMax" -> optional(numberIn(Query.averageRatings)),
"hasAi" -> optional(numberIn(Query.hasAis)),
"aiLevelMin" -> optional(numberIn(Query.aiLevels)),
"aiLevelMax" -> optional(numberIn(Query.aiLevels)),
"durationMin" -> optional(numberIn(Query.durations)),
"durationMax" -> optional(numberIn(Query.durations)),
"clock" -> mapping(
"initMin" -> optional(numberIn(Query.clockInits)),
"initMax" -> optional(numberIn(Query.clockInits)),
"incMin" -> optional(numberIn(Query.clockIncs)),
"incMax" -> optional(numberIn(Query.clockIncs))
)(SearchClock.apply)(SearchClock.unapply),
2020-08-21 14:40:37 -06:00
"dateMin" -> GameSearchForm.dateField,
"dateMax" -> GameSearchForm.dateField,
2019-12-13 07:30:20 -07:00
"status" -> optional(numberIn(Query.statuses)),
"analysed" -> optional(number),
"sort" -> optional(
mapping(
"field" -> stringIn(Sorting.fields),
"order" -> stringIn(Sorting.orders)
)(SearchSort.apply)(SearchSort.unapply)
)
)(SearchData.apply)(SearchData.unapply)
) fill SearchData()
2012-09-04 15:54:42 -06:00
}
2020-08-21 14:40:37 -06:00
private[gameSearch] object GameSearchForm {
val dateField = optional(ISODateOrTimestamp.isoDateOrTimestamp)
2016-01-30 19:20:54 -07:00
}
2013-05-09 17:00:27 -06:00
private[gameSearch] case class SearchData(
2012-09-07 09:14:59 -06:00
players: SearchPlayer = SearchPlayer(),
2015-07-18 05:00:26 -06:00
winnerColor: Option[Int] = None,
perf: Option[Int] = None,
source: Option[Int] = None,
2012-09-07 04:00:21 -06:00
mode: Option[Int] = None,
turnsMin: Option[Int] = None,
turnsMax: Option[Int] = None,
2013-12-17 15:20:18 -07:00
ratingMin: Option[Int] = None,
ratingMax: Option[Int] = None,
2012-09-07 04:00:21 -06:00
hasAi: Option[Int] = None,
aiLevelMin: Option[Int] = None,
aiLevelMax: Option[Int] = None,
durationMin: Option[Int] = None,
durationMax: Option[Int] = None,
2016-03-13 22:52:32 -06:00
clock: SearchClock = SearchClock(),
2019-04-08 11:44:20 -06:00
dateMin: Option[DateTime] = None,
dateMax: Option[DateTime] = None,
2012-09-07 04:00:21 -06:00
status: Option[Int] = None,
2013-10-02 10:02:59 -06:00
analysed: Option[Int] = None,
sort: Option[SearchSort] = None
) {
2015-08-27 04:50:10 -06:00
def sortOrDefault = sort | SearchSort()
2012-09-05 17:26:09 -06:00
2020-05-05 22:11:15 -06:00
def query =
Query(
user1 = players.cleanA,
user2 = players.cleanB,
winner = players.cleanWinner,
loser = players.cleanLoser,
winnerColor = winnerColor,
perf = perf,
source = source,
rated = mode flatMap Mode.apply map (_.rated),
turns = Range(turnsMin, turnsMax),
averageRating = Range(ratingMin, ratingMax),
hasAi = hasAi map (_ == 1),
aiLevel = Range(aiLevelMin, aiLevelMax),
duration = Range(durationMin, durationMax),
clock = Clocking(clock.initMin, clock.initMax, clock.incMin, clock.incMax),
date = Range(dateMin, dateMax),
status = status,
analysed = analysed map (_ == 1),
whiteUser = players.cleanWhite,
blackUser = players.cleanBlack,
sorting = Sorting(sortOrDefault.field, sortOrDefault.order)
)
2012-09-05 17:26:09 -06:00
2015-09-01 06:18:24 -06:00
def nonEmptyQuery = Some(query).filter(_.nonEmpty)
2012-09-05 17:26:09 -06:00
}
2012-09-07 09:14:59 -06:00
2013-05-09 17:00:27 -06:00
private[gameSearch] case class SearchPlayer(
2012-09-07 09:14:59 -06:00
a: Option[String] = None,
b: Option[String] = None,
winner: Option[String] = None,
2017-12-16 20:52:50 -07:00
loser: Option[String] = None,
white: Option[String] = None,
black: Option[String] = None
) {
2012-09-07 09:14:59 -06:00
2015-07-26 15:19:59 -06:00
lazy val cleanA = clean(a)
lazy val cleanB = clean(b)
def cleanWinner = oneOf(winner)
2019-12-13 07:30:20 -07:00
def cleanLoser = oneOf(loser)
def cleanWhite = oneOf(white)
def cleanBlack = oneOf(black)
2012-09-07 09:14:59 -06:00
private def oneOf(s: Option[String]) = clean(s).filter(List(cleanA, cleanB).flatten.contains)
private def clean(s: Option[String]) = s map (_.trim.toLowerCase) filter (_.nonEmpty)
2012-09-07 09:14:59 -06:00
}
2013-05-09 17:00:27 -06:00
private[gameSearch] case class SearchSort(
2017-08-23 17:56:39 -06:00
field: String = Sorting.default.f,
order: String = Sorting.default.order
)
2016-03-13 22:52:32 -06:00
private[gameSearch] case class SearchClock(
2017-08-23 17:56:39 -06:00
initMin: Option[Int] = None,
initMax: Option[Int] = None,
incMin: Option[Int] = None,
incMax: Option[Int] = None
)