mirror of
				https://github.com/arcan1s/ffxivbis.git
				synced 2025-11-04 07:03:41 +00:00 
			
		
		
		
	base views
This commit is contained in:
		@ -23,7 +23,7 @@ class BiSView(override val storage: ActorRef, ariyala: ActorRef)(implicit timeou
 | 
			
		||||
          get {
 | 
			
		||||
            complete {
 | 
			
		||||
              bis(partyId, None).map { players =>
 | 
			
		||||
                BiSView.template(partyId, players, Piece.available, None)
 | 
			
		||||
                BiSView.template(partyId, players, None)
 | 
			
		||||
              }.map { text =>
 | 
			
		||||
                (StatusCodes.OK, RootView.toHtml(text))
 | 
			
		||||
              }
 | 
			
		||||
@ -53,8 +53,10 @@ class BiSView(override val storage: ActorRef, ariyala: ActorRef)(implicit timeou
 | 
			
		||||
                            maybePiece: Option[String], maybeIsTome: Option[String],
 | 
			
		||||
                            maybeLink: Option[String], action: String)
 | 
			
		||||
                           (implicit executionContext: ExecutionContext, timeout: Timeout): Future[Unit] = {
 | 
			
		||||
    import me.arcanis.ffxivbis.utils.Implicits._
 | 
			
		||||
 | 
			
		||||
    def getPiece(playerId: PlayerId, piece: String) =
 | 
			
		||||
      Try(Piece(piece, maybeIsTome.isDefined, playerId.job)).toOption
 | 
			
		||||
      Try(Piece(piece, maybeIsTome, playerId.job)).toOption
 | 
			
		||||
 | 
			
		||||
    PlayerId(partyId, player) match {
 | 
			
		||||
      case Some(playerId) => (maybePiece, action, maybeLink) match {
 | 
			
		||||
@ -77,7 +79,7 @@ class BiSView(override val storage: ActorRef, ariyala: ActorRef)(implicit timeou
 | 
			
		||||
object BiSView {
 | 
			
		||||
  import scalatags.Text.all._
 | 
			
		||||
 | 
			
		||||
  def template(partyId: String, party: Seq[Player], pieces: Seq[String], error: Option[String]): String =
 | 
			
		||||
  def template(partyId: String, party: Seq[Player], error: Option[String]): String =
 | 
			
		||||
    "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">" +
 | 
			
		||||
      html(lang:="en",
 | 
			
		||||
        head(
 | 
			
		||||
@ -95,7 +97,7 @@ object BiSView {
 | 
			
		||||
            select(name:="player", id:="player", title:="player")
 | 
			
		||||
                  (for (player <- party) yield option(player.playerId.toString)),
 | 
			
		||||
            select(name:="piece", id:="piece", title:="piece")
 | 
			
		||||
                  (for (piece <- pieces) yield option(piece)),
 | 
			
		||||
                  (for (piece <- Piece.available) yield option(piece)),
 | 
			
		||||
            input(name:="is_tome", id:="is_tome", title:="is tome", `type`:="checkbox"),
 | 
			
		||||
            label(`for`:="is_tome")("is tome gear"),
 | 
			
		||||
            input(name:="action", id:="action", `type`:="hidden", value:="add"),
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,120 @@
 | 
			
		||||
package me.arcanis.ffxivbis.http.view
 | 
			
		||||
 | 
			
		||||
import akka.actor.ActorRef
 | 
			
		||||
import akka.http.scaladsl.model.StatusCodes
 | 
			
		||||
import akka.http.scaladsl.server.Directives._
 | 
			
		||||
import akka.http.scaladsl.server.Route
 | 
			
		||||
import akka.util.Timeout
 | 
			
		||||
import me.arcanis.ffxivbis.http.{Authorization, LootHelper}
 | 
			
		||||
import me.arcanis.ffxivbis.models.{Piece, PlayerIdWithCounters}
 | 
			
		||||
 | 
			
		||||
import scala.concurrent.{ExecutionContext, Future}
 | 
			
		||||
import scala.util.{Failure, Success, Try}
 | 
			
		||||
 | 
			
		||||
class LootSuggestView(override val storage: ActorRef)(implicit timeout: Timeout)
 | 
			
		||||
  extends LootHelper(storage) with Authorization {
 | 
			
		||||
 | 
			
		||||
  def route: Route = getIndex ~ suggestLoot
 | 
			
		||||
 | 
			
		||||
  def getIndex: Route =
 | 
			
		||||
    path("party" / Segment / "suggest") { partyId: String =>
 | 
			
		||||
      extractExecutionContext { implicit executionContext =>
 | 
			
		||||
        authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ =>
 | 
			
		||||
          get {
 | 
			
		||||
            complete {
 | 
			
		||||
              val text = LootSuggestView.template(partyId, Seq.empty, None, None)
 | 
			
		||||
              (StatusCodes.OK, RootView.toHtml(text))
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  def suggestLoot: Route =
 | 
			
		||||
    path("party" / Segment / "suggest") { partyId: String =>
 | 
			
		||||
      extractExecutionContext { implicit executionContext =>
 | 
			
		||||
        authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ =>
 | 
			
		||||
          post {
 | 
			
		||||
            formFields("piece".as[String], "is_tome".as[String].?) { (piece, maybeTome) =>
 | 
			
		||||
              import me.arcanis.ffxivbis.utils.Implicits._
 | 
			
		||||
              val maybePiece = Try(Piece(piece, maybeTome)).toOption
 | 
			
		||||
 | 
			
		||||
              onComplete(suggestLootCall(partyId, maybePiece)) {
 | 
			
		||||
                case Success(players) =>
 | 
			
		||||
                  val text = LootSuggestView.template(partyId, players, maybePiece, None)
 | 
			
		||||
                  complete(StatusCodes.OK, RootView.toHtml(text))
 | 
			
		||||
                case Failure(exception) =>
 | 
			
		||||
                  val text = LootSuggestView.template(partyId, Seq.empty, maybePiece, Some(exception.getMessage))
 | 
			
		||||
                  complete(StatusCodes.OK, RootView.toHtml(text))
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  private def suggestLootCall(partyId: String, maybePiece: Option[Piece])
 | 
			
		||||
                             (implicit executionContext: ExecutionContext, timeout: Timeout): Future[Seq[PlayerIdWithCounters]] =
 | 
			
		||||
    maybePiece match {
 | 
			
		||||
      case Some(piece) => suggestPiece(partyId, piece)
 | 
			
		||||
      case _ => Future.failed(new Error(s"Could not construct piece from `$maybePiece`"))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object LootSuggestView {
 | 
			
		||||
  import scalatags.Text.all._
 | 
			
		||||
 | 
			
		||||
  def template(partyId: String, party: Seq[PlayerIdWithCounters], piece: Option[Piece], error: Option[String]): String =
 | 
			
		||||
    "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">" +
 | 
			
		||||
      html(lang:="en",
 | 
			
		||||
        head(
 | 
			
		||||
          title:="Suggest loot",
 | 
			
		||||
          link(rel:="stylesheet", `type`:="text/css", href:="/static/styles.css")
 | 
			
		||||
        ),
 | 
			
		||||
 | 
			
		||||
        body(
 | 
			
		||||
          h2("Suggest loot"),
 | 
			
		||||
 | 
			
		||||
          ErrorView.template(error),
 | 
			
		||||
          SearchLineView.template,
 | 
			
		||||
 | 
			
		||||
          form(action:=s"/party/$partyId/suggest", method:="post")(
 | 
			
		||||
            select(name:="piece", id:="piece", title:="piece")
 | 
			
		||||
                  (for (piece <- Piece.available) yield option(piece)),
 | 
			
		||||
            input(name:="is_tome", id:="is_tome", title:="is tome", `type`:="checkbox"),
 | 
			
		||||
            label(`for`:="is_tome")("is tome gear"),
 | 
			
		||||
            input(name:="suggest", id:="suggest", `type`:="submit", value:="suggest")
 | 
			
		||||
          ),
 | 
			
		||||
 | 
			
		||||
          table(id:="result")(
 | 
			
		||||
            tr(
 | 
			
		||||
              th("player"),
 | 
			
		||||
              th("is required"),
 | 
			
		||||
              th("these pieces looted"),
 | 
			
		||||
              th("total bis pieces looted"),
 | 
			
		||||
              th("total pieces looted"),
 | 
			
		||||
              th("")
 | 
			
		||||
            ),
 | 
			
		||||
            for (player <- party) yield tr(
 | 
			
		||||
              td(`class`:="include_search")(player.playerId.toString),
 | 
			
		||||
              td(player.isRequiredToString),
 | 
			
		||||
              td(player.lootCount),
 | 
			
		||||
              td(player.lootCountBiS),
 | 
			
		||||
              td(player.lootCountTotal),
 | 
			
		||||
              td(
 | 
			
		||||
                form(action:=s"/party/$partyId/loot", method:="post")(
 | 
			
		||||
                  input(name:="player", id:="player", `type`:="hidden", value:=player.playerId.toString),
 | 
			
		||||
                  input(name:="piece", id:="piece", `type`:="hidden", value:=piece.map(_.piece).getOrElse("")),
 | 
			
		||||
                  input(name:="is_tome", id:="is_tome", `type`:="hidden", value:=piece.map(_.isTomeToString).getOrElse("")),
 | 
			
		||||
                  input(name:="action", id:="action", `type`:="hidden", value:="add"),
 | 
			
		||||
                  input(name:="add", id:="add", `type`:="submit", value:="add")
 | 
			
		||||
                )
 | 
			
		||||
              )
 | 
			
		||||
            )
 | 
			
		||||
          ),
 | 
			
		||||
 | 
			
		||||
          ExportToCSVView.template,
 | 
			
		||||
          script(src:="/static/table_search.js", `type`:="text/javascript")
 | 
			
		||||
        )
 | 
			
		||||
      )
 | 
			
		||||
}
 | 
			
		||||
@ -23,7 +23,7 @@ class LootView (override val storage: ActorRef)(implicit timeout: Timeout)
 | 
			
		||||
          get {
 | 
			
		||||
            complete {
 | 
			
		||||
              loot(partyId, None).map { players =>
 | 
			
		||||
                LootView.template(partyId, players, Piece.available, None)
 | 
			
		||||
                LootView.template(partyId, players, None)
 | 
			
		||||
              }.map { text =>
 | 
			
		||||
                (StatusCodes.OK, RootView.toHtml(text))
 | 
			
		||||
              }
 | 
			
		||||
@ -53,8 +53,10 @@ class LootView (override val storage: ActorRef)(implicit timeout: Timeout)
 | 
			
		||||
                             maybePiece: String, maybeIsTome: Option[String],
 | 
			
		||||
                             action: String)
 | 
			
		||||
                            (implicit executionContext: ExecutionContext, timeout: Timeout): Future[Unit] = {
 | 
			
		||||
    import me.arcanis.ffxivbis.utils.Implicits._
 | 
			
		||||
 | 
			
		||||
    def getPiece(playerId: PlayerId) =
 | 
			
		||||
      Try(Piece(maybePiece, maybeIsTome.isDefined, playerId.job)).toOption
 | 
			
		||||
      Try(Piece(maybePiece, maybeIsTome, playerId.job)).toOption
 | 
			
		||||
 | 
			
		||||
    PlayerId(partyId, player) match {
 | 
			
		||||
      case Some(playerId) => (getPiece(playerId), action) match {
 | 
			
		||||
@ -70,7 +72,7 @@ class LootView (override val storage: ActorRef)(implicit timeout: Timeout)
 | 
			
		||||
object LootView {
 | 
			
		||||
  import scalatags.Text.all._
 | 
			
		||||
 | 
			
		||||
  def template(partyId: String, party: Seq[Player], pieces: Seq[String], error: Option[String]): String =
 | 
			
		||||
  def template(partyId: String, party: Seq[Player], error: Option[String]): String =
 | 
			
		||||
    "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">" +
 | 
			
		||||
      html(lang:="en",
 | 
			
		||||
        head(
 | 
			
		||||
@ -88,7 +90,7 @@ object LootView {
 | 
			
		||||
            select(name:="player", id:="player", title:="player")
 | 
			
		||||
                  (for (player <- party) yield option(player.playerId.toString)),
 | 
			
		||||
            select(name:="piece", id:="piece", title:="piece")
 | 
			
		||||
                  (for (piece <- pieces) yield option(piece)),
 | 
			
		||||
                  (for (piece <- Piece.available) yield option(piece)),
 | 
			
		||||
            input(name:="is_tome", id:="is_tome", title:="is tome", `type`:="checkbox"),
 | 
			
		||||
            label(`for`:="is_tome")("is tome gear"),
 | 
			
		||||
            input(name:="action", id:="action", `type`:="hidden", value:="add"),
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										124
									
								
								src/main/scala/me/arcanis/ffxivbis/http/view/PlayerView.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								src/main/scala/me/arcanis/ffxivbis/http/view/PlayerView.scala
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,124 @@
 | 
			
		||||
package me.arcanis.ffxivbis.http.view
 | 
			
		||||
 | 
			
		||||
import akka.actor.ActorRef
 | 
			
		||||
import akka.http.scaladsl.model.StatusCodes
 | 
			
		||||
import akka.http.scaladsl.server.Directives._
 | 
			
		||||
import akka.http.scaladsl.server.Route
 | 
			
		||||
import akka.util.Timeout
 | 
			
		||||
import me.arcanis.ffxivbis.http.{Authorization, PlayerHelper}
 | 
			
		||||
import me.arcanis.ffxivbis.models.{BiS, Job, Player, PlayerId, PlayerIdWithCounters}
 | 
			
		||||
 | 
			
		||||
import scala.concurrent.{ExecutionContext, Future}
 | 
			
		||||
 | 
			
		||||
class PlayerView(override val storage: ActorRef, ariyala: ActorRef)(implicit timeout: Timeout)
 | 
			
		||||
  extends PlayerHelper(storage, ariyala) with Authorization {
 | 
			
		||||
 | 
			
		||||
  def route: Route = getParty ~ modifyParty
 | 
			
		||||
 | 
			
		||||
  def getParty: Route =
 | 
			
		||||
    path("party" / Segment) { partyId: String =>
 | 
			
		||||
      extractExecutionContext { implicit executionContext =>
 | 
			
		||||
        authenticateBasicBCrypt(s"party $partyId", authGet(partyId)) { _ =>
 | 
			
		||||
          get {
 | 
			
		||||
            complete {
 | 
			
		||||
              getPlayers(partyId, None).map { players =>
 | 
			
		||||
                PlayerView.template(partyId, players.map(_.withCounters(None)), None)
 | 
			
		||||
              }.map { text =>
 | 
			
		||||
                (StatusCodes.OK, RootView.toHtml(text))
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  def modifyParty: Route =
 | 
			
		||||
    path("party" / Segment) { partyId: String =>
 | 
			
		||||
      extractExecutionContext { implicit executionContext =>
 | 
			
		||||
        authenticateBasicBCrypt(s"party $partyId", authPost(partyId)) { _ =>
 | 
			
		||||
          post {
 | 
			
		||||
            formFields("nick".as[String], "job".as[String], "priority".as[Int].?, "link".as[String].?, "action".as[String]) {
 | 
			
		||||
              (nick, job, maybePriority, maybeLink, action) =>
 | 
			
		||||
                onComplete(modifyPartyCall(partyId, nick, job, maybePriority, maybeLink, action)) {
 | 
			
		||||
                  case _ => redirect(s"/party/$partyId", StatusCodes.Found)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  private def modifyPartyCall(partyId: String, nick: String, job: String,
 | 
			
		||||
                              maybePriority: Option[Int], maybeLink: Option[String],
 | 
			
		||||
                              action: String)
 | 
			
		||||
                             (implicit executionContext: ExecutionContext, timeout: Timeout): Future[Unit] = {
 | 
			
		||||
    def maybePlayerId = PlayerId(partyId, Some(nick), Some(job))
 | 
			
		||||
    def player(playerId: PlayerId) =
 | 
			
		||||
      Player(partyId, playerId.job, playerId.nick, BiS(), Seq.empty, maybeLink, maybePriority.getOrElse(0))
 | 
			
		||||
 | 
			
		||||
    (action, maybePlayerId) match {
 | 
			
		||||
      case ("add", Some(playerId)) => addPlayer(player(playerId)).map(_ => ())
 | 
			
		||||
      case ("remove", Some(playerId)) => removePlayer(playerId).map(_ => ())
 | 
			
		||||
      case _ => Future.failed(new Error(s"Could not perform $action with $nick ($job)"))
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object PlayerView {
 | 
			
		||||
  import scalatags.Text.all._
 | 
			
		||||
 | 
			
		||||
  def template(partyId: String, party: Seq[PlayerIdWithCounters], error: Option[String]): String =
 | 
			
		||||
    "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">" +
 | 
			
		||||
      html(lang:="en",
 | 
			
		||||
        head(
 | 
			
		||||
          title:="Party",
 | 
			
		||||
          link(rel:="stylesheet", `type`:="text/css", href:="/static/styles.css")
 | 
			
		||||
        ),
 | 
			
		||||
 | 
			
		||||
        body(
 | 
			
		||||
          h2("Party"),
 | 
			
		||||
 | 
			
		||||
          ErrorView.template(error),
 | 
			
		||||
          SearchLineView.template,
 | 
			
		||||
 | 
			
		||||
          form(action:=s"/party/$partyId", method:="post")(
 | 
			
		||||
            input(name:="nick", id:="nick", placeholder:="nick", title:="nick", `type`:="nick"),
 | 
			
		||||
            select(name:="job", id:="job", title:="job")
 | 
			
		||||
                  (for (job <- Job.groupAll) yield option(job.toString)),
 | 
			
		||||
            input(name:="link", id:="link", placeholder:="player bis link", title:="link", `type`:="text"),
 | 
			
		||||
            input(name:="prioiry", id:="priority", placeholder:="priority", title:="priority", `type`:="number", value:="0"),
 | 
			
		||||
            input(name:="action", id:="action", `type`:="hidden", value:="add"),
 | 
			
		||||
            input(name:="add", id:="add", `type`:="submit", value:="add")
 | 
			
		||||
          ),
 | 
			
		||||
 | 
			
		||||
          table(id:="result")(
 | 
			
		||||
            tr(
 | 
			
		||||
              th("nick"),
 | 
			
		||||
              th("job"),
 | 
			
		||||
              th("total bis pieces looted"),
 | 
			
		||||
              th("total pieces looted"),
 | 
			
		||||
              th("priority"),
 | 
			
		||||
              th("")
 | 
			
		||||
            ),
 | 
			
		||||
            for (player <- party) yield tr(
 | 
			
		||||
              td(`class`:="include_search")(player.nick),
 | 
			
		||||
              td(`class`:="include_search")(player.job.toString),
 | 
			
		||||
              td(player.lootCountBiS),
 | 
			
		||||
              td(player.lootCountTotal),
 | 
			
		||||
              td(player.priority),
 | 
			
		||||
              td(
 | 
			
		||||
                form(action:=s"/party/$partyId", method:="post")(
 | 
			
		||||
                  input(name:="nick", id:="nick", `type`:="hidden", value:=player.nick),
 | 
			
		||||
                  input(name:="job", id:="job", `type`:="hidden", value:=player.job.toString),
 | 
			
		||||
                  input(name:="action", id:="action", `type`:="hidden", value:="remove"),
 | 
			
		||||
                  input(name:="remove", id:="remove", `type`:="submit", value:="x")
 | 
			
		||||
                )
 | 
			
		||||
              )
 | 
			
		||||
            )
 | 
			
		||||
          ),
 | 
			
		||||
 | 
			
		||||
          ExportToCSVView.template,
 | 
			
		||||
          script(src:="/static/table_search.js", `type`:="text/javascript")
 | 
			
		||||
        )
 | 
			
		||||
      )
 | 
			
		||||
}
 | 
			
		||||
@ -10,10 +10,12 @@ class RootView(storage: ActorRef, ariyala: ActorRef)(implicit timeout: Timeout)
 | 
			
		||||
 | 
			
		||||
  private val biSView = new BiSView(storage, ariyala)
 | 
			
		||||
  private val lootView = new LootView(storage)
 | 
			
		||||
  private val lootSuggestView = new LootSuggestView(storage)
 | 
			
		||||
  private val playerView = new PlayerView(storage, ariyala)
 | 
			
		||||
  private val userView = new UserView(storage)
 | 
			
		||||
 | 
			
		||||
  def route: Route =
 | 
			
		||||
    biSView.route ~ lootView.route ~ userView.route
 | 
			
		||||
    biSView.route ~ lootView.route ~ lootSuggestView.route ~ playerView.route ~ userView.route
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object RootView {
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,7 @@ import scala.util.Try
 | 
			
		||||
class UserView(override val storage: ActorRef)(implicit timeout: Timeout)
 | 
			
		||||
  extends UserHelper(storage) with Authorization {
 | 
			
		||||
 | 
			
		||||
  def route: Route = getUsers
 | 
			
		||||
  def route: Route = getUsers ~ modifyUsers
 | 
			
		||||
 | 
			
		||||
  def getUsers: Route =
 | 
			
		||||
    path("party" / Segment / "users") { partyId: String =>
 | 
			
		||||
@ -85,8 +85,8 @@ object UserView {
 | 
			
		||||
          SearchLineView.template,
 | 
			
		||||
 | 
			
		||||
          form(action:=s"/party/$partyId/users", method:="post")(
 | 
			
		||||
            input(name:="username", id:="username", title:="username", placeholder:="username", `type`:="text"),
 | 
			
		||||
            input(name:="password", id:="password", title:="password", placeholder:="password", `type`:="password"),
 | 
			
		||||
            input(name:="username", id:="username", placeholder:="username", title:="username", `type`:="text"),
 | 
			
		||||
            input(name:="password", id:="password", placeholder:="password", title:="password", `type`:="password"),
 | 
			
		||||
            select(name:="permission", id:="permission", title:="permission")(option("get"), option("post")),
 | 
			
		||||
            input(name:="action", id:="action", `type`:="hidden", value:="add"),
 | 
			
		||||
            input(name:="add", id:="add", `type`:="submit", value:="add")
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
package me.arcanis.ffxivbis.models
 | 
			
		||||
 | 
			
		||||
import scala.util.Try
 | 
			
		||||
import scala.util.matching.Regex
 | 
			
		||||
 | 
			
		||||
trait PlayerIdBase {
 | 
			
		||||
@ -14,13 +15,13 @@ case class PlayerId(partyId: String, job: Job.Job, nick: String) extends PlayerI
 | 
			
		||||
object PlayerId {
 | 
			
		||||
  def apply(partyId: String, maybeNick: Option[String], maybeJob: Option[String]): Option[PlayerId] =
 | 
			
		||||
    (maybeNick, maybeJob) match {
 | 
			
		||||
      case (Some(nick), Some(job)) => Some(PlayerId(partyId, Job.fromString(job), nick))
 | 
			
		||||
      case (Some(nick), Some(job)) => Try(PlayerId(partyId, Job.fromString(job), nick)).toOption
 | 
			
		||||
      case _ => None
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  private val prettyPlayerIdRegex: Regex = "^(.*) \\(([A-Z]{3})\\)$".r
 | 
			
		||||
  def apply(partyId: String, player: String): Option[PlayerId] = player match {
 | 
			
		||||
    case s"${prettyPlayerIdRegex(nick, job)}" => Some(PlayerId(partyId, Job.fromString(job), nick))
 | 
			
		||||
    case s"${prettyPlayerIdRegex(nick, job)}" => Try(PlayerId(partyId, Job.fromString(job), nick)).toOption
 | 
			
		||||
    case _ => None
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -12,10 +12,10 @@ case class PlayerIdWithCounters(partyId: String,
 | 
			
		||||
  extends PlayerIdBase {
 | 
			
		||||
  import PlayerIdWithCounters._
 | 
			
		||||
 | 
			
		||||
  def playerId: PlayerId = PlayerId(partyId, job, nick)
 | 
			
		||||
 | 
			
		||||
  def gt(that: PlayerIdWithCounters, orderBy: Seq[String]): Boolean =
 | 
			
		||||
    withCounters(orderBy) > that.withCounters(orderBy)
 | 
			
		||||
  def isRequiredToString: String = if (isRequired) "yes" else "no"
 | 
			
		||||
  def playerId: PlayerId = PlayerId(partyId, job, nick)
 | 
			
		||||
 | 
			
		||||
  private val counters: Map[String, Int] = Map(
 | 
			
		||||
    "isRequired" -> (if (isRequired) 1 else 0),
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,11 @@ import scala.concurrent.duration.FiniteDuration
 | 
			
		||||
import scala.language.implicitConversions
 | 
			
		||||
 | 
			
		||||
object Implicits {
 | 
			
		||||
  implicit def getBooleanFromOptionString(maybeYes: Option[String]): Boolean = maybeYes match {
 | 
			
		||||
    case Some("yes" | "on") => true
 | 
			
		||||
    case _ => false
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  implicit def getFiniteDuration(duration: Duration): Timeout =
 | 
			
		||||
    FiniteDuration(duration.toNanos, TimeUnit.NANOSECONDS)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user