complete search form backbone

pull/83/head
Thibault Duplessis 2012-09-05 00:59:21 +02:00
parent d30d5340a2
commit c8a90693a8
5 changed files with 122 additions and 20 deletions

View File

@ -9,28 +9,46 @@ final class DataForm {
val search = Form(mapping(
"usernames" -> optional(nonEmptyText),
"variant" -> optional(numberIn(Query.variants)),
"mode" -> optional(numberIn(Query.modes)),
"opening" -> optional(stringIn(Query.openings)),
"turnsMin" -> optional(numberIn(Query.turns)),
"turnsMax" -> optional(numberIn(Query.turns))
"variant" -> numberIn(Query.variants),
"mode" -> numberIn(Query.modes),
"opening" -> stringIn(Query.openings),
"turnsMin" -> numberIn(Query.turns),
"turnsMax" -> numberIn(Query.turns),
"eloMin" -> numberIn(Query.averageElos),
"eloMax" -> numberIn(Query.averageElos),
"hasAi" -> numberIn(Query.hasAis),
"aiLevel" -> numberIn(Query.aiLevels),
"durationMin" -> numberIn(Query.durations),
"durationMax" -> numberIn(Query.durations),
"dateMin" -> stringIn(Query.dates),
"dateMax" -> stringIn(Query.dates),
"status" -> numberIn(Query.statuses)
)(SearchData.apply)(SearchData.unapply))
private def numberIn(choices: List[(Int, String)]) =
number.verifying(hasKey(choices, _))
private def numberIn(choices: Seq[(Int, String)]) =
optional(number.verifying(hasKey(choices, _)))
private def stringIn(choices: List[(String, String)]) =
nonEmptyText.verifying(hasKey(choices, _))
private def stringIn(choices: Seq[(String, String)]) =
optional(text.verifying(hasKey(choices, _)))
private def hasKey[A](choices: List[(A, _)], key: A) =
private def hasKey[A](choices: Seq[(A, _)], key: A) =
choices map (_._1) contains key
}
case class SearchData(
usernames: Option[String] = None,
usernames: Option[String],
variant: Option[Int],
mode: Option[Int],
opening: Option[String],
turnsMin: Option[Int],
turnsMax: Option[Int]
turnsMax: Option[Int],
eloMin: Option[Int],
eloMax: Option[Int],
hasAi: Option[Int],
aiLevel: Option[Int],
durationMin: Option[Int],
durationMax: Option[Int],
dateMin: Option[String],
dateMax: Option[String],
status: Option[Int]
)

View File

