tournaments wip
This commit is contained in:
parent
3b2176d903
commit
8c4a16e6e0
30
app/controllers/Tournament.scala
Normal file
30
app/controllers/Tournament.scala
Normal file
|
@ -0,0 +1,30 @@
|
|||
package controllers
|
||||
|
||||
import lila._
|
||||
import views._
|
||||
import http.Context
|
||||
|
||||
import play.api.mvc.Result
|
||||
|
||||
object Tournament extends LilaController {
|
||||
|
||||
val repo = env.tournament.repo
|
||||
val forms = env.tournament.forms
|
||||
|
||||
val home = Open { implicit ctx ⇒
|
||||
IOk(repo.created map { tournaments ⇒
|
||||
html.tournament.home(tournaments)
|
||||
})
|
||||
}
|
||||
|
||||
def show(id: String) = Open { implicit ctx ⇒
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
def form = Auth { implicit ctx ⇒
|
||||
me ⇒
|
||||
Ok(html.tournament.form(forms.create))
|
||||
}
|
||||
|
||||
def create = TODO
|
||||
}
|
|
@ -97,6 +97,10 @@ final class CoreEnv private (application: Application, val settings: Settings) {
|
|||
flood = security.flood,
|
||||
indexGame = search.indexGame)
|
||||
|
||||
lazy val tournament = new lila.tournament.TournamentEnv(
|
||||
settings = settings,
|
||||
mongodb = mongodb.apply _)
|
||||
|
||||
lazy val analyse = new lila.analyse.AnalyseEnv(
|
||||
settings = settings,
|
||||
gameRepo = game.gameRepo,
|
||||
|
|
|
@ -40,6 +40,8 @@ final class Settings(config: Config) {
|
|||
val RoundCollectionRoom = getString("round.collection.room")
|
||||
val RoundCollectionWatcherRoom = getString("round.collection.watcher_room")
|
||||
|
||||
val TournamentCollectionTournament = getString("tournament.collection.tournament")
|
||||
|
||||
val AnalyseCachedNbTtl = millis("analyse.cached.nb.ttl")
|
||||
|
||||
val UserPaginatorMaxPerPage = getInt("user.paginator.max_per_page")
|
||||
|
|
|
@ -174,9 +174,9 @@ class GameRepo(collection: MongoCollection)
|
|||
|
||||
def recentGames(limit: Int): IO[List[DbGame]] = io {
|
||||
find(Query.started ++ Query.turnsGt(1))
|
||||
.sort(DBObject("createdAt" -> -1))
|
||||
.sort(Query.sortCreated)
|
||||
.limit(limit)
|
||||
.toList.map(_.decode).flatten sortBy (_.id)
|
||||
.toList.map(_.decode).flatten
|
||||
}
|
||||
|
||||
def games(ids: List[String]): IO[List[DbGame]] = io {
|
||||
|
|
|
@ -162,7 +162,8 @@ final class I18nKeys(translator: Translator) {
|
|||
val bookmarkThisGame = new Key("bookmarkThisGame")
|
||||
val toggleBackground = new Key("toggleBackground")
|
||||
val advancedSearch = new Key("advancedSearch")
|
||||
val tournament = new Key("tournament")
|
||||
val freeOnlineChessGamePlayChessNowInACleanInterfaceNoRegistrationNoAdsNoPluginRequiredPlayChessWithComputerFriendsOrRandomOpponents = new Key("freeOnlineChessGamePlayChessNowInACleanInterfaceNoRegistrationNoAdsNoPluginRequiredPlayChessWithComputerFriendsOrRandomOpponents")
|
||||
|
||||
def keys = List(playWithAFriend, inviteAFriendToPlayWithYou, playWithTheMachine, challengeTheArtificialIntelligence, toInviteSomeoneToPlayGiveThisUrl, gameOver, waitingForOpponent, waiting, yourTurn, aiNameLevelAiLevel, level, toggleTheChat, toggleSound, chat, resign, checkmate, stalemate, white, black, createAGame, noGameAvailableRightNowCreateOne, whiteIsVictorious, blackIsVictorious, playWithTheSameOpponentAgain, newOpponent, playWithAnotherOpponent, yourOpponentWantsToPlayANewGameWithYou, joinTheGame, whitePlays, blackPlays, theOtherPlayerHasLeftTheGameYouCanForceResignationOrWaitForHim, makeYourOpponentResign, forceResignation, talkInChat, theFirstPersonToComeOnThisUrlWillPlayWithYou, whiteCreatesTheGame, blackCreatesTheGame, whiteJoinsTheGame, blackJoinsTheGame, whiteResigned, blackResigned, whiteLeftTheGame, blackLeftTheGame, shareThisUrlToLetSpectatorsSeeTheGame, youAreViewingThisGameAsASpectator, replayAndAnalyse, viewGameStats, flipBoard, threefoldRepetition, claimADraw, offerDraw, draw, nbConnectedPlayers, talkAboutChessAndDiscussLichessFeaturesInTheForum, seeTheGamesBeingPlayedInRealTime, gamesBeingPlayedRightNow, viewAllNbGames, viewNbCheckmates, nbBookmarks, nbPopularGames, nbAnalysedGames, bookmarkedByNbPlayers, viewInFullSize, logOut, signIn, signUp, people, games, forum, chessPlayers, minutesPerSide, variant, timeControl, start, username, password, haveAnAccount, allYouNeedIsAUsernameAndAPassword, learnMoreAboutLichess, rank, gamesPlayed, declineInvitation, cancel, timeOut, drawOfferSent, drawOfferDeclined, drawOfferAccepted, drawOfferCanceled, yourOpponentOffersADraw, accept, decline, playingRightNow, abortGame, gameAborted, standard, unlimited, mode, casual, rated, thisGameIsRated, rematch, rematchOfferSent, rematchOfferAccepted, rematchOfferCanceled, rematchOfferDeclined, cancelRematchOffer, viewRematch, play, inbox, chatRoom, spectatorRoom, composeMessage, sentMessages, incrementInSeconds, freeOnlineChess, spectators, nbWins, nbLosses, nbDraws, exportGames, color, eloRange, giveNbSeconds, searchAPlayer, whoIsOnline, allPlayers, namedPlayers, premoveEnabledClickAnywhereToCancel, thisPlayerUsesChessComputerAssistance, opening, takeback, proposeATakeback, takebackPropositionSent, takebackPropositionDeclined, takebackPropositionAccepted, takebackPropositionCanceled, yourOpponentProposesATakeback, bookmarkThisGame, toggleBackground, advancedSearch, freeOnlineChessGamePlayChessNowInACleanInterfaceNoRegistrationNoAdsNoPluginRequiredPlayChessWithComputerFriendsOrRandomOpponents)
|
||||
def keys = List(playWithAFriend, inviteAFriendToPlayWithYou, playWithTheMachine, challengeTheArtificialIntelligence, toInviteSomeoneToPlayGiveThisUrl, gameOver, waitingForOpponent, waiting, yourTurn, aiNameLevelAiLevel, level, toggleTheChat, toggleSound, chat, resign, checkmate, stalemate, white, black, createAGame, noGameAvailableRightNowCreateOne, whiteIsVictorious, blackIsVictorious, playWithTheSameOpponentAgain, newOpponent, playWithAnotherOpponent, yourOpponentWantsToPlayANewGameWithYou, joinTheGame, whitePlays, blackPlays, theOtherPlayerHasLeftTheGameYouCanForceResignationOrWaitForHim, makeYourOpponentResign, forceResignation, talkInChat, theFirstPersonToComeOnThisUrlWillPlayWithYou, whiteCreatesTheGame, blackCreatesTheGame, whiteJoinsTheGame, blackJoinsTheGame, whiteResigned, blackResigned, whiteLeftTheGame, blackLeftTheGame, shareThisUrlToLetSpectatorsSeeTheGame, youAreViewingThisGameAsASpectator, replayAndAnalyse, viewGameStats, flipBoard, threefoldRepetition, claimADraw, offerDraw, draw, nbConnectedPlayers, talkAboutChessAndDiscussLichessFeaturesInTheForum, seeTheGamesBeingPlayedInRealTime, gamesBeingPlayedRightNow, viewAllNbGames, viewNbCheckmates, nbBookmarks, nbPopularGames, nbAnalysedGames, bookmarkedByNbPlayers, viewInFullSize, logOut, signIn, signUp, people, games, forum, chessPlayers, minutesPerSide, variant, timeControl, start, username, password, haveAnAccount, allYouNeedIsAUsernameAndAPassword, learnMoreAboutLichess, rank, gamesPlayed, declineInvitation, cancel, timeOut, drawOfferSent, drawOfferDeclined, drawOfferAccepted, drawOfferCanceled, yourOpponentOffersADraw, accept, decline, playingRightNow, abortGame, gameAborted, standard, unlimited, mode, casual, rated, thisGameIsRated, rematch, rematchOfferSent, rematchOfferAccepted, rematchOfferCanceled, rematchOfferDeclined, cancelRematchOffer, viewRematch, play, inbox, chatRoom, spectatorRoom, composeMessage, sentMessages, incrementInSeconds, freeOnlineChess, spectators, nbWins, nbLosses, nbDraws, exportGames, color, eloRange, giveNbSeconds, searchAPlayer, whoIsOnline, allPlayers, namedPlayers, premoveEnabledClickAnywhereToCancel, thisPlayerUsesChessComputerAssistance, opening, takeback, proposeATakeback, takebackPropositionSent, takebackPropositionDeclined, takebackPropositionAccepted, takebackPropositionCanceled, yourOpponentProposesATakeback, bookmarkThisGame, toggleBackground, advancedSearch, tournament, freeOnlineChessGamePlayChessNowInACleanInterfaceNoRegistrationNoAdsNoPluginRequiredPlayChessWithComputerFriendsOrRandomOpponents)
|
||||
}
|
||||
|
|
16
app/tournament/DataForm.scala
Normal file
16
app/tournament/DataForm.scala
Normal file
|
@ -0,0 +1,16 @@
|
|||
package lila
|
||||
package tournament
|
||||
|
||||
import play.api.data._
|
||||
import play.api.data.Forms._
|
||||
import play.api.data.validation.Constraints._
|
||||
|
||||
final class DataForm {
|
||||
|
||||
val create = Form(mapping(
|
||||
"maxUsers" -> number.verifying(min(3), max(8))
|
||||
)(TournamentSetup.apply)(TournamentSetup.unapply))
|
||||
}
|
||||
|
||||
case class TournamentSetup(
|
||||
maxUsers: Int)
|
26
app/tournament/Status.scala
Normal file
26
app/tournament/Status.scala
Normal file
|
@ -0,0 +1,26 @@
|
|||
package lila
|
||||
package tournament
|
||||
|
||||
sealed abstract class Status(val id: Int) extends Ordered[Status] {
|
||||
|
||||
def compare(other: Status) = id compare other.id
|
||||
|
||||
def name = toString
|
||||
|
||||
def is(s: Status): Boolean = this == s
|
||||
def is(f: Status.type ⇒ Status): Boolean = is(f(Status))
|
||||
}
|
||||
|
||||
object Status {
|
||||
|
||||
case object Created extends Status(10)
|
||||
case object Started extends Status(20)
|
||||
case object Aborted extends Status(25) // from this point the game is finished
|
||||
case object Finished extends Status(30)
|
||||
|
||||
val all = List(Created, Started, Aborted, Finished)
|
||||
|
||||
val byId = all map { v ⇒ (v.id, v) } toMap
|
||||
|
||||
def apply(id: Int): Option[Status] = byId get id
|
||||
}
|
|
@ -6,8 +6,15 @@ import org.scala_tools.time.Imports._
|
|||
import com.novus.salat.annotations.Key
|
||||
|
||||
case class Tournament(
|
||||
@Key("_id") id: String,
|
||||
createdAt: DateTime,
|
||||
createdBy: String) {
|
||||
@Key("_id") id: String,
|
||||
createdBy: String,
|
||||
maxUsers: Int,
|
||||
createdAt: DateTime = DateTime.now,
|
||||
status: Status = Status.Created,
|
||||
users: List[String]) {
|
||||
|
||||
}
|
||||
|
||||
object Tournament {
|
||||
|
||||
}
|
||||
|
|
20
app/tournament/TournamentEnv.scala
Normal file
20
app/tournament/TournamentEnv.scala
Normal file
|
@ -0,0 +1,20 @@
|
|||
package lila
|
||||
package tournament
|
||||
|
||||
import game.{ GameRepo, DbGame }
|
||||
import core.Settings
|
||||
|
||||
import com.traackr.scalastic.elasticsearch
|
||||
import com.mongodb.casbah.MongoCollection
|
||||
|
||||
final class TournamentEnv(
|
||||
settings: Settings,
|
||||
mongodb: String ⇒ MongoCollection) {
|
||||
|
||||
import settings._
|
||||
|
||||
lazy val forms = new DataForm
|
||||
|
||||
lazy val repo = new TournamentRepo(
|
||||
collection = mongodb(TournamentCollectionTournament))
|
||||
}
|
27
app/tournament/TournamentRepo.scala
Normal file
27
app/tournament/TournamentRepo.scala
Normal file
|
@ -0,0 +1,27 @@
|
|||
package lila
|
||||
package tournament
|
||||
|
||||
import com.novus.salat._
|
||||
import com.novus.salat.dao._
|
||||
import com.mongodb.casbah.MongoCollection
|
||||
import com.mongodb.casbah.query.Imports._
|
||||
import scalaz.effects._
|
||||
import org.joda.time.DateTime
|
||||
import org.scala_tools.time.Imports._
|
||||
|
||||
class TournamentRepo(collection: MongoCollection)
|
||||
extends SalatDAO[Tournament, String](collection) {
|
||||
|
||||
def byId(id: String): IO[Option[Tournament]] = io {
|
||||
findOneById(id)
|
||||
}
|
||||
|
||||
def created: IO[List[Tournament]] = io {
|
||||
find(DBObject("status" -> Status.Created))
|
||||
.sort(DBObject("createdAt" -> -1))
|
||||
.toList
|
||||
}
|
||||
|
||||
private def idSelector(id: String): DBObject = DBObject("_id" -> id)
|
||||
private def idSelector(tournament: Tournament): DBObject = idSelector(tournament.id)
|
||||
}
|
|
@ -13,12 +13,13 @@ final class SiteMenu(trans: I18nKeys) {
|
|||
|
||||
val play = new Elem("play", routes.Lobby.home, trans.play)
|
||||
val game = new Elem("game", routes.Game.realtime, trans.games)
|
||||
val tournament = new Elem("tournament", routes.Tournament.home, trans.tournament)
|
||||
val user = new Elem("user", routes.User.list(page = 1), trans.people)
|
||||
val forum = new Elem("forum", routes.ForumCateg.index, trans.forum)
|
||||
val message = new Elem("message", routes.Message.inbox(page = 1), trans.inbox)
|
||||
|
||||
private val authenticated = List(play, game, user, forum, message)
|
||||
private val anonymous = List(play, game, user, forum)
|
||||
private val authenticated = List(play, game, tournament, user, forum, message)
|
||||
private val anonymous = List(play, game, tournament, user, forum)
|
||||
|
||||
def all(me: Option[User]) = me.isDefined.fold(authenticated, anonymous)
|
||||
}
|
||||
|
|
8
app/views/tournament/form.scala.html
Normal file
8
app/views/tournament/form.scala.html
Normal file
|
@ -0,0 +1,8 @@
|
|||
@(form: Form[_])(implicit ctx: Context)
|
||||
|
||||
@tournament.layout(
|
||||
title = "New tournament") {
|
||||
<h1>New tournament</h1>
|
||||
<form action="@routes.Tournament.create" method="POST">
|
||||
</form>
|
||||
}
|
13
app/views/tournament/home.scala.html
Normal file
13
app/views/tournament/home.scala.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
@(tournaments: List[lila.tournament.Tournament])(implicit ctx: Context)
|
||||
|
||||
@tournament.layout(
|
||||
title = "Tournaments") {
|
||||
|
||||
<div class="content_box tournament_box">
|
||||
<h1 class="lichess_title">Tournaments</h1>
|
||||
<div class="body">
|
||||
list of tournaments
|
||||
</div>
|
||||
<a href="@routes.Tournament.form()" class="action button">Create a new tournament</a>
|
||||
</div>
|
||||
}
|
12
app/views/tournament/layout.scala.html
Normal file
12
app/views/tournament/layout.scala.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
@(title: String)(body: Html)(implicit ctx: Context)
|
||||
|
||||
@moreCss = {
|
||||
@cssTag("tournament.css")
|
||||
}
|
||||
|
||||
@base.layout(
|
||||
title = title,
|
||||
moreCss = moreCss,
|
||||
active = siteMenu.tournament.some) {
|
||||
<div id="tournament">@body</div>
|
||||
}
|
|
@ -138,4 +138,5 @@ yourOpponentProposesATakeback=Your opponent proposes a takeback
|
|||
bookmarkThisGame=Bookmark this game
|
||||
toggleBackground=Toggle background color
|
||||
advancedSearch=Advanced Search
|
||||
tournament=Tournament
|
||||
freeOnlineChessGamePlayChessNowInACleanInterfaceNoRegistrationNoAdsNoPluginRequiredPlayChessWithComputerFriendsOrRandomOpponents=Free online Chess game. Play Chess now in a clean interface. No registration, no ads, no plugin required. Play Chess with computer, friends or random opponents.
|
||||
|
|
|
@ -138,4 +138,5 @@ yourOpponentProposesATakeback=Votre adversaire propose l'annulation du coup
|
|||
bookmarkThisGame=Mettre cette partie en favoris
|
||||
toggleBackground=Changer la couleur d'arrière plan
|
||||
advancedSearch=Recherche avancée
|
||||
tournament=Tournoi
|
||||
freeOnlineChessGamePlayChessNowInACleanInterfaceNoRegistrationNoAdsNoPluginRequiredPlayChessWithComputerFriendsOrRandomOpponents=Jeu d'échecs gratuit en ligne. Jouez aux échecs immédiatement avec une interface simple. Pas d'inscription obligatoire, pas de pub, pas de plugin. Jouez aux échecs contre l'ordinateur, des amis ou des adversaires en ligne.
|
||||
|
|
|
@ -38,8 +38,14 @@ GET /$gameId<[\w\-]{8}>/$color<white|black>/table controllers.Round.tableWatc
|
|||
GET /$fullId<[\w\-]{12}>/table controllers.Round.tablePlayer(fullId: String)
|
||||
GET /$gameId<[\w\-]{8}>/players controllers.Round.players(gameId: String)
|
||||
|
||||
# Tournament
|
||||
GET /tournament controllers.Tournament.home
|
||||
GET /tournament/$id<[\w\-]{8}> controllers.Tournament.show(id: String)
|
||||
GET /tournament/new controllers.Tournament.form
|
||||
POST /tournament/new controllers.Tournament.create
|
||||
|
||||
# Analyse
|
||||
GET /analyse/$gameId<[\w\-]{8}> controllers.Analyse.replay(gameId: String, color: String = "white")
|
||||
GET /analyse/$gameId<[\w\-]{8}> controllers.Analyse.replay(gameId: String, color: String = "white")
|
||||
GET /analyse/$gameId<[\w\-]{8}>/$color<white|black> controllers.Analyse.replay(gameId: String, color: String)
|
||||
POST /analyse/$gameId<[\w\-]{8}>/$color<white|black>/computer controllers.Analyse.computer(gameId: String, color: String)
|
||||
GET /$gameId<[\w\-]{8}>/stats controllers.Analyse.stats(gameId: String)
|
||||
|
|
Loading…
Reference in a new issue