From 816ef24136e3fe054892b78d66ed2b5e8d5c63f4 Mon Sep 17 00:00:00 2001 From: Claude Brisson Date: Wed, 21 Feb 2024 23:19:52 +0100 Subject: [PATCH] Fix country import; fix layout; bump to 0.3 --- api-webapp/pom.xml | 2 +- .../kotlin/org/jeudego/pairgoth/ext/OpenGotha.kt | 2 +- .../kotlin/org/jeudego/pairgoth/store/FileStore.kt | 13 ++++++++++--- .../store/{StoreImplementation.kt => IStore.kt} | 4 ++-- .../org/jeudego/pairgoth/store/MemoryStore.kt | 6 ++++-- .../main/kotlin/org/jeudego/pairgoth/store/Store.kt | 7 ++----- application/pom.xml | 2 +- pom.xml | 2 +- view-webapp/pom.xml | 2 +- .../org/jeudego/pairgoth/oauth/OAuthHelper.kt | 2 +- .../jeudego/pairgoth/ratings/EGFRatingsHandler.kt | 2 +- .../org/jeudego/pairgoth/util/CredentialsChecker.kt | 4 ++-- .../kotlin/org/jeudego/pairgoth/web/LoginServlet.kt | 6 +++--- view-webapp/src/main/sass/main.scss | 4 ++++ view-webapp/src/main/webapp/WEB-INF/translations/fr | 5 +++-- view-webapp/src/main/webapp/index.html | 4 ++-- .../src/main/webapp/js/tour-registration.inc.js | 1 + .../src/main/webapp/tour-registration.inc.html | 4 +++- webserver/pom.xml | 2 +- 19 files changed, 44 insertions(+), 30 deletions(-) rename api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/{StoreImplementation.kt => IStore.kt} (90%) diff --git a/api-webapp/pom.xml b/api-webapp/pom.xml index dae8fa6..aefa2a2 100644 --- a/api-webapp/pom.xml +++ b/api-webapp/pom.xml @@ -7,7 +7,7 @@ org.jeudego.pairgoth engine-parent - 0.2 + 0.3 api-webapp diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/ext/OpenGotha.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/ext/OpenGotha.kt index 1c759b4..7227d14 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/ext/OpenGotha.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/ext/OpenGotha.kt @@ -124,7 +124,7 @@ object OpenGotha { shortName = genParams.shortName, startDate = genParams.beginDate.toLocalDate(), endDate = genParams.endDate.toLocalDate(), - country = "FR", // no country in opengotha format + country = "fr", // no country in opengotha format location = genParams.location, online = genParams.isBInternet ?: false, timeSystem = when (genParams.complementaryTimeSystem) { diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/FileStore.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/FileStore.kt index 048ef9a..07c91e8 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/FileStore.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/FileStore.kt @@ -21,9 +21,10 @@ import kotlin.io.path.useDirectoryEntries 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" -class FileStore(pathStr: String): StoreImplementation { +class FileStore(pathStr: String): IStore { companion object { 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 timestamp: String get() = timestampFormat.format(Date()) } @@ -37,11 +38,17 @@ class FileStore(pathStr: String): StoreImplementation { _nextTournamentId.set(getTournaments().keys.maxOrNull() ?: 0.toID()) } - override fun getTournaments(): Map { + + private fun lastModified(path: Path) = displayFormat.format(Date(path.toFile().lastModified())) + + override fun getTournaments(): Map> { return path.useDirectoryEntries("*.tour") { entries -> entries.mapNotNull { entry -> 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() } } diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/StoreImplementation.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/IStore.kt similarity index 90% rename from api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/StoreImplementation.kt rename to api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/IStore.kt index 0a6ac83..4a2b8ad 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/StoreImplementation.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/IStore.kt @@ -8,13 +8,13 @@ internal val _nextTournamentId = AtomicInteger() internal val _nextPlayerId = AtomicInteger() internal val _nextGameId = AtomicInteger() -interface StoreImplementation { +interface IStore { val nextTournamentId get() = _nextTournamentId.incrementAndGet() val nextPlayerId get() = _nextPlayerId.incrementAndGet() val nextGameId get() = _nextGameId.incrementAndGet() - fun getTournaments(): Map + fun getTournaments(): Map> fun addTournament(tournament: Tournament<*>) fun getTournament(id: ID): Tournament<*>? fun replaceTournament(tournament: Tournament<*>) diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/MemoryStore.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/MemoryStore.kt index 4ff7387..c9a016c 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/MemoryStore.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/MemoryStore.kt @@ -3,10 +3,12 @@ package org.jeudego.pairgoth.store import org.jeudego.pairgoth.model.ID import org.jeudego.pairgoth.model.Tournament -class MemoryStore: StoreImplementation { +class MemoryStore: IStore { private val tournaments = mutableMapOf>() - override fun getTournaments(): Map = tournaments.mapValues { it.value.shortName } + override fun getTournaments(): Map> = tournaments.mapValues { + mapOf("name" to it.value.shortName) + } override fun addTournament(tournament: Tournament<*>) { if (tournaments.containsKey(tournament.id)) throw Error("tournament id #${tournament.id} already exists") diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/Store.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/Store.kt index 582e528..fd95cca 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/Store.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/store/Store.kt @@ -1,11 +1,8 @@ package org.jeudego.pairgoth.store -import org.jeudego.pairgoth.model.ID -import org.jeudego.pairgoth.model.Tournament 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") { "memory" -> MemoryStore() "file" -> { @@ -16,4 +13,4 @@ private fun createStoreImplementation(): StoreImplementation { } } -object Store: StoreImplementation by createStoreImplementation() +object Store: IStore by createStoreImplementation() diff --git a/application/pom.xml b/application/pom.xml index bcb0da6..2026a5a 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -4,7 +4,7 @@ org.jeudego.pairgoth engine-parent - 0.2 + 0.3 application pom diff --git a/pom.xml b/pom.xml index cc81844..307653f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.jeudego.pairgoth engine-parent - 0.2 + 0.3 pom diff --git a/view-webapp/pom.xml b/view-webapp/pom.xml index abc7851..666107d 100644 --- a/view-webapp/pom.xml +++ b/view-webapp/pom.xml @@ -7,7 +7,7 @@ org.jeudego.pairgoth engine-parent - 0.2 + 0.3 view-webapp diff --git a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/oauth/OAuthHelper.kt b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/oauth/OAuthHelper.kt index 02e02b6..09e22a0 100644 --- a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/oauth/OAuthHelper.kt +++ b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/oauth/OAuthHelper.kt @@ -48,7 +48,7 @@ abstract class OAuthHelper { protected abstract fun getUserInfosURL(accessToken: String): Pair> @Throws(IOException::class) - fun getUserInfos(accessToken: String): Json { + fun getUserInfos(accessToken: String): Json.Object { val (url, params) = getUserInfosURL(accessToken) return JsonApiClient.get(url, *params.toTypedArray()).asObject() } diff --git a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/ratings/EGFRatingsHandler.kt b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/ratings/EGFRatingsHandler.kt index 4fd955d..75c5128 100644 --- a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/ratings/EGFRatingsHandler.kt +++ b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/ratings/EGFRatingsHandler.kt @@ -21,7 +21,7 @@ object EGFRatingsHandler: RatingsHandler(RatingsManager.Ratings.EGF) { player["origin"] = "EGF" // override rank with rating equivalent 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" } } } } diff --git a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/util/CredentialsChecker.kt b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/util/CredentialsChecker.kt index 1a7f90d..99bffff 100644 --- a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/util/CredentialsChecker.kt +++ b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/util/CredentialsChecker.kt @@ -10,7 +10,7 @@ object CredentialsChecker { private const val CREDENTIALS_DB = "pairgoth.db" private val hasher = MessageDigest.getInstance("SHA-256") @OptIn(ExperimentalStdlibApi::class) - fun check(email: String, password: String): String? { + fun check(email: String, password: String): Json.Object? { initDatabase() val sha256 = hasher.digest(password.toByteArray(StandardCharsets.UTF_8)).toHexString() DriverManager.getConnection("jdbc:sqlite:$CREDENTIALS_DB").use { conn -> @@ -19,7 +19,7 @@ object CredentialsChecker { setString(1, email) setString(2, password) }.executeQuery() - return if (rs.next()) email else null + return if (rs.next()) Json.Object("email" to email) else null } } diff --git a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/web/LoginServlet.kt b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/web/LoginServlet.kt index 3188363..b57a4c1 100644 --- a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/web/LoginServlet.kt +++ b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/web/LoginServlet.kt @@ -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") - 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( payload.getString("email") ?: throw Error("Missing login field"), payload.getString("password") ?: throw Error("missing password field")) diff --git a/view-webapp/src/main/sass/main.scss b/view-webapp/src/main/sass/main.scss index 04ef24b..b04060b 100644 --- a/view-webapp/src/main/sass/main.scss +++ b/view-webapp/src/main/sass/main.scss @@ -77,6 +77,10 @@ /* align-items: center; */ margin-left: auto; margin-right: auto; + > .section { + margin-left: auto; + margin-right: auto; + } } } diff --git a/view-webapp/src/main/webapp/WEB-INF/translations/fr b/view-webapp/src/main/webapp/WEB-INF/translations/fr index ea2a3b8..0e6eb5b 100644 --- a/view-webapp/src/main/webapp/WEB-INF/translations/fr +++ b/view-webapp/src/main/webapp/WEB-INF/translations/fr @@ -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 ! , 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 ! -.ui.form input[type=checkbox][name=online] { vertical-align: initial; } +, last modified , dernière modification : 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 : This mode allows you to run : Ce mode vous permet de lancer @@ -37,6 +37,7 @@ Export Exporter Export tournament Exporter le tournoi Family name Nom de famille Filter Filtrer +Filter... Filtrer… First name Prénom Fischer timing Cadence Fischer French rules Règles françaises @@ -93,7 +94,7 @@ Results for round Résultats pour la ronde Round-robin Toutes rondes Rounds Rondes Rules Règles -Search... Chercher… +Search... Chercher… Short name Nom de code Since the project is still in beta, the sources are only available to FFG actors. If that's your case, you can access the sources here: Comme le projet est encore en beta, les sources sont seulement accessibles aux acteurs FFG. Si c’est votre cas, vous pouvez accéder aux sources ici : Split and fold Couper-plier diff --git a/view-webapp/src/main/webapp/index.html b/view-webapp/src/main/webapp/index.html index 64fde18..7785564 100644 --- a/view-webapp/src/main/webapp/index.html +++ b/view-webapp/src/main/webapp/index.html @@ -23,9 +23,9 @@ #else #foreach($tour in $files.entrySet()) - + - $tour.value + $tour.value.name #end #end diff --git a/view-webapp/src/main/webapp/js/tour-registration.inc.js b/view-webapp/src/main/webapp/js/tour-registration.inc.js index 3e4fa7f..4c646d6 100644 --- a/view-webapp/src/main/webapp/js/tour-registration.inc.js +++ b/view-webapp/src/main/webapp/js/tour-registration.inc.js @@ -40,6 +40,7 @@ function search(needle) { store('searchFormState', searchFormState); api.postJson('search', search) .then(result => { + console.log(result) if (Array.isArray(result)) { searchResult = result let html = resultTemplate.render(result); diff --git a/view-webapp/src/main/webapp/tour-registration.inc.html b/view-webapp/src/main/webapp/tour-registration.inc.html index 92d3dba..894c557 100644 --- a/view-webapp/src/main/webapp/tour-registration.inc.html +++ b/view-webapp/src/main/webapp/tour-registration.inc.html @@ -4,7 +4,7 @@
- +
@@ -73,6 +73,7 @@