@ -2,16 +2,18 @@ package lila
package search
import Game.fields
import chess.{ Variant, Mode, EcoDb }
import chess.{ Variant, Mode, Status, EcoDb }
import org.elasticsearch.index.query._, FilterBuilders._, QueryBuilders._
case class Query(
usernames: List[String] = Nil,
variant: Option[Int] = None,
status: Option[Int] = None,
turns: Range[Int] = Range.none,
averageElo: Range[Int] = Range.none,
ai: Range[Int] = Range.none,
hasAi: Option[Boolean] = None,
aiLevel: Range[Int] = Range.none,
rated: Option[Boolean] = None,
opening: Option[String] = None,
date: Range[String] = Range.none,
@ -33,10 +35,17 @@ case class Query(
duration filters fields.duration,
date filters fields.date,
averageElo filters fields.date,
ai filters fields.ai,
hasAi.toList map { a
a.fold(
rangeFilter(fields.ai) gt 0,
termFilter(fields.ai, null)
)
},
aiLevel filters fields.ai,
toFilter(variant, fields.variant),
toFilter(rated, fields.rated),
toFilter(opening, fields.opening)
toFilter(opening, fields.opening),
toFilter(status, fields.status)
).flatten
def toFilter(query: Option[_], name: String) =
@ -48,7 +57,9 @@ case class Query(
object Query {
val durations = List(0, 1, 2, 3, 5, 10, 15, 20, 30)
val durations = List(0, 1, 2, 3, 5, 10, 15, 20, 30) map { d
d -> (d + " minutes")
}
val variants = Variant.all map { v v.id -> v.name }
@ -62,6 +73,26 @@ object Query {
(1 to 5) ++ (10 to 45 by 5) ++ (50 to 90 by 10) ++ (100 to 300 by 25)
}.toList map { t t -> (t + " turns") }
val averageElos = (800 to 2300 by 100).toList map { e e -> (e + " ELO") }
val hasAis = List(
0 -> "Human opponent",
1 -> "Computer opponent")
val aiLevels = (1 to 8) map { l l -> ("Stockfish level " + l) }
val dates = List("0d" -> "Today") ++ {
(1 to 6) map { d (d + "d") -> (d + " days ago") }
} ++ {
(1 to 3) map { w (w + "w") -> (w + " weeks ago") }
} ++ {
(1 to 6) map { m (m + "m") -> (m + " months ago") }
} ++ {
(1 to 3) map { y (y + "y") -> (y + " years ago") }
}
val statuses = Status.finishedNotCheated map { s s.id -> s.name }
def test = Query(
usernames = List("thibault"),
duration = Range(60.some, 150.some),
@ -77,7 +108,8 @@ object Query {
turns = Range(20.some, 100.some),
averageElo = Range(1100.some, 2000.some),
opening = "A00".some,
ai = Range.none,
hasAi = true.some,
aiLevel = Range.none,
date = Range("2011-01-01".some, none),
sorting = Sorting(fields.date, "desc")
)

View File

@ -11,7 +11,7 @@ menu = game.sideMenu(listMenu, "search").some) {
<table>
<tr>
<th>
<label for="@form("usernames").id">Users</label>
<label for="@form("usernames").id">Players</label>
</th>
<td>
<input
@ -38,6 +38,14 @@ menu = game.sideMenu(listMenu, "search").some) {
@select(form("mode"), Query.modes, "Casual or Rated")
</td>
</tr>
<tr>
<th>
<label for="@form("status").id">Result</label>
</th>
<td>
@select(form("status"), Query.statuses, "Any result")
</td>
</tr>
<tr>
<th>
<label for="@form("opening").id">@trans.opening()</label>
@ -55,6 +63,49 @@ menu = game.sideMenu(listMenu, "search").some) {
To @select(form("turnsMax"), Query.turns, "Any number of turns")
</td>
</tr>
<tr>
<th>
<label>Players ELO</label>
</th>
<td>
From @select(form("eloMin"), Query.averageElos, "Any ELO")
To @select(form("eloMax"), Query.averageElos, "Any ELO")
</td>
</tr>
<tr>
<th>
<label for="@form("hasAi").id">Opponent</label>
</th>
<td>
@select(form("hasAi"), Query.hasAis, "Human or Computer")
</td>
</tr>
<tr>
<th>
<label for="@form("aiLevel").id">Stockfish level</label>
</th>
<td>
@select(form("aiLevel"), Query.aiLevels, "Any Stockfish level")
</td>
</tr>
<tr>
<th>
<label>Duration</label>
</th>
<td>
From @select(form("durationMin"), Query.durations, "Any duration")
To @select(form("durationMax"), Query.durations, "Any duration")
</td>
</tr>
<tr>
<th>
<label>Date</label>
</th>
<td>
From @select(form("dateMin"), Query.dates, "Any date")
To @select(form("dateMax"), Query.dates, "Any date")
</td>
</tr>
<tr>
<th></th>
<td>

@ -1 +1 @@
Subproject commit 56b2604f722084c739af8cfc821798d6d631fcbb
Subproject commit 6fc609570941db4840e7de7c810bb2fa957b4153

1
todo
View File

@ -37,3 +37,4 @@ complete search engine using https://github.com/bsadeh/scalastic
localize elo chart dates
recognize tor IPs http://en.lichess.org/forum/staff/cheater-101#9 https://check.torproject.org/cgi-bin/TorBulkExitList.py?ip=37.59.32.99
weird UI clock bug (+30 minutes) http://en.lichess.org/forum/lichess-feedback/game-timer-is-30-minutes-incorrectly#4
add more system messages to the game chat http://en.lichess.org/forum/lichess-feedback/feedback-about-chat-rooms#2