forked from SteamWar/SteamWar
Refactor page routing and point calculation logic
Streamlined the `page` routing structure by optimizing branch and file handling, introducing a reusable `filesInDirectory` method, and cleaning up redundancies. Enhanced `EventGroup` point calculation with incremental updates, new helper methods (`getTeams`, `getTeamsId`), and better handling of unfinished fights.
This commit is contained in:
@@ -23,10 +23,9 @@ import de.steamwar.sql.internal.*;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.stream.Collectors;
|
||||||
import java.util.Map;
|
import java.util.stream.Stream;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@@ -94,6 +93,15 @@ public class EventGroup {
|
|||||||
return EventFight.get(this);
|
return EventFight.get(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<Integer> getTeamsId() {
|
||||||
|
return getFights().stream().flatMap(fight -> Stream.of(fight.getTeamBlue(), fight.getTeamRed()))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Team> getTeams() {
|
||||||
|
return getTeamsId().stream().map(Team::get).collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
public Optional<EventFight> getLastFight() {
|
public Optional<EventFight> getLastFight() {
|
||||||
return EventFight.getLast(this);
|
return EventFight.getLast(this);
|
||||||
}
|
}
|
||||||
@@ -104,13 +112,16 @@ public class EventGroup {
|
|||||||
|
|
||||||
public Map<Team, Integer> calculatePoints() {
|
public Map<Team, Integer> calculatePoints() {
|
||||||
if (points == null) {
|
if (points == null) {
|
||||||
Map<Integer, Team> teams = new HashMap<>();
|
Map<Integer, Integer> p = getTeamsId().stream().collect(Collectors.toMap(team -> team, team -> 0));
|
||||||
points = new HashMap<>();
|
|
||||||
|
|
||||||
for (EventFight fight : getFights()) {
|
for (EventFight fight : getFights()) {
|
||||||
int blueTeamAdd = 0;
|
int blueTeamAdd = 0;
|
||||||
int redTeamAdd = 0;
|
int redTeamAdd = 0;
|
||||||
|
|
||||||
|
if (!fight.hasFinished()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch (fight.getErgebnis()) {
|
switch (fight.getErgebnis()) {
|
||||||
case 1:
|
case 1:
|
||||||
blueTeamAdd += pointsPerWin;
|
blueTeamAdd += pointsPerWin;
|
||||||
@@ -128,19 +139,18 @@ public class EventGroup {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Team blueTeam = teams.computeIfAbsent(fight.getTeamBlue(), Team::get);
|
p.put(fight.getTeamBlue(), p.get(fight.getTeamBlue()) + blueTeamAdd);
|
||||||
Team redTeam = teams.computeIfAbsent(fight.getTeamRed(), Team::get);
|
p.put(fight.getTeamRed(), p.get(fight.getTeamRed()) + redTeamAdd);
|
||||||
|
|
||||||
points.put(blueTeam, points.getOrDefault(blueTeam, 0) + blueTeamAdd);
|
|
||||||
points.put(redTeam, points.getOrDefault(redTeam, 0) + redTeamAdd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
points = p.entrySet().stream().collect(Collectors.toMap(integerIntegerEntry -> Team.get(integerIntegerEntry.getKey()), Map.Entry::getValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(String name, EventGroupType type, int pointsPerWin, int pointsPerLoss, int pointsPerDraw) {
|
public void update(String name, EventGroupType type, int pointsPerWin, int pointsPerLoss, int pointsPerDraw) {
|
||||||
update.update(id, name, type, pointsPerWin, pointsPerLoss, pointsPerDraw);
|
update.update(name, type, pointsPerWin, pointsPerLoss, pointsPerDraw, id);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.pointsPerWin = pointsPerWin;
|
this.pointsPerWin = pointsPerWin;
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ data class ResponseEventFight(
|
|||||||
val start: Long,
|
val start: Long,
|
||||||
val ergebnis: Int,
|
val ergebnis: Int,
|
||||||
val spectatePort: Int?,
|
val spectatePort: Int?,
|
||||||
val group: ResponseGroups?
|
val group: ResponseGroups?,
|
||||||
|
val hasFinished: Boolean
|
||||||
) {
|
) {
|
||||||
constructor(eventFight: EventFight) : this(
|
constructor(eventFight: EventFight) : this(
|
||||||
eventFight.fightID,
|
eventFight.fightID,
|
||||||
@@ -51,7 +52,8 @@ data class ResponseEventFight(
|
|||||||
eventFight.startTime.time,
|
eventFight.startTime.time,
|
||||||
eventFight.ergebnis,
|
eventFight.ergebnis,
|
||||||
eventFight.spectatePort,
|
eventFight.spectatePort,
|
||||||
eventFight.group.orElse(null)?.let { ResponseGroups(it) }
|
eventFight.group.orElse(null)?.let { ResponseGroups(it, short = true) },
|
||||||
|
eventFight.hasFinished()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import de.steamwar.plugins.SWAuthPrincipal
|
|||||||
import de.steamwar.plugins.SWPermissionCheck
|
import de.steamwar.plugins.SWPermissionCheck
|
||||||
import de.steamwar.sql.UserPerm
|
import de.steamwar.sql.UserPerm
|
||||||
import io.ktor.client.*
|
import io.ktor.client.*
|
||||||
import io.ktor.client.call.*
|
|
||||||
import io.ktor.client.engine.java.*
|
import io.ktor.client.engine.java.*
|
||||||
import io.ktor.client.plugins.*
|
import io.ktor.client.plugins.*
|
||||||
import io.ktor.client.plugins.contentnegotiation.*
|
import io.ktor.client.plugins.contentnegotiation.*
|
||||||
@@ -37,9 +36,7 @@ import io.ktor.server.auth.*
|
|||||||
import io.ktor.server.request.*
|
import io.ktor.server.request.*
|
||||||
import io.ktor.server.response.*
|
import io.ktor.server.response.*
|
||||||
import io.ktor.server.routing.*
|
import io.ktor.server.routing.*
|
||||||
import io.ktor.util.reflect.*
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.encodeToString
|
|
||||||
import kotlinx.serialization.json.*
|
import kotlinx.serialization.json.*
|
||||||
import java.util.Base64
|
import java.util.Base64
|
||||||
|
|
||||||
@@ -113,65 +110,42 @@ fun Route.configurePage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun filesInDirectory(path: String, branch: String = "master", fileFilter: (name: String) -> Boolean = { true }): List<PageResponseList> {
|
||||||
|
val filesToCheck = mutableListOf(path)
|
||||||
|
val files = mutableListOf<PageResponseList>()
|
||||||
|
|
||||||
|
while (filesToCheck.isNotEmpty()) {
|
||||||
|
val path = filesToCheck.removeAt(0)
|
||||||
|
val res = client.get("repos/SteamWar/Website/contents/$path?ref=$branch")
|
||||||
|
val fileJson = Json.parseToJsonElement(res.bodyAsText())
|
||||||
|
|
||||||
|
if (fileJson is JsonArray) {
|
||||||
|
fileJson.forEach {
|
||||||
|
val obj = it.jsonObject
|
||||||
|
if (obj["type"]?.jsonPrimitive?.content == "dir") {
|
||||||
|
filesToCheck.add(obj["path"]?.jsonPrimitive?.content!!)
|
||||||
|
} else if (obj["type"]?.jsonPrimitive?.content == "file" && fileFilter(obj["name"]!!.jsonPrimitive.content)) {
|
||||||
|
files.add(PageResponseList(obj, pathPageIdMap.computeIfAbsent(obj["path"]?.jsonPrimitive?.content!!) { pageId++ }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
files.add(PageResponseList(fileJson.jsonObject, pathPageIdMap.computeIfAbsent(fileJson.jsonObject["path"]?.jsonPrimitive?.content!!) { pageId++ }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return files
|
||||||
|
}
|
||||||
|
|
||||||
route("page") {
|
route("page") {
|
||||||
install(SWPermissionCheck) {
|
install(SWPermissionCheck) {
|
||||||
permission = UserPerm.MODERATION
|
permission = UserPerm.MODERATION
|
||||||
}
|
}
|
||||||
get {
|
get {
|
||||||
val branch = call.request.queryParameters["branch"] ?: "master"
|
val branch = call.request.queryParameters["branch"] ?: "master"
|
||||||
val filesToCheck = mutableListOf("src/content")
|
|
||||||
val files = mutableListOf<PageResponseList>()
|
|
||||||
|
|
||||||
while (filesToCheck.isNotEmpty()) {
|
call.respond(filesInDirectory("/src/content", branch) {
|
||||||
val path = filesToCheck.removeAt(0)
|
it.endsWith(".md") || it.endsWith(".json")
|
||||||
val res = client.get("repos/SteamWar/Website/contents/$path?ref=$branch")
|
})
|
||||||
val fileJson = Json.parseToJsonElement(res.bodyAsText())
|
|
||||||
|
|
||||||
if (fileJson is JsonArray) {
|
|
||||||
fileJson.forEach {
|
|
||||||
val obj = it.jsonObject
|
|
||||||
if (obj["type"]?.jsonPrimitive?.content == "dir") {
|
|
||||||
filesToCheck.add(obj["path"]?.jsonPrimitive?.content!!)
|
|
||||||
} else if (obj["type"]?.jsonPrimitive?.content == "file" && (obj["name"]?.jsonPrimitive?.content?.endsWith(".md") == true || obj["name"]?.jsonPrimitive?.content?.endsWith(".json") == true)) {
|
|
||||||
files.add(PageResponseList(obj, pathPageIdMap.computeIfAbsent(obj["path"]?.jsonPrimitive?.content!!) { pageId++ }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
files.add(PageResponseList(fileJson.jsonObject, pathPageIdMap.computeIfAbsent(fileJson.jsonObject["path"]?.jsonPrimitive?.content!!) { pageId++ }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
call.respond(files)
|
|
||||||
}
|
|
||||||
get("branch") {
|
|
||||||
val res = client.get("repos/SteamWar/Website/branches")
|
|
||||||
call.respond(res.status, Json.parseToJsonElement(res.bodyAsText()).jsonArray.map { it.jsonObject["name"]?.jsonPrimitive?.content!! })
|
|
||||||
}
|
|
||||||
post("branch") {
|
|
||||||
@Serializable
|
|
||||||
data class CreateGiteaBranchRequest(val new_branch_name: String, val old_branch_name: String)
|
|
||||||
|
|
||||||
val branch = call.receive<CreateBranchRequest>().branch
|
|
||||||
val res = client.post("repos/SteamWar/Website/branches") {
|
|
||||||
contentType(ContentType.Application.Json)
|
|
||||||
setBody(CreateGiteaBranchRequest(branch, "master"))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class CreateGiteaMergeRequest(val base: String, val head: String, val title: String)
|
|
||||||
|
|
||||||
client.post("repos/SteamWar/Website/pulls") {
|
|
||||||
contentType(ContentType.Application.Json)
|
|
||||||
setBody(CreateGiteaMergeRequest("master", branch, "Merge branch $branch"))
|
|
||||||
}
|
|
||||||
|
|
||||||
call.respond(res.status)
|
|
||||||
}
|
|
||||||
delete("branch") {
|
|
||||||
val branch = call.receive<CreateBranchRequest>().branch
|
|
||||||
val res = client.delete("repos/SteamWar/Website/branches/$branch")
|
|
||||||
call.respond(res.status)
|
|
||||||
}
|
}
|
||||||
post {
|
post {
|
||||||
@Serializable
|
@Serializable
|
||||||
@@ -197,55 +171,94 @@ fun Route.configurePage() {
|
|||||||
""".trimIndent().toByteArray()),
|
""".trimIndent().toByteArray()),
|
||||||
call.request.queryParameters["branch"] ?: "master",
|
call.request.queryParameters["branch"] ?: "master",
|
||||||
Identity(call.principal<SWAuthPrincipal>()!!.user.userName, "admin-tool@steamwar.de"
|
Identity(call.principal<SWAuthPrincipal>()!!.user.userName, "admin-tool@steamwar.de"
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
call.respond(res.status)
|
call.respond(res.status)
|
||||||
}
|
}
|
||||||
get("{id}") {
|
route("branch") {
|
||||||
val id = call.parameters["id"]?.toIntOrNull() ?: return@get call.respond(HttpStatusCode.BadRequest, "Invalid id")
|
get {
|
||||||
val path = pathPageIdMap.entries.find { it.value == id }?.key ?: return@get call.respond(HttpStatusCode.NotFound, "Page not found")
|
val res = client.get("repos/SteamWar/Website/branches")
|
||||||
|
call.respond(res.status, Json.parseToJsonElement(res.bodyAsText()).jsonArray.map { it.jsonObject["name"]?.jsonPrimitive?.content!! })
|
||||||
val branch = call.request.queryParameters["branch"] ?: "master"
|
|
||||||
val res = client.get("repos/SteamWar/Website/contents/$path?ref=$branch")
|
|
||||||
val fileJson = Json.parseToJsonElement(res.bodyAsText())
|
|
||||||
if (fileJson is JsonArray) {
|
|
||||||
return@get call.respond(HttpStatusCode.BadRequest, "Invalid id")
|
|
||||||
}
|
}
|
||||||
|
post {
|
||||||
|
@Serializable
|
||||||
|
data class CreateGiteaBranchRequest(val new_branch_name: String, val old_branch_name: String)
|
||||||
|
|
||||||
val file = PageResponse(fileJson.jsonObject, id)
|
val branch = call.receive<CreateBranchRequest>().branch
|
||||||
call.respond(file)
|
val res = client.post("repos/SteamWar/Website/branches") {
|
||||||
|
contentType(ContentType.Application.Json)
|
||||||
|
setBody(CreateGiteaBranchRequest(branch, "master"))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class CreateGiteaMergeRequest(val base: String, val head: String, val title: String)
|
||||||
|
|
||||||
|
client.post("repos/SteamWar/Website/pulls") {
|
||||||
|
contentType(ContentType.Application.Json)
|
||||||
|
setBody(CreateGiteaMergeRequest("master", branch, "Merge branch $branch"))
|
||||||
|
}
|
||||||
|
|
||||||
|
call.respond(res.status)
|
||||||
|
}
|
||||||
|
delete {
|
||||||
|
val branch = call.receive<CreateBranchRequest>().branch
|
||||||
|
val res = client.delete("repos/SteamWar/Website/branches/$branch")
|
||||||
|
call.respond(res.status)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
route("{id}") {
|
||||||
|
get {
|
||||||
|
val id = call.parameters["id"]?.toIntOrNull() ?: return@get call.respond(HttpStatusCode.BadRequest, "Invalid id")
|
||||||
|
val path = pathPageIdMap.entries.find { it.value == id }?.key ?: return@get call.respond(HttpStatusCode.NotFound, "Page not found")
|
||||||
|
|
||||||
delete("{id}") {
|
val branch = call.request.queryParameters["branch"] ?: "master"
|
||||||
val data = call.receive<DeletePageRequest>()
|
val res = client.get("repos/SteamWar/Website/contents/$path?ref=$branch")
|
||||||
|
val fileJson = Json.parseToJsonElement(res.bodyAsText())
|
||||||
|
if (fileJson is JsonArray) {
|
||||||
|
return@get call.respond(HttpStatusCode.BadRequest, "Invalid id")
|
||||||
|
}
|
||||||
|
|
||||||
val path = pathPageIdMap.entries.find { it.value == call.parameters["id"]?.toIntOrNull() }?.key ?: return@delete call.respond(HttpStatusCode.NotFound, "Page not found")
|
val file = PageResponse(fileJson.jsonObject, id)
|
||||||
val branch = call.request.queryParameters["branch"] ?: "master"
|
call.respond(file)
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class DeleteGiteaPageRequest(val sha: String, val message: String, val branch: String, val author: Identity)
|
|
||||||
|
|
||||||
val res = client.delete("repos/SteamWar/Website/contents/$path") {
|
|
||||||
contentType(ContentType.Application.Json)
|
|
||||||
setBody(DeleteGiteaPageRequest(data.sha, data.message, branch, Identity(call.principal<SWAuthPrincipal>()!!.user.userName, "admin-tool@steamwar.de")))
|
|
||||||
}
|
}
|
||||||
|
delete {
|
||||||
|
val data = call.receive<DeletePageRequest>()
|
||||||
|
|
||||||
call.respond(res.status)
|
val path = pathPageIdMap.entries.find { it.value == call.parameters["id"]?.toIntOrNull() }?.key ?: return@delete call.respond(HttpStatusCode.NotFound, "Page not found")
|
||||||
|
val branch = call.request.queryParameters["branch"] ?: "master"
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class DeleteGiteaPageRequest(val sha: String, val message: String, val branch: String, val author: Identity)
|
||||||
|
|
||||||
|
val res = client.delete("repos/SteamWar/Website/contents/$path") {
|
||||||
|
contentType(ContentType.Application.Json)
|
||||||
|
setBody(DeleteGiteaPageRequest(data.sha, data.message, branch, Identity(call.principal<SWAuthPrincipal>()!!.user.userName, "admin-tool@steamwar.de")))
|
||||||
|
}
|
||||||
|
|
||||||
|
call.respond(res.status)
|
||||||
|
}
|
||||||
|
put {
|
||||||
|
@Serializable
|
||||||
|
data class UpdateGiteaPageRequest(val content: String, val sha: String, val message: String, val branch: String, val author: Identity)
|
||||||
|
|
||||||
|
val data = call.receive<UpdatePageRequest>()
|
||||||
|
val path = pathPageIdMap.entries.find { it.value == call.parameters["id"]?.toIntOrNull() }?.key ?: return@put call.respond(HttpStatusCode.NotFound, "Page not found")
|
||||||
|
|
||||||
|
val res = client.put("repos/SteamWar/Website/contents/$path") {
|
||||||
|
contentType(ContentType.Application.Json)
|
||||||
|
setBody(UpdateGiteaPageRequest(data.content, data.sha, data.message, (call.request.queryParameters["branch"] ?: "master"), Identity(call.principal<SWAuthPrincipal>()!!.user.userName, "admin-tool@steamwar.de")))
|
||||||
|
}
|
||||||
|
|
||||||
|
call.respond(res.status)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
route("images") {
|
||||||
|
get {
|
||||||
|
val branch = call.request.queryParameters["branch"] ?: "master"
|
||||||
|
|
||||||
put("{id}") {
|
call.respond(filesInDirectory("/src/images", branch))
|
||||||
@Serializable
|
|
||||||
data class UpdateGiteaPageRequest(val content: String, val sha: String, val message: String, val branch: String, val author: Identity)
|
|
||||||
|
|
||||||
val data = call.receive<UpdatePageRequest>()
|
|
||||||
val path = pathPageIdMap.entries.find { it.value == call.parameters["id"]?.toIntOrNull() }?.key ?: return@put call.respond(HttpStatusCode.NotFound, "Page not found")
|
|
||||||
|
|
||||||
val res = client.put("repos/SteamWar/Website/contents/$path") {
|
|
||||||
contentType(ContentType.Application.Json)
|
|
||||||
setBody(UpdateGiteaPageRequest(data.content, data.sha, data.message, (call.request.queryParameters["branch"] ?: "master"), Identity(call.principal<SWAuthPrincipal>()!!.user.userName, "admin-tool@steamwar.de")))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
call.respond(res.status)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user