Fix country import; fix layout; bump to 0.3
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.jeudego.pairgoth</groupId>
|
<groupId>org.jeudego.pairgoth</groupId>
|
||||||
<artifactId>engine-parent</artifactId>
|
<artifactId>engine-parent</artifactId>
|
||||||
<version>0.2</version>
|
<version>0.3</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>api-webapp</artifactId>
|
<artifactId>api-webapp</artifactId>
|
||||||
|
|
||||||
|
@@ -124,7 +124,7 @@ object OpenGotha {
|
|||||||
shortName = genParams.shortName,
|
shortName = genParams.shortName,
|
||||||
startDate = genParams.beginDate.toLocalDate(),
|
startDate = genParams.beginDate.toLocalDate(),
|
||||||
endDate = genParams.endDate.toLocalDate(),
|
endDate = genParams.endDate.toLocalDate(),
|
||||||
country = "FR", // no country in opengotha format
|
country = "fr", // no country in opengotha format
|
||||||
location = genParams.location,
|
location = genParams.location,
|
||||||
online = genParams.isBInternet ?: false,
|
online = genParams.isBInternet ?: false,
|
||||||
timeSystem = when (genParams.complementaryTimeSystem) {
|
timeSystem = when (genParams.complementaryTimeSystem) {
|
||||||
|
@@ -21,9 +21,10 @@ import kotlin.io.path.useDirectoryEntries
|
|||||||
private const val LEFT_PAD = 6 // left padding of IDs with '0' in filename
|
private const val LEFT_PAD = 6 // left padding of IDs with '0' in filename
|
||||||
private fun Tournament<*>.filename() = "${id.toString().padStart(LEFT_PAD, '0')}-${shortName}.tour"
|
private fun Tournament<*>.filename() = "${id.toString().padStart(LEFT_PAD, '0')}-${shortName}.tour"
|
||||||
|
|
||||||
class FileStore(pathStr: String): StoreImplementation {
|
class FileStore(pathStr: String): IStore {
|
||||||
companion object {
|
companion object {
|
||||||
private val filenameRegex = Regex("^(\\d+)-(.*)\\.tour$")
|
private val filenameRegex = Regex("^(\\d+)-(.*)\\.tour$")
|
||||||
|
private val displayFormat: DateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
|
||||||
private val timestampFormat: DateFormat = SimpleDateFormat("yyyyMMddHHmmss")
|
private val timestampFormat: DateFormat = SimpleDateFormat("yyyyMMddHHmmss")
|
||||||
private val timestamp: String get() = timestampFormat.format(Date())
|
private val timestamp: String get() = timestampFormat.format(Date())
|
||||||
}
|
}
|
||||||
@@ -37,11 +38,17 @@ class FileStore(pathStr: String): StoreImplementation {
|
|||||||
_nextTournamentId.set(getTournaments().keys.maxOrNull() ?: 0.toID())
|
_nextTournamentId.set(getTournaments().keys.maxOrNull() ?: 0.toID())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTournaments(): Map<ID, String> {
|
|
||||||
|
private fun lastModified(path: Path) = displayFormat.format(Date(path.toFile().lastModified()))
|
||||||
|
|
||||||
|
override fun getTournaments(): Map<ID, Map<String, String>> {
|
||||||
return path.useDirectoryEntries("*.tour") { entries ->
|
return path.useDirectoryEntries("*.tour") { entries ->
|
||||||
entries.mapNotNull { entry ->
|
entries.mapNotNull { entry ->
|
||||||
val match = filenameRegex.matchEntire(entry.fileName.toString())
|
val match = filenameRegex.matchEntire(entry.fileName.toString())
|
||||||
match?.let { Pair(it.groupValues[1].toID(), it.groupValues[2]) }
|
match?.let { Pair(it.groupValues[1].toID(), mapOf(
|
||||||
|
"name" to it.groupValues[2],
|
||||||
|
"lastModified" to lastModified(entry))
|
||||||
|
) }
|
||||||
}.sortedBy { it.first }.toMap()
|
}.sortedBy { it.first }.toMap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,13 +8,13 @@ internal val _nextTournamentId = AtomicInteger()
|
|||||||
internal val _nextPlayerId = AtomicInteger()
|
internal val _nextPlayerId = AtomicInteger()
|
||||||
internal val _nextGameId = AtomicInteger()
|
internal val _nextGameId = AtomicInteger()
|
||||||
|
|
||||||
interface StoreImplementation {
|
interface IStore {
|
||||||
|
|
||||||
val nextTournamentId get() = _nextTournamentId.incrementAndGet()
|
val nextTournamentId get() = _nextTournamentId.incrementAndGet()
|
||||||
val nextPlayerId get() = _nextPlayerId.incrementAndGet()
|
val nextPlayerId get() = _nextPlayerId.incrementAndGet()
|
||||||
val nextGameId get() = _nextGameId.incrementAndGet()
|
val nextGameId get() = _nextGameId.incrementAndGet()
|
||||||
|
|
||||||
fun getTournaments(): Map<ID, String>
|
fun getTournaments(): Map<ID, Map<String, String>>
|
||||||
fun addTournament(tournament: Tournament<*>)
|
fun addTournament(tournament: Tournament<*>)
|
||||||
fun getTournament(id: ID): Tournament<*>?
|
fun getTournament(id: ID): Tournament<*>?
|
||||||
fun replaceTournament(tournament: Tournament<*>)
|
fun replaceTournament(tournament: Tournament<*>)
|
@@ -3,10 +3,12 @@ package org.jeudego.pairgoth.store
|
|||||||
import org.jeudego.pairgoth.model.ID
|
import org.jeudego.pairgoth.model.ID
|
||||||
import org.jeudego.pairgoth.model.Tournament
|
import org.jeudego.pairgoth.model.Tournament
|
||||||
|
|
||||||
class MemoryStore: StoreImplementation {
|
class MemoryStore: IStore {
|
||||||
private val tournaments = mutableMapOf<ID, Tournament<*>>()
|
private val tournaments = mutableMapOf<ID, Tournament<*>>()
|
||||||
|
|
||||||
override fun getTournaments(): Map<ID, String> = tournaments.mapValues { it.value.shortName }
|
override fun getTournaments(): Map<ID, Map<String, String>> = tournaments.mapValues {
|
||||||
|
mapOf("name" to it.value.shortName)
|
||||||
|
}
|
||||||
|
|
||||||
override fun addTournament(tournament: Tournament<*>) {
|
override fun addTournament(tournament: Tournament<*>) {
|
||||||
if (tournaments.containsKey(tournament.id)) throw Error("tournament id #${tournament.id} already exists")
|
if (tournaments.containsKey(tournament.id)) throw Error("tournament id #${tournament.id} already exists")
|
||||||
|
@@ -1,11 +1,8 @@
|
|||||||
package org.jeudego.pairgoth.store
|
package org.jeudego.pairgoth.store
|
||||||
|
|
||||||
import org.jeudego.pairgoth.model.ID
|
|
||||||
import org.jeudego.pairgoth.model.Tournament
|
|
||||||
import org.jeudego.pairgoth.server.WebappManager
|
import org.jeudego.pairgoth.server.WebappManager
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
|
||||||
|
|
||||||
private fun createStoreImplementation(): StoreImplementation {
|
private fun createStoreImplementation(): IStore {
|
||||||
return when (val storeProperty = WebappManager.getProperty("store") ?: "memory") {
|
return when (val storeProperty = WebappManager.getProperty("store") ?: "memory") {
|
||||||
"memory" -> MemoryStore()
|
"memory" -> MemoryStore()
|
||||||
"file" -> {
|
"file" -> {
|
||||||
@@ -16,4 +13,4 @@ private fun createStoreImplementation(): StoreImplementation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object Store: StoreImplementation by createStoreImplementation()
|
object Store: IStore by createStoreImplementation()
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.jeudego.pairgoth</groupId>
|
<groupId>org.jeudego.pairgoth</groupId>
|
||||||
<artifactId>engine-parent</artifactId>
|
<artifactId>engine-parent</artifactId>
|
||||||
<version>0.2</version>
|
<version>0.3</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>application</artifactId>
|
<artifactId>application</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
2
pom.xml
2
pom.xml
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<groupId>org.jeudego.pairgoth</groupId>
|
<groupId>org.jeudego.pairgoth</groupId>
|
||||||
<artifactId>engine-parent</artifactId>
|
<artifactId>engine-parent</artifactId>
|
||||||
<version>0.2</version>
|
<version>0.3</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<!-- CB: Temporary add my repository, while waiting for SSE Java server module author to incorporate my PR or for me to fork it -->
|
<!-- CB: Temporary add my repository, while waiting for SSE Java server module author to incorporate my PR or for me to fork it -->
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.jeudego.pairgoth</groupId>
|
<groupId>org.jeudego.pairgoth</groupId>
|
||||||
<artifactId>engine-parent</artifactId>
|
<artifactId>engine-parent</artifactId>
|
||||||
<version>0.2</version>
|
<version>0.3</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>view-webapp</artifactId>
|
<artifactId>view-webapp</artifactId>
|
||||||
|
|
||||||
|
@@ -48,7 +48,7 @@ abstract class OAuthHelper {
|
|||||||
protected abstract fun getUserInfosURL(accessToken: String): Pair<String, List<NameValuePair>>
|
protected abstract fun getUserInfosURL(accessToken: String): Pair<String, List<NameValuePair>>
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun getUserInfos(accessToken: String): Json {
|
fun getUserInfos(accessToken: String): Json.Object {
|
||||||
val (url, params) = getUserInfosURL(accessToken)
|
val (url, params) = getUserInfosURL(accessToken)
|
||||||
return JsonApiClient.get(url, *params.toTypedArray()).asObject()
|
return JsonApiClient.get(url, *params.toTypedArray()).asObject()
|
||||||
}
|
}
|
||||||
|
@@ -21,7 +21,7 @@ object EGFRatingsHandler: RatingsHandler(RatingsManager.Ratings.EGF) {
|
|||||||
player["origin"] = "EGF"
|
player["origin"] = "EGF"
|
||||||
// override rank with rating equivalent
|
// override rank with rating equivalent
|
||||||
player["rating"]?.toString()?.toIntOrNull()?.let { rating ->
|
player["rating"]?.toString()?.toIntOrNull()?.let { rating ->
|
||||||
player["rank"] = ((rating - 2050)/100).let { if (rating < 0) "${-it+1}k" else "${it+1}d" }
|
player["rank"] = ((rating - 2050)/100).let { if (it < 0) "${-it+1}k" else "${it+1}d" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,7 @@ object CredentialsChecker {
|
|||||||
private const val CREDENTIALS_DB = "pairgoth.db"
|
private const val CREDENTIALS_DB = "pairgoth.db"
|
||||||
private val hasher = MessageDigest.getInstance("SHA-256")
|
private val hasher = MessageDigest.getInstance("SHA-256")
|
||||||
@OptIn(ExperimentalStdlibApi::class)
|
@OptIn(ExperimentalStdlibApi::class)
|
||||||
fun check(email: String, password: String): String? {
|
fun check(email: String, password: String): Json.Object? {
|
||||||
initDatabase()
|
initDatabase()
|
||||||
val sha256 = hasher.digest(password.toByteArray(StandardCharsets.UTF_8)).toHexString()
|
val sha256 = hasher.digest(password.toByteArray(StandardCharsets.UTF_8)).toHexString()
|
||||||
DriverManager.getConnection("jdbc:sqlite:$CREDENTIALS_DB").use { conn ->
|
DriverManager.getConnection("jdbc:sqlite:$CREDENTIALS_DB").use { conn ->
|
||||||
@@ -19,7 +19,7 @@ object CredentialsChecker {
|
|||||||
setString(1, email)
|
setString(1, email)
|
||||||
setString(2, password)
|
setString(2, password)
|
||||||
}.executeQuery()
|
}.executeQuery()
|
||||||
return if (rs.next()) email else null
|
return if (rs.next()) Json.Object("email" to email) else null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,12 +32,12 @@ class LoginServlet: HttpServlet() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkSesame(payload: Json.Object): Boolean? {
|
fun checkSesame(payload: Json.Object): Json.Object? {
|
||||||
val expected = WebappManager.getProperty("auth.sesame") ?: throw Error("sesame wrongly configured")
|
val expected = WebappManager.getProperty("auth.sesame") ?: throw Error("sesame wrongly configured")
|
||||||
return if (payload.getString("sesame")?.equals(expected) == true) true else null
|
return if (payload.getString("sesame")?.equals(expected) == true) Json.Object("logged" to true) else null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkLoginPass(payload: Json.Object): String? {
|
fun checkLoginPass(payload: Json.Object): Json.Object? {
|
||||||
return CredentialsChecker.check(
|
return CredentialsChecker.check(
|
||||||
payload.getString("email") ?: throw Error("Missing login field"),
|
payload.getString("email") ?: throw Error("Missing login field"),
|
||||||
payload.getString("password") ?: throw Error("missing password field"))
|
payload.getString("password") ?: throw Error("missing password field"))
|
||||||
|
@@ -77,6 +77,10 @@
|
|||||||
/* align-items: center; */
|
/* align-items: center; */
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
|
> .section {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
, allowing you to tweak it in any possible way. Be sure to contribute back your enhancements! , vous permettant de complètement le modifier. N’oubliez pas de partager vos améliorations !
|
, allowing you to tweak it in any possible way. Be sure to contribute back your enhancements! , vous permettant de complètement le modifier. N’oubliez pas de partager vos améliorations !
|
||||||
, the well known pairing system software developed by , le logiciel d’appariement très connu développé par
|
, the well known pairing system software developed by , le logiciel d’appariement très connu développé par
|
||||||
, your Go Pairing Engine! , votre logiciel d’appariement de Go !
|
, your Go Pairing Engine! , votre logiciel d’appariement de Go !
|
||||||
.ui.form input[type=checkbox][name=online] { vertical-align: initial; }
|
, last modified , dernière modification :
|
||||||
1st round seeding méthode 1è ronde
|
1st round seeding méthode 1è ronde
|
||||||
: If you prefer convenience, you can simply use the : Si vous préférez la commodité, vous pouvez simplement utiliser l’instance
|
: If you prefer convenience, you can simply use the : Si vous préférez la commodité, vous pouvez simplement utiliser l’instance
|
||||||
: This mode allows you to run : Ce mode vous permet de lancer
|
: This mode allows you to run : Ce mode vous permet de lancer
|
||||||
@@ -37,6 +37,7 @@ Export Exporter
|
|||||||
Export tournament Exporter le tournoi
|
Export tournament Exporter le tournoi
|
||||||
Family name Nom de famille
|
Family name Nom de famille
|
||||||
Filter Filtrer
|
Filter Filtrer
|
||||||
|
Filter... Filtrer…
|
||||||
First name Prénom
|
First name Prénom
|
||||||
Fischer timing Cadence Fischer
|
Fischer timing Cadence Fischer
|
||||||
French rules Règles françaises
|
French rules Règles françaises
|
||||||
|
@@ -23,9 +23,9 @@
|
|||||||
</script>
|
</script>
|
||||||
#else
|
#else
|
||||||
#foreach($tour in $files.entrySet())
|
#foreach($tour in $files.entrySet())
|
||||||
<a href="tour?id=${tour.key}" class="ui open basic secondary white icon floating button">
|
<a href="tour?id=${tour.key}" class="ui open basic secondary white icon floating button" title="id $tour.key, last modified $tour.value.lastModified">
|
||||||
<i class="fa fa-folder-open-o"></i>
|
<i class="fa fa-folder-open-o"></i>
|
||||||
$tour.value
|
$tour.value.name
|
||||||
</a>
|
</a>
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
@@ -40,6 +40,7 @@ function search(needle) {
|
|||||||
store('searchFormState', searchFormState);
|
store('searchFormState', searchFormState);
|
||||||
api.postJson('search', search)
|
api.postJson('search', search)
|
||||||
.then(result => {
|
.then(result => {
|
||||||
|
console.log(result)
|
||||||
if (Array.isArray(result)) {
|
if (Array.isArray(result)) {
|
||||||
searchResult = result
|
searchResult = result
|
||||||
let html = resultTemplate.render(result);
|
let html = resultTemplate.render(result);
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
<div id="reg-view">
|
<div id="reg-view">
|
||||||
<div id="list-header">
|
<div id="list-header">
|
||||||
<div id="filter-box" class="ui icon input">
|
<div id="filter-box" class="ui icon input">
|
||||||
<input type="text" id="filter" placeholder="Search..."/>
|
<input type="text" id="filter" placeholder="Filter..."/>
|
||||||
<i class="circular times link icon"></i>
|
<i class="circular times link icon"></i>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -73,6 +73,7 @@
|
|||||||
<input type="hidden" name="id"/>
|
<input type="hidden" name="id"/>
|
||||||
<div class="popup-content">
|
<div class="popup-content">
|
||||||
<div id="search-form" class="five stackable fields">
|
<div id="search-form" class="five stackable fields">
|
||||||
|
#if($tour.country)
|
||||||
<div class="two wide field">
|
<div class="two wide field">
|
||||||
<div class="toggle">
|
<div class="toggle">
|
||||||
<input id="countryFilter" name="countryFilter" type="checkbox" value="$tour.country"/>
|
<input id="countryFilter" name="countryFilter" type="checkbox" value="$tour.country"/>
|
||||||
@@ -82,6 +83,7 @@
|
|||||||
<label>$tour.country.toUpperCase()</label>
|
<label>$tour.country.toUpperCase()</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
#end
|
||||||
<div class="ten wide field">
|
<div class="ten wide field">
|
||||||
<div class="ui icon input">
|
<div class="ui icon input">
|
||||||
<input id="needle" name="needle" type="text" placeholder="Search...">
|
<input id="needle" name="needle" type="text" placeholder="Search...">
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.jeudego.pairgoth</groupId>
|
<groupId>org.jeudego.pairgoth</groupId>
|
||||||
<artifactId>engine-parent</artifactId>
|
<artifactId>engine-parent</artifactId>
|
||||||
<version>0.2</version>
|
<version>0.3</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>webserver</artifactId>
|
<artifactId>webserver</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
Reference in New Issue
Block a user