diff --git a/docs/team/translate/de.properties b/docs/team/translate/de.properties new file mode 100644 index 00000000..c5e9f0db --- /dev/null +++ b/docs/team/translate/de.properties @@ -0,0 +1,85 @@ +rank.builder.description= Das Bauteam kreiert neue Maps und Lobbys für alle Gelegenheiten und Spielmodi auf Timolia. \ +Sie betreuen die architektonische Gestaltung neuer Modi und betreuen externe Mapeinsendungen. +rank.builder_plus.description= Builder+ übernehmen zusätzliche organisatorische Verantwortung durch ihre hohe Erfahrung sowohl im Level Design als auch im Team. \ +So leiten sie beispielsweise Projekte oder sind Ansprechpartner für neue Builder. +rank.content.description= Als kreative Ader sind sie für die verschiedensten Belange von Grafikdesign bis Übersetzung zuständig. +rank.developer.description= Developer kümmern sich um die Timolia Plugins, entwickeln neue Features und Spielmodi und kümmern sich um die Bugs, pardon, Features auf Timolia. +rank.developer_plus.description= Sie verfügen über langjährige Erfahrung als Entwickler auf Timolia und stehen bei internen Fragen zum Development zur Verfügung. \ +Auch kümmern sie sich um Timolia Plugins, entwickeln neue Features und Spielmodi und beheben mögliche Spielfehler. +rank.head_builder.description= Sie leiten und organisieren das Bauteam und dienen als erste Ansprechpartner für alle Builder. \ +Außerdem kümmern sie sich um die Auswahl und Einarbeitung neuer Builder und sind die Schnittstelle zwischen dem Bauteam und der allgemeinen Projektorganisation. +rank.administrator.description= Diese Teamler bilden die Leitung Timolias. Sie kümmern sich um die Verwaltung, Organisation und die Teamleitung. +rank.moderator.description= Moderatoren sind langjährige und besonders erfahrene Teamler, die einzigartige Expertise in ihrem jeweiligen Fachgebiet aufweisen. \ +Sie dienen als interne Ansprechpartner bei Fragen und koordinieren häufig einzelne Aufgabengebiete. +rank.supporter.description= Supporter stehen für alle grundlegenden Fragen und Reports zur Verfügung und sind die ersten, an die sich Spieler mit ihren Anliegen wenden können. +rank.supporter_plus.description= Sie verfügen über ein umfassendes Fachwissen und stehen für alle Fragen und Reports zur Verfügung. \ +Sie sind die ersten, an die sich Spieler mit ihren Anliegen wenden können. +rank.sysadmin.description= Systemadministratoren planen, installieren, konfigurieren und warten die technischen Systeme Timolias. \ +Sie führen Updates durch und sorgen für ein reibungsloses Spielerlebnis im Alltag. +page.rank-change.first= Hier werden alle Aus- und Eintritte bzw. Beförderungen und Degradierungen aufgelistet. +player= Spieler +page.rank-change.rank-previous= Vorheriger Rang +page.rank-change.rank-new= Jetziger Rang +date= Datum +page.members.first-1= Das Timolia-Team besteht aktuell aus +page.members.first-2= Mitgliedern und ist in die Ränge +and= und +page.members.first-3= aufgeteilt. +page.members.first-4= Nachfolgend findet ihr eine Liste aller Teammitglieder von Timolia sowie deren Aufgabenbereiche und Verantwortlichkeiten. Diese Zuteilung heißt nicht, dass ausschießlich diese Teamler in diesem Bereich aktiv sind. \ +Die Planung und Entwicklung von neuen Modi, Updates, Events und Ähnlichem liegt ausdrücklich nicht bei einem festen Teammitglied oder einer festen Gruppe von Teammitgliedern sondern unterscheidet sich von Projekt zu Projekt oder ändert sich zum Teil im Laufe des Projekts. +page.members.first-5= Die Ränge auf Timolia +page.members.rank-ingame= Rang (ingame) +page.members.hv= Hauptverantwortlich +page.members.nv= Nebenverantwortlich +page.members.fields= Bereiche +page.responsibilities.project-team-orga= Projekt- und Teamorganisation +page.responsibilities.teamleader= Team-Leiter +page.responsibilities.teamleader.desc= Im Timolia Team gibt es kleinere Teams, welche unter anderem durch diese Verantwortlichen organisiert werden. +page.responsibilities.project-team-orga.apply.builder= Teamlerauswahl Builder und Timolia Creative +page.responsibilities.project-team-orga.apply.content= Teamlerauswahl Content +page.responsibilities.project-team-orga.apply.development= Teamlerauswahl Development +page.responsibilities.project-team-orga.apply.support= Teamlerauswahl Support +page.responsibilities.project-team-orga.apply.support.desc= Wenn es wieder daran geht, neue Teammitglieder für den Support in unsere Reihen zu holen, kümmern sich diese Verantwortlichen darum. +page.responsibilities.project-team-orga.howto= Timolia HowTo +page.responsibilities.project-team-orga.howto.desc= Diese Teamler kümmern sich um's Aktualisieren und Erstellen des HowTos Timolias. +page.responsibilities.project-team-orga.tournament= Timolia Turnier Organisation +page.responsibilities.project-team-orga.tournament.desc= Dieses Team entscheidet über die Turniereinstellungen bei den Freitagsturnieren. +page.responsibilities.project-team-orga.uhc= UHC +page.responsibilities.project-team-orga.uhc.desc= Diese Teammitglieder kümmern sich um die Organisation und den reibungslosen Ablauf aller Timolia UHCs. +page.responsibilities.project-team-orga.youtuber= Youtuber-Ränge +page.responsibilities.project-team-orga.youtuber.desc= Wenn sich ein YouTuber für einen Rang auf Timolia interessiert, werden die Anfragen von diesem Team bearbeitet. +page.responsibilities.communication-platforms= Kommunikationsplattformen +page.responsibilities.communication-platforms.community-discord= Community-Discord +page.responsibilities.communication-platforms.community-discord.desc= Der Community-Discord von Timolia ist unter [https://timolia.de/discord](https://timolia.de/discord) zu erreichen. Er wird betreut von diesen Teamlern. +page.responsibilities.communication-platforms.bug-reports= Bug Reports +page.responsibilities.communication-platforms.appeal= Entschuldigungen +page.responsibilities.communication-platforms.falsely-banned= Zu Unrecht gebannt +page.responsibilities.communication-platforms.socialmedia= Social Media +page.responsibilities.communication-platforms.socialmedia.desc= Für einen ständigen Support und Content auf Twitter und anderen sozialen Medien sorgen diese Teamler. +page.responsibilities.communication-platforms.teamspeak= TeamSpeak +page.responsibilities.communication-platforms.teamspeak.desc= Der TeamSpeak von Timolia ist unter `ts.timolia.de` zu erreichen. Er wird betreut von diesen Teamlern. +page.responsibilities.other-responsibilities= Sonstige Aufgaben +page.responsibilities.other-responsibilities.translation= Translation und Content creation +page.responsibilities.other-responsibilities.map-submissions= Map-Einsendungen +page.responsibilities.other-responsibilities.graphicdesign= Grafikdesign +page.responsibilities.other-responsibilities.announcements= Ankündigungen +page.responsibilities.other-responsibilities.monthly-winner= Monatssieger +page.responsibilities.info= Hier werden die verschiedenen Aufgabenbereiche der Timolia Teamler aufgelistet. +page.responsibilities.custom.bug-reports.modsanddevs= Moderatoren und Developer +page.responsibilities.custom.sm.title= Projekte u. Verantwortungsgrad +page.responsibilities.custom.sm.twitter= Twitter +page.responsibilities.custom.sm.twitter-builder= Bauteam-Twitter +page.responsibilities.custom.sm.twitter.hv= Twitter HV +page.responsibilities.custom.sm.twitter.nv= Twitter NV +page.responsibilities.custom.sm.twitter-builder.hv= Bauteam-Twitter MR +page.responsibilities.custom.sm.twitter-builder.nv= Bauteam-Twitter SR +page.responsibilities.custom.teamleader.title= Zuständigkeit +page.responsibilities.custom.teamleader.whole-team= Management des Timolia-Teams +page.responsibilities.custom.teamleader.builder= Management des Bau-Teams +page.responsibilities.custom.teamleader.content= Management des Content-Teams +page.responsibilities.custom.teamleader.development= Management des Dev-Teams +page.responsibilities.custom.yter.title= Zuständigkeit +page.responsibilities.teamler= Teamler +page.responsibilities.responsib= Verantwortungsgrad +page.responsibilities.hv= Hauptverantwortlich +page.responsibilities.nv= Nebenverantwortlich diff --git a/docs/team/translate/en.properties b/docs/team/translate/en.properties new file mode 100644 index 00000000..a8dafd02 --- /dev/null +++ b/docs/team/translate/en.properties @@ -0,0 +1,86 @@ +rank.builder.description= The builder team creates new maps and lobbies for all occasions and game modes on Timolia. \ +They supervise the architectural design of new game modes and manage external map submissions. +rank.builder_plus.description= Builder+ take on additional organizational responsibility through their high level of experience in both level design and the team. \ +For example, they manage projects or are the contact person for new builders. +rank.content.description= As a creative streak, they are responsible for a wide range of interests from graphic design to translation. +rank.developer.description= Developers take care of Timolia plugins, develop new features and game modes and fix bugs (oh sorry, we really mean features) features on Timolia. +rank.developer_plus.description= They have many years of experience as a developer on Timolia and are available to answer internal questions about development. \ +They also take care of Timolia plugins, develop new features and game modes and fix possible bugs in games. +rank.head_builder.description= They lead and organize the builder team and act as the first point of contact for all builders. \ +Moreover, they take care of the selection and training of new builders and are the link between the builder team and the general project organization. +rank.administrator.description= These team members form the leadership of Timolia. They take care of administration, organization and team management. +rank.moderator.description= Moderators are long-term and outstandingly experienced team members who have unique knowledge in their respective fields. \ +They serve as internal contacts for questions and often coordinate individual areas of responsibility. +rank.supporter.description= Supporters are available for all basic questions and reports and \ +are the first to whom players can address their concerns. +rank.supporter_plus.description= They have comprehensive specialized knowledge and are available for all questions and reports. \ +They are the first to whom players can turn with their concerns. +rank.sysadmin.description= System administrators plan, install, configure and maintain Timolia's technical systems. \ +They carry out updates and ensure a smooth gaming experience in everyday life. +page.rank-change.first= Here, all team entries and resignations as well as promotions and demotions are listed. +player= Name +page.rank-change.rank-previous= Previous rank +page.rank-change.rank-new= Current Rank +date= Date +page.members.first-1= The Timolia team currently consists of +page.members.first-2= team members and is divided into the ranks +and= and +page.members.first-3= . +page.members.first-4= Below you will find a list of all team members of Timolia and their responsibilities aswell as their fields of operation. This does not mean that these team members alone are active in that specific field. \ +Planning and developing new game modes, updates and events is not assigned to one specific team member or a specific group of team members. It rather differs from one project to another and may change during the course of the project. +page.members.first-5= The ranks on Timolia +page.members.rank-ingame= Rang (ingame) +page.members.hv= Main responsibilities +page.members.nv= Secondary responsibilities +page.members.fields= Fields +page.responsibilities.project-team-orga= Project- and Teamorganization +page.responsibilities.teamleader= Team Leader +page.responsibilities.teamleader.desc= In the Timolia team, there are smaller teams, which are organized among others by these responsible persons. +page.responsibilities.project-team-orga.apply.builder= Staff selection builder and Timolia Creative +page.responsibilities.project-team-orga.apply.content= Staff selection content +page.responsibilities.project-team-orga.apply.development= Staff selection development +page.responsibilities.project-team-orga.apply.support= Staff selection support +page.responsibilities.project-team-orga.apply.support.desc= When it comes to recruiting new supporters, those team members will take care of it. +page.responsibilities.project-team-orga.howto= Timolia HowTo +page.responsibilities.project-team-orga.howto.desc= These team members are responsible for updating and creating Timolia's HowTos. +page.responsibilities.project-team-orga.tournament= Timolia Tournament Organization +page.responsibilities.project-team-orga.tournament.desc= This team decides on the tournament settings for the Friday tournaments. +page.responsibilities.project-team-orga.uhc= UHC +page.responsibilities.project-team-orga.uhc.desc= These team members take care of the organization and seamless experience of all Timolia UHCs. +page.responsibilities.project-team-orga.youtuber= YouTuber Ranks +page.responsibilities.project-team-orga.youtuber.desc= If a YouTuber is interested in a rank on Timolia, the requests are processed by this team. +page.responsibilities.communication-platforms= Communication platforms +page.responsibilities.communication-platforms.community-discord= Community-Discord +page.responsibilities.communication-platforms.community-discord.desc= The Community-Discord of Timolia can be reached at [https://timolia.de/discord](https://timolia.de/discord). It is maintained by these team members. +page.responsibilities.communication-platforms.bug-reports= Bug Reports +page.responsibilities.communication-platforms.appeal= Appeals +page.responsibilities.communication-platforms.falsely-banned= Falsely banned +page.responsibilities.communication-platforms.socialmedia= Social Media +page.responsibilities.communication-platforms.socialmedia.desc= These team members provide ongoing support and content on Twitter and other social media. +page.responsibilities.communication-platforms.teamspeak= TeamSpeak +page.responsibilities.communication-platforms.teamspeak.desc= The TeamSpeak of Timolia can be reached at `ts.timolia.de`. It is supervised by these team members. +page.responsibilities.other-responsibilities= Other responsibilites +page.responsibilities.other-responsibilities.translation= Translation and Content creation +page.responsibilities.other-responsibilities.map-submissions= Map submissions +page.responsibilities.other-responsibilities.graphicdesign= Graphic design +page.responsibilities.other-responsibilities.announcements= Announcements +page.responsibilities.other-responsibilities.monthly-winner= Monthly winner +page.responsibilities.info= The various areas of responsibility of the Timolia team members are listed here. +page.responsibilities.custom.bug-reports.modsanddevs= Moderators and Developers +page.responsibilities.custom.sm.title= Projects and level of responsibility +page.responsibilities.custom.sm.twitter= Twitter +page.responsibilities.custom.sm.twitter-builder= Builder Team-Twitter +page.responsibilities.custom.sm.twitter.hv= Twitter MR +page.responsibilities.custom.sm.twitter.nv= Twitter SR +page.responsibilities.custom.sm.twitter-builder.hv= Builder Team-Twitter MR +page.responsibilities.custom.sm.twitter-builder.nv= Builder Team-Twitter SR +page.responsibilities.custom.teamleader.title= Responsibility +page.responsibilities.custom.teamleader.whole-team= Management of the Timolia team +page.responsibilities.custom.teamleader.builder= Management of the builder team +page.responsibilities.custom.teamleader.content= Management of the content team +page.responsibilities.custom.teamleader.development= Management of the development team +page.responsibilities.custom.yter.title= Responsibility +page.responsibilities.teamler= Team member +page.responsibilities.responsib= Level of responsibility +page.responsibilities.hv= Main responsibility +page.responsibilities.nv= Secondary responsibility diff --git a/howto-dapp/build.gradle b/howto-dapp/build.gradle index 140e0016..6ad834da 100644 --- a/howto-dapp/build.gradle +++ b/howto-dapp/build.gradle @@ -1,6 +1,7 @@ plugins { id 'java' id 'com.github.johnrengelman.shadow' version '6.1.0' + id 'org.jetbrains.kotlin.jvm' version '1.8.21' } group 'de.timolia.howto' @@ -13,19 +14,18 @@ repositories { dependencies { testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.2' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.2' - implementation 'com.google.code.gson:gson:2.8.8' - implementation 'mysql:mysql-connector-java:8.0.25' + implementation 'com.google.code.gson:gson:2.8.9' + implementation 'mysql:mysql-connector-java:8.0.28' // https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.11' } -test { - useJUnitPlatform() -} - jar { manifest { attributes 'Main-Class': 'de.timolia.howto.Dapp' } +} +kotlin { + jvmToolchain(17) } \ No newline at end of file diff --git a/howto-dapp/gradle/wrapper/gradle-wrapper.jar b/howto-dapp/gradle/wrapper/gradle-wrapper.jar index e708b1c0..7454180f 100644 Binary files a/howto-dapp/gradle/wrapper/gradle-wrapper.jar and b/howto-dapp/gradle/wrapper/gradle-wrapper.jar differ diff --git a/howto-dapp/gradle/wrapper/gradle-wrapper.properties b/howto-dapp/gradle/wrapper/gradle-wrapper.properties index 4d9ca164..8f5ef1a1 100644 --- a/howto-dapp/gradle/wrapper/gradle-wrapper.properties +++ b/howto-dapp/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists +zipStorePath=wrapper/dists \ No newline at end of file diff --git a/howto-dapp/gradlew b/howto-dapp/src/gradlew old mode 100644 new mode 100755 similarity index 99% rename from howto-dapp/gradlew rename to howto-dapp/src/gradlew index 4f906e0c..744e882e --- a/howto-dapp/gradlew +++ b/howto-dapp/src/gradlew @@ -72,7 +72,7 @@ case "`uname`" in Darwin* ) darwin=true ;; - MINGW* ) + MSYS* | MINGW* ) msys=true ;; NONSTOP* ) diff --git a/howto-dapp/gradlew.bat b/howto-dapp/src/gradlew.bat similarity index 97% rename from howto-dapp/gradlew.bat rename to howto-dapp/src/gradlew.bat index 107acd32..e18c03ce 100644 --- a/howto-dapp/gradlew.bat +++ b/howto-dapp/src/gradlew.bat @@ -33,7 +33,7 @@ set APP_HOME=%DIRNAME% for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" "-Dfile.encoding=UTF-8" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome diff --git a/howto-dapp/src/main/java/de/timolia/howto/Dapp.java b/howto-dapp/src/main/java/de/timolia/howto/Dapp.java deleted file mode 100644 index 97f259ca..00000000 --- a/howto-dapp/src/main/java/de/timolia/howto/Dapp.java +++ /dev/null @@ -1,144 +0,0 @@ -package de.timolia.howto; - -import com.google.gson.FieldNamingPolicy; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import de.timolia.howto.conversion.JsonBuilder; -import de.timolia.howto.conversion.models.TeamlerRankChange; -import de.timolia.howto.conversion.models.TeamlerResponsibilities; -import de.timolia.howto.generator.PageRankChange; -import de.timolia.howto.generator.PageResponsibilities; -import de.timolia.howto.generator.PageTeamMembers; -import de.timolia.howto.models.Language; -import de.timolia.howto.models.Rank; -import de.timolia.howto.models.Sex; -import de.timolia.howto.models.Teamler; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.stream.Collectors; - -public class Dapp { // D. Application - - private static final Gson gson = new GsonBuilder() - .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) - .create(); - - public static boolean isDevEnv = false; - public static String MYSQL_USER = null; - public static String MYSQL_PASS = null; - public static String MYSQL_CON_STR = null; - - public static void main(String[] args) { - - if (System.getenv("MYSQL_USER_LIVE") != null) { - // live - MYSQL_USER = System.getenv("MYSQL_USER_LIVE"); - MYSQL_PASS = System.getenv("MYSQL_PASS_LIVE"); - MYSQL_CON_STR = System.getenv("MYSQL_CON_STR_LIVE"); - } else { - // dev - isDevEnv = true; - MYSQL_USER = System.getenv("MYSQL_USER_DEV"); - MYSQL_PASS = System.getenv("MYSQL_PASS_DEV"); - MYSQL_CON_STR = System.getenv("MYSQL_CON_STR_DEV"); - } - - - try { - - String json = Files.readString(Path.of("docs", "team", "teamler.json"), Charset.defaultCharset()); - Teamler[] teamlers = gson.fromJson(json, Teamler[].class); - List teamlerList = Arrays.asList(teamlers); - teamlerList.forEach(Teamler::updateName); - -// for(Teamler teamler : teamlerList) { -// String name = SQLApi.getName(teamler.getUuid()); -// if(!name.equals(teamler.getName())) { -// System.out.println("!!! " + teamler.getName() + " -> " + name); -// } -// } - - String changesMD = PageRankChange.generate(teamlerList); - String membersMD = PageTeamMembers.generate(teamlerList); - String responsibilitiesMD = PageResponsibilities.generate(teamlerList); - - writeFile(Path.of("docs", "team", "changes.de.md"), LanguageUtil.translate(Language.DE, changesMD)); - writeFile(Path.of("docs", "team", "members.de.md"), LanguageUtil.translate(Language.DE, membersMD)); - writeFile(Path.of("docs", "team", "responsibilities.de.md"), LanguageUtil.translate(Language.DE, responsibilitiesMD)); - - writeFile(Path.of("docs", "team", "changes.en.md"), LanguageUtil.translate(Language.EN, changesMD)); - writeFile(Path.of("docs", "team", "members.en.md"), LanguageUtil.translate(Language.EN, membersMD)); - writeFile(Path.of("docs", "team", "responsibilities.en.md"), LanguageUtil.translate(Language.EN, responsibilitiesMD)); - - } catch (Exception e) { - e.printStackTrace(); - System.exit(1); - } - - // used for initial conversion only - //convert(); - - - System.exit(0); - } - - private static void writeFile(Path path, String text) throws IOException { - path.toFile().getParentFile().mkdirs(); - Files.writeString(path, text, Charset.defaultCharset(), StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE); - System.out.println("Wrote file '" + path.toString() + "'"); - } - - private static void convert() throws IOException, ParseException { - - List teamlers = new ArrayList<>(); - List teamlerRankChanges = JsonBuilder.getTeamlerRankChanges(); - - - teamlerRankChanges.stream().map(TeamlerRankChange::getUuid).sorted().distinct().forEach(uuid -> { - List changes = teamlerRankChanges.stream().filter(teamlerRankChange -> teamlerRankChange.getUuid().equals(uuid)).collect(Collectors.toList()); - - LinkedHashMap rankHistory = new LinkedHashMap<>(); - for (TeamlerRankChange teamlerRankChange : changes) { - if (rankHistory.isEmpty()) { - rankHistory.put("initial", teamlerRankChange.getRankFrom()); - } - rankHistory.put(teamlerRankChange.getReadableDate(), teamlerRankChange.getRankTo()); - } - - Teamler teamler = new Teamler(uuid, Sex.undefined, null, null, null, rankHistory); - teamlers.add(teamler); - }); - - List teamlerResponsibilitiesList = JsonBuilder.getTeamlerResponsibilities(); - teamlerResponsibilitiesList.forEach(teamlerResponsibilities -> { - Teamler teamler = teamlers.stream().filter(teamler1 -> teamler1.getUuid().equals(teamlerResponsibilities.getUuid())).findFirst().orElse(null); - - if (teamler == null) { - teamler = new Teamler(teamlerResponsibilities.getUuid(), Sex.undefined, null, null, null, null); - } - - System.out.println("teamler: " + teamler); - if (teamlerResponsibilities.getHv() != null) { - System.out.println("teamlerResponsibilities.getHv(): " + teamlerResponsibilities.getHv()); - teamler.setResponsibilitiesMain(Arrays.asList(teamlerResponsibilities.getHv().split(", "))); - } - if (teamlerResponsibilities.getNv() != null) { - teamler.setResponsibilitiesSecondary(Arrays.asList(teamlerResponsibilities.getNv().split(", "))); - } - }); - - - System.out.println(gson.toJson(teamlers)); - - } - -} diff --git a/howto-dapp/src/main/java/de/timolia/howto/Dapp.kt b/howto-dapp/src/main/java/de/timolia/howto/Dapp.kt new file mode 100644 index 00000000..d134a035 --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/Dapp.kt @@ -0,0 +1,43 @@ +package de.timolia.howto + +import com.google.gson.FieldNamingPolicy +import com.google.gson.Gson +import com.google.gson.GsonBuilder +import de.timolia.howto.conversion.InitialConversion +import de.timolia.howto.generator.FileWriter +import de.timolia.howto.generator.PageRankChange +import de.timolia.howto.generator.PageResponsibilities +import de.timolia.howto.generator.PageTeamMembers +import de.timolia.howto.teamler.Teamler +import de.timolia.howto.translate.Translate +import java.nio.file.Files +import java.nio.file.Path +import java.util.* +import kotlin.Throws +import kotlin.jvm.JvmStatic + +object Dapp { + val translate: Translate = Translate() + val gson: Gson = GsonBuilder() + .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) + .create() + + @Throws(Exception::class) + @JvmStatic + fun main(args: Array) { + val path = Path.of("docs", "team") + translate.loadDirectory(path.resolve("translate")) + val json = Files.readString(path.resolve("teamler.json")) + val teamlers = gson.fromJson(json, Array::class.java) + val teamlerList = listOf(*teamlers) + teamlerList.forEach(Teamler::updateName) + with(FileWriter(path, translate)) { + writeFile("changes", PageRankChange.generate(teamlerList)) + writeFile("members", PageTeamMembers(teamlerList).generate()) + writeFile("responsibilities", PageResponsibilities.generate(teamlerList)) + } + if(args.any { it.equals("init", ignoreCase = true) }) { + InitialConversion.convert() + } + } +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/LanguageUtil.java b/howto-dapp/src/main/java/de/timolia/howto/LanguageUtil.java deleted file mode 100644 index 0c332a61..00000000 --- a/howto-dapp/src/main/java/de/timolia/howto/LanguageUtil.java +++ /dev/null @@ -1,205 +0,0 @@ -package de.timolia.howto; - -import de.timolia.howto.models.Language; -import de.timolia.howto.models.LanguageString; - -import java.util.ArrayList; -import java.util.stream.Collectors; - -public class LanguageUtil { - - public static String translate(Language language, String s) { - for(LanguageString languageString : getTranslations().stream().filter(languageString -> languageString.getLanguage().equals(language)).collect(Collectors.toList())) { - s = s.replaceAll("%" + languageString.getKey() + "%", languageString.getValue()); - } - return s; - } - - private static ArrayList getTranslations() { - return new ArrayList<>() {{ - add(new LanguageString(Language.DE, "rank.builder.description", "Das Bauteam kreiert neue Maps und Lobbys für alle Gelegenheiten und Spielmodi auf Timolia. \n" + - "Sie betreuen die architektonische Gestaltung neuer Modi und betreuen externe Mapeinsendungen.")); - add(new LanguageString(Language.EN, "rank.builder.description", "The builder team creates new maps and lobbies for all occasions and game modes on Timolia. \n" + - "They supervise the architectural design of new game modes and manage external map submissions.")); - add(new LanguageString(Language.DE, "rank.builder_plus.description", "Builder+ übernehmen zusätzliche organisatorische Verantwortung durch ihre hohe Erfahrung sowohl im Level Design als auch im Team. \n" + - "So leiten sie beispielsweise Projekte oder sind Ansprechpartner für neue Builder.")); - add(new LanguageString(Language.EN, "rank.builder_plus.description", "Builder+ take on additional organizational responsibility through their high level of experience in both level design and the team. \n" + - "For example, they manage projects or are the contact person for new builders.")); - add(new LanguageString(Language.DE, "rank.content.description", "Als kreative Ader sind sie für die verschiedensten Belange von Grafikdesign bis Übersetzung zuständig.")); - add(new LanguageString(Language.EN, "rank.content.description", "As a creative streak, they are responsible for a wide range of interests from graphic design to translation.")); - add(new LanguageString(Language.DE, "rank.developer.description", "Developer kümmern sich um die Timolia Plugins, entwickeln neue Features und Spielmodi und kümmern sich um die Bugs, pardon, Features auf Timolia.")); - add(new LanguageString(Language.EN, "rank.developer.description", "Developers take care of Timolia plugins, develop new features and game modes and fix bugs (oh sorry, we really mean features) features on Timolia.")); - add(new LanguageString(Language.DE, "rank.developer_plus.description", "Sie verfügen über langjährige Erfahrung als Entwickler auf Timolia und stehen bei internen Fragen zum Development zur Verfügung. \n" + - "Auch kümmern sie sich um Timolia Plugins, entwickeln neue Features und Spielmodi und beheben mögliche Spielfehler.")); - add(new LanguageString(Language.EN, "rank.developer_plus.description", "They have many years of experience as a developer on Timolia and are available to answer internal questions about development. \n" + - "They also take care of Timolia plugins, develop new features and game modes and fix possible bugs in games.")); - add(new LanguageString(Language.DE, "rank.head_builder.description", "Sie leiten und organisieren das Bauteam und dienen als erste Ansprechpartner für alle Builder. \n" + - "Außerdem kümmern sie sich um die Auswahl und Einarbeitung neuer Builder und sind die Schnittstelle zwischen dem Bauteam und der allgemeinen Projektorganisation.")); - add(new LanguageString(Language.EN, "rank.head_builder.description", "They lead and organize the builder team and act as the first point of contact for all builders. \n" + - "Moreover, they take care of the selection and training of new builders and are the link between the builder team and the general project organization.")); - add(new LanguageString(Language.DE, "rank.administrator.description", "Diese Teamler bilden die Leitung Timolias. " + - "Sie kümmern sich um die Verwaltung, Organisation und die Teamleitung.")); - add(new LanguageString(Language.EN, "rank.administrator.description", "These team members form the leadership of Timolia. " + - "They take care of administration, organization and team management.")); - add(new LanguageString(Language.DE, "rank.moderator.description", "Moderatoren sind langjährige und besonders erfahrene Teamler, die einzigartige Expertise in ihrem jeweiligen Fachgebiet aufweisen. \n" + - "Sie dienen als interne Ansprechpartner bei Fragen und koordinieren häufig einzelne Aufgabengebiete.")); - add(new LanguageString(Language.EN, "rank.moderator.description", "Moderators are long-term and outstandingly experienced team members who have unique knowledge in their respective fields. \n" + - "They serve as internal contacts for questions and often coordinate individual areas of responsibility.")); - add(new LanguageString(Language.DE, "rank.supporter.description", "Supporter stehen für alle grundlegenden Fragen und Reports zur Verfügung und sind die ersten, an die sich Spieler mit ihren Anliegen wenden können. ")); - add(new LanguageString(Language.EN, "rank.supporter.description", "Supporters are available for all basic questions and reports and \n" + - "are the first to whom players can address their concerns.")); - add(new LanguageString(Language.DE, "rank.supporter_plus.description", "Sie verfügen über ein umfassendes Fachwissen und stehen für alle Fragen und Reports zur Verfügung. \n" + - "Sie sind die ersten, an die sich Spieler mit ihren Anliegen wenden können.")); - add(new LanguageString(Language.EN, "rank.supporter_plus.description", "They have comprehensive specialized knowledge and are available for all questions and reports. \n" + - "They are the first to whom players can turn with their concerns.")); - add(new LanguageString(Language.DE, "rank.sysadmin.description", "Systemadministratoren planen, installieren, konfigurieren und warten die technischen Systeme Timolias. \n" + - "Sie führen Updates durch und sorgen für ein reibungsloses Spielerlebnis im Alltag.")); - add(new LanguageString(Language.EN, "rank.sysadmin.description", "System administrators plan, install, configure and maintain Timolia's technical systems. \n" + - "They carry out updates and ensure a smooth gaming experience in everyday life.")); - - add(new LanguageString(Language.DE, "page.rank-change.first", "Hier werden alle Aus- und Eintritte bzw. Beförderungen und Degradierungen aufgelistet.")); - add(new LanguageString(Language.EN, "page.rank-change.first", "Here, all team entries and resignations as well as promotions and demotions are listed.")); - add(new LanguageString(Language.DE, "player", "Spieler")); - add(new LanguageString(Language.EN, "player", "Name")); - add(new LanguageString(Language.DE, "page.rank-change.rank-previous", "Vorheriger Rang")); - add(new LanguageString(Language.EN, "page.rank-change.rank-previous", "Previous rank")); - add(new LanguageString(Language.DE, "page.rank-change.rank-new", "Jetziger Rang")); - add(new LanguageString(Language.EN, "page.rank-change.rank-new", "Current Rank")); - add(new LanguageString(Language.DE, "date", "Datum")); - add(new LanguageString(Language.EN, "date", "Date")); - - add(new LanguageString(Language.DE, "page.members.first-1", "Das Timolia-Team besteht aktuell aus ")); - add(new LanguageString(Language.EN, "page.members.first-1", "The Timolia team currently consists of ")); - add(new LanguageString(Language.DE, "page.members.first-2", " Mitgliedern und ist in die Ränge ")); - add(new LanguageString(Language.EN, "page.members.first-2", " team members and is divided into the ranks")); - add(new LanguageString(Language.DE, "and", "und")); - add(new LanguageString(Language.EN, "and", "and")); - add(new LanguageString(Language.DE, "page.members.first-3", " aufgeteilt.")); - add(new LanguageString(Language.EN, "page.members.first-3", ".")); - add(new LanguageString(Language.DE, "page.members.first-4", "Nachfolgend findet ihr eine Liste aller Teammitglieder von Timolia sowie deren Aufgabenbereiche und Verantwortlichkeiten. Diese Zuteilung heißt nicht, dass ausschießlich diese Teamler in diesem Bereich aktiv sind. \n" + - "Die Planung und Entwicklung von neuen Modi, Updates, Events und Ähnlichem liegt ausdrücklich nicht bei einem festen Teammitglied oder einer festen Gruppe von Teammitgliedern sondern unterscheidet sich von Projekt zu Projekt oder ändert sich zum Teil im Laufe des Projekts.")); - add(new LanguageString(Language.EN, "page.members.first-4", "Below you will find a list of all team members of Timolia and their responsibilities aswell as their fields of operation. This does not mean that these team members alone are active in that specific field. \n" + - "Planning and developing new game modes, updates and events is not assigned to one specific team member or a specific group of team members. It rather differs from one project to another and may change during the course of the project.")); - add(new LanguageString(Language.DE, "page.members.first-5", "Die Ränge auf Timolia")); - add(new LanguageString(Language.EN, "page.members.first-5", "The ranks on Timolia")); - add(new LanguageString(Language.DE, "page.members.rank-ingame", "Rang (ingame)")); - add(new LanguageString(Language.EN, "page.members.rank-ingame", "Rang (ingame)")); - add(new LanguageString(Language.DE, "page.members.hv", "Hauptverantwortlich")); - add(new LanguageString(Language.EN, "page.members.hv", "Main responsibilities")); - add(new LanguageString(Language.DE, "page.members.nv", "Nebenverantwortlich")); - add(new LanguageString(Language.EN, "page.members.nv", "Secondary responsibilities")); - add(new LanguageString(Language.DE, "page.members.fields", "Bereiche")); - add(new LanguageString(Language.EN, "page.members.fields", "Fields")); - - add(new LanguageString(Language.DE, "page.responsibilities.project-team-orga", "Projekt- und Teamorganisation")); - add(new LanguageString(Language.EN, "page.responsibilities.project-team-orga", "Project- and Teamorganization")); - add(new LanguageString(Language.DE, "page.responsibilities.teamleader", "Team-Leiter")); - add(new LanguageString(Language.EN, "page.responsibilities.teamleader", "Team Leader")); - add(new LanguageString(Language.DE, "page.responsibilities.teamleader.desc", "Im Timolia Team gibt es kleinere Teams, welche unter anderem durch diese Verantwortlichen organisiert werden.")); - add(new LanguageString(Language.EN, "page.responsibilities.teamleader.desc", "In the Timolia team, there are smaller teams, which are organized among others by these responsible persons.")); - add(new LanguageString(Language.DE, "page.responsibilities.project-team-orga.apply.builder", "Teamlerauswahl Builder und Timolia Creative")); - add(new LanguageString(Language.EN, "page.responsibilities.project-team-orga.apply.builder", "Staff selection builder and Timolia Creative")); - add(new LanguageString(Language.DE, "page.responsibilities.project-team-orga.apply.content", "Teamlerauswahl Content")); - add(new LanguageString(Language.EN, "page.responsibilities.project-team-orga.apply.content", "Staff selection content")); - add(new LanguageString(Language.DE, "page.responsibilities.project-team-orga.apply.development", "Teamlerauswahl Development")); - add(new LanguageString(Language.EN, "page.responsibilities.project-team-orga.apply.development", "Staff selection development")); - add(new LanguageString(Language.DE, "page.responsibilities.project-team-orga.apply.support", "Teamlerauswahl Support")); - add(new LanguageString(Language.EN, "page.responsibilities.project-team-orga.apply.support", "Staff selection support")); - add(new LanguageString(Language.DE, "page.responsibilities.project-team-orga.apply.support.desc", "Wenn es wieder daran geht, neue Teammitglieder für den Support in unsere Reihen zu holen, kümmern sich diese Verantwortlichen darum.")); - add(new LanguageString(Language.EN, "page.responsibilities.project-team-orga.apply.support.desc", "When it comes to recruiting new supporters, those team members will take care of it.")); - add(new LanguageString(Language.DE, "page.responsibilities.project-team-orga.howto", "Timolia HowTo")); - add(new LanguageString(Language.EN, "page.responsibilities.project-team-orga.howto", "Timolia HowTo")); - add(new LanguageString(Language.DE, "page.responsibilities.project-team-orga.howto.desc", "Diese Teamler kümmern sich um's Aktualisieren und Erstellen des HowTos Timolias.")); - add(new LanguageString(Language.EN, "page.responsibilities.project-team-orga.howto.desc", "These team members are responsible for updating and creating Timolia's HowTos.")); - add(new LanguageString(Language.DE, "page.responsibilities.project-team-orga.tournament", "Timolia Turnier Organisation")); - add(new LanguageString(Language.EN, "page.responsibilities.project-team-orga.tournament", "Timolia Tournament Organization")); - add(new LanguageString(Language.DE, "page.responsibilities.project-team-orga.tournament.desc", "Dieses Team entscheidet über die Turniereinstellungen bei den Freitagsturnieren.")); - add(new LanguageString(Language.EN, "page.responsibilities.project-team-orga.tournament.desc", "This team decides on the tournament settings for the Friday tournaments.")); - add(new LanguageString(Language.DE, "page.responsibilities.project-team-orga.uhc", "UHC")); - add(new LanguageString(Language.EN, "page.responsibilities.project-team-orga.uhc", "UHC")); - add(new LanguageString(Language.DE, "page.responsibilities.project-team-orga.uhc.desc", "Diese Teammitglieder kümmern sich um die Organisation und den reibungslosen Ablauf aller Timolia UHCs.")); - add(new LanguageString(Language.EN, "page.responsibilities.project-team-orga.uhc.desc", "These team members take care of the organization and seamless experience of all Timolia UHCs.")); - add(new LanguageString(Language.DE, "page.responsibilities.project-team-orga.youtuber", "Youtuber-Ränge")); - add(new LanguageString(Language.EN, "page.responsibilities.project-team-orga.youtuber", "YouTuber Ranks")); - add(new LanguageString(Language.DE, "page.responsibilities.project-team-orga.youtuber.desc", "Wenn sich ein YouTuber für einen Rang auf Timolia interessiert, werden die Anfragen von diesem Team bearbeitet.")); - add(new LanguageString(Language.EN, "page.responsibilities.project-team-orga.youtuber.desc", "If a YouTuber is interested in a rank on Timolia, the requests are processed by this team.")); - - add(new LanguageString(Language.DE, "page.responsibilities.communication-platforms", "Kommunikationsplattformen")); - add(new LanguageString(Language.EN, "page.responsibilities.communication-platforms", "Communication platforms")); - add(new LanguageString(Language.DE, "page.responsibilities.communication-platforms.community-discord", "Community-Discord")); - add(new LanguageString(Language.EN, "page.responsibilities.communication-platforms.community-discord", "Community-Discord")); - add(new LanguageString(Language.DE, "page.responsibilities.communication-platforms.community-discord.desc", "Der Community-Discord von Timolia ist unter [https://timolia.de/discord](https://timolia.de/discord) zu erreichen. Er wird betreut von diesen Teamlern.")); - add(new LanguageString(Language.EN, "page.responsibilities.communication-platforms.community-discord.desc", "The Community-Discord of Timolia can be reached at [https://timolia.de/discord](https://timolia.de/discord). It is maintained by these team members.")); - add(new LanguageString(Language.DE, "page.responsibilities.communication-platforms.bug-reports", "Bug Reports")); - add(new LanguageString(Language.EN, "page.responsibilities.communication-platforms.bug-reports", "Bug Reports")); - add(new LanguageString(Language.DE, "page.responsibilities.communication-platforms.appeal", "Entschuldigungen")); - add(new LanguageString(Language.EN, "page.responsibilities.communication-platforms.appeal", "Appeals")); - add(new LanguageString(Language.DE, "page.responsibilities.communication-platforms.falsely-banned", "Zu Unrecht gebannt")); - add(new LanguageString(Language.EN, "page.responsibilities.communication-platforms.falsely-banned", "Falsely banned")); - add(new LanguageString(Language.DE, "page.responsibilities.communication-platforms.socialmedia", "Social Media")); - add(new LanguageString(Language.EN, "page.responsibilities.communication-platforms.socialmedia", "Social Media")); - add(new LanguageString(Language.DE, "page.responsibilities.communication-platforms.socialmedia.desc", "Für einen ständigen Support und Content auf Twitter und anderen sozialen Medien sorgen diese Teamler.")); - add(new LanguageString(Language.EN, "page.responsibilities.communication-platforms.socialmedia.desc", "These team members provide ongoing support and content on Twitter and other social media.")); - add(new LanguageString(Language.DE, "page.responsibilities.communication-platforms.teamspeak", "TeamSpeak")); - add(new LanguageString(Language.EN, "page.responsibilities.communication-platforms.teamspeak", "TeamSpeak")); - add(new LanguageString(Language.DE, "page.responsibilities.communication-platforms.teamspeak.desc", "Der TeamSpeak von Timolia ist unter `ts.timolia.de` zu erreichen. Er wird betreut von diesen Teamlern.")); - add(new LanguageString(Language.EN, "page.responsibilities.communication-platforms.teamspeak.desc", "The TeamSpeak of Timolia can be reached at `ts.timolia.de`. It is supervised by these team members.")); - - add(new LanguageString(Language.DE, "page.responsibilities.other-responsibilities", "Sonstige Aufgaben")); - add(new LanguageString(Language.EN, "page.responsibilities.other-responsibilities", "Other responsibilites")); - add(new LanguageString(Language.DE, "page.responsibilities.other-responsibilities.translation", "Translation und Content creation")); - add(new LanguageString(Language.EN, "page.responsibilities.other-responsibilities.translation", "Translation and Content creation")); - add(new LanguageString(Language.DE, "page.responsibilities.other-responsibilities.map-submissions", "Map-Einsendungen")); - add(new LanguageString(Language.EN, "page.responsibilities.other-responsibilities.map-submissions", "Map submissions")); - add(new LanguageString(Language.DE, "page.responsibilities.other-responsibilities.graphicdesign", "Grafikdesign")); - add(new LanguageString(Language.EN, "page.responsibilities.other-responsibilities.graphicdesign", "Graphic design")); - add(new LanguageString(Language.DE, "page.responsibilities.other-responsibilities.announcements", "Ankündigungen")); - add(new LanguageString(Language.EN, "page.responsibilities.other-responsibilities.announcements", "Announcements")); - add(new LanguageString(Language.DE, "page.responsibilities.other-responsibilities.monthly-winner", "Monatssieger")); - add(new LanguageString(Language.EN, "page.responsibilities.other-responsibilities.monthly-winner", "Monthly winner")); - -// add(new LanguageString(Language.DE, "page.responsibilities.broadcasts.desc", "Um auch ingame immer auf dem neusten Stand zu bleiben, wird sich hier um Broadcast Mitteilungen gekümmert.")); -// add(new LanguageString(Language.EN, "page.responsibilities.broadcasts.desc", "To always stay up to date in-game, here is it taken care of broadcast messages.")); - - add(new LanguageString(Language.DE, "page.responsibilities.info", "Hier werden die verschiedenen Aufgabenbereiche der Timolia Teamler aufgelistet.")); - add(new LanguageString(Language.EN, "page.responsibilities.info", "The various areas of responsibility of the Timolia team members are listed here.")); - add(new LanguageString(Language.DE, "page.responsibilities.custom.bug-reports.modsanddevs", "Moderatoren und Developer")); - add(new LanguageString(Language.EN, "page.responsibilities.custom.bug-reports.modsanddevs", "Moderators and Developers")); - add(new LanguageString(Language.DE, "page.responsibilities.custom.sm.title", "Projekte u. Verantwortungsgrad")); - add(new LanguageString(Language.EN, "page.responsibilities.custom.sm.title", "Projects and level of responsibility")); - add(new LanguageString(Language.DE, "page.responsibilities.custom.sm.twitter", "Twitter")); - add(new LanguageString(Language.EN, "page.responsibilities.custom.sm.twitter", "Twitter")); - add(new LanguageString(Language.DE, "page.responsibilities.custom.sm.twitter-builder", "Bauteam-Twitter")); - add(new LanguageString(Language.EN, "page.responsibilities.custom.sm.twitter-builder", "Builder Team-Twitter")); - add(new LanguageString(Language.DE, "page.responsibilities.custom.sm.twitter.hv", "Twitter HV")); - add(new LanguageString(Language.EN, "page.responsibilities.custom.sm.twitter.hv", "Twitter MR")); - add(new LanguageString(Language.DE, "page.responsibilities.custom.sm.twitter.nv", "Twitter NV")); - add(new LanguageString(Language.EN, "page.responsibilities.custom.sm.twitter.nv", "Twitter SR")); - add(new LanguageString(Language.DE, "page.responsibilities.custom.sm.twitter-builder.hv", "Bauteam-Twitter MR")); - add(new LanguageString(Language.EN, "page.responsibilities.custom.sm.twitter-builder.hv", "Builder Team-Twitter MR")); - add(new LanguageString(Language.DE, "page.responsibilities.custom.sm.twitter-builder.nv", "Bauteam-Twitter SR")); - add(new LanguageString(Language.EN, "page.responsibilities.custom.sm.twitter-builder.nv", "Builder Team-Twitter SR")); - add(new LanguageString(Language.DE, "page.responsibilities.custom.teamleader.title", "Zuständigkeit")); - add(new LanguageString(Language.EN, "page.responsibilities.custom.teamleader.title", "Responsibility")); - add(new LanguageString(Language.DE, "page.responsibilities.custom.teamleader.whole-team", "Management des Timolia-Teams")); - add(new LanguageString(Language.EN, "page.responsibilities.custom.teamleader.whole-team", "Management of the Timolia team")); - add(new LanguageString(Language.DE, "page.responsibilities.custom.teamleader.builder", "Management des Bau-Teams")); - add(new LanguageString(Language.EN, "page.responsibilities.custom.teamleader.builder", "Management of the builder team")); - add(new LanguageString(Language.DE, "page.responsibilities.custom.teamleader.content", "Management des Content-Teams")); - add(new LanguageString(Language.EN, "page.responsibilities.custom.teamleader.content", "Management of the content team")); - add(new LanguageString(Language.DE, "page.responsibilities.custom.teamleader.development", "Management des Dev-Teams")); - add(new LanguageString(Language.EN, "page.responsibilities.custom.teamleader.development", "Management of the development team")); - add(new LanguageString(Language.DE, "page.responsibilities.custom.yter.title", "Zuständigkeit")); - add(new LanguageString(Language.EN, "page.responsibilities.custom.yter.title", "Responsibility")); - add(new LanguageString(Language.DE, "page.responsibilities.teamler", "Teamler")); - add(new LanguageString(Language.EN, "page.responsibilities.teamler", "Team member")); - add(new LanguageString(Language.DE, "page.responsibilities.responsib", "Verantwortungsgrad")); - add(new LanguageString(Language.EN, "page.responsibilities.responsib", "Level of responsibility")); - add(new LanguageString(Language.DE, "page.responsibilities.hv", "Hauptverantwortlich")); - add(new LanguageString(Language.EN, "page.responsibilities.hv", "Main responsibility")); - add(new LanguageString(Language.DE, "page.responsibilities.nv", "Nebenverantwortlich")); - add(new LanguageString(Language.EN, "page.responsibilities.nv", "Secondary responsibility")); - }}; - } - -} diff --git a/howto-dapp/src/main/java/de/timolia/howto/Utils.java b/howto-dapp/src/main/java/de/timolia/howto/Utils.java deleted file mode 100644 index 6779649d..00000000 --- a/howto-dapp/src/main/java/de/timolia/howto/Utils.java +++ /dev/null @@ -1,38 +0,0 @@ -package de.timolia.howto; - -import de.timolia.howto.models.Teamler; - -import java.util.Arrays; -import java.util.List; -import java.util.UUID; -import java.util.stream.Collectors; - -public class Utils { - - public static List getTeamler(List teamlers, UUID... uuid) { - List uuids = Arrays.asList(uuid); - return teamlers.stream().filter(teamler -> uuids.contains(teamler.getUuid())).collect(Collectors.toList()); - } - - public static class KeyValuePair { - - private final T key; - private final U value; - - public KeyValuePair(T key, U value) { - this.key = key; - this.value = value; - } - - - public T getKey() { - return key; - } - - public U getValue() { - return value; - } - - } - -} diff --git a/howto-dapp/src/main/java/de/timolia/howto/conversion/InitialConversion.kt b/howto-dapp/src/main/java/de/timolia/howto/conversion/InitialConversion.kt new file mode 100644 index 00000000..d962d7f1 --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/conversion/InitialConversion.kt @@ -0,0 +1,47 @@ +package de.timolia.howto.conversion + +import de.timolia.howto.Dapp +import de.timolia.howto.rank.Rank +import de.timolia.howto.rank.TeamlerRankChange +import de.timolia.howto.teamler.Sex +import de.timolia.howto.teamler.Teamler +import java.io.IOException +import java.text.ParseException + +object InitialConversion { + @Throws(IOException::class, ParseException::class) + fun convert() { + val teamlerRankChanges = JsonBuilder.getTeamlerRankChanges() + val teamlers = teamlerRankChanges.asSequence().map(TeamlerRankChange::uuid).sorted().distinct().map { uuid -> + val rankHistory = LinkedHashMap() + teamlerRankChanges + .filter { teamlerRankChange -> teamlerRankChange.uuid == uuid } + .forEach { + if (rankHistory.isEmpty()) { + rankHistory["initial"] = it.rankFrom + } + rankHistory[it.getReadableDate()] = it.rankTo + } + Teamler(uuid, Sex.undefined, null, null, null, rankHistory) + }.toList() + JsonBuilder.getTeamlerResponsibilities().forEach { responsibilities -> + val teamler = teamlers.find { teamler1 -> teamler1.uuid == responsibilities.uuid } ?: Teamler ( + uuid = responsibilities.uuid, + sex = Sex.undefined, + responsibilitiesMain = null, + responsibilitiesSecondary = null, + fields = null, + rankHistory = null + ) + println("teamler: $teamler") + if (responsibilities.hv != null) { + println("responsibilities.getHv(): " + responsibilities.hv) + teamler.responsibilitiesMain = responsibilities.hv.split(", ") + } + if (responsibilities.nv != null) { + teamler.responsibilitiesSecondary = responsibilities.nv.split(", ") + } + } + println(Dapp.gson.toJson(teamlers)) + } +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/conversion/JsonBuilder.java b/howto-dapp/src/main/java/de/timolia/howto/conversion/JsonBuilder.java deleted file mode 100644 index 9d8374ed..00000000 --- a/howto-dapp/src/main/java/de/timolia/howto/conversion/JsonBuilder.java +++ /dev/null @@ -1,90 +0,0 @@ -package de.timolia.howto.conversion; - -import de.timolia.howto.conversion.models.TeamlerRankChange; -import de.timolia.howto.conversion.models.TeamlerResponsibilities; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Pattern; - -public class JsonBuilder { - - public static List getTeamlerRankChanges() throws IOException, ParseException { - String content = Files.readString(Path.of("src/main/resources", "changes.md"), StandardCharsets.UTF_8); - content = Pattern.compile("^([^|]|\\| ------|\\| Spieler).*$", Pattern.MULTILINE).matcher(content).replaceAll(""); - content = Pattern.compile("(\r\n)+", Pattern.MULTILINE).matcher(content).replaceAll("\n"); - content = Pattern.compile("[ \t]*\\|[ \t]*", Pattern.MULTILINE).matcher(content).replaceAll("|"); - content = Pattern.compile("", Pattern.MULTILINE).matcher(content).replaceAll(""); - content = Pattern.compile("", Pattern.MULTILINE).matcher(content).replaceAll(""); - - List teamlerRankChanges = new ArrayList<>(); - String[] lines = content.split("\n"); - for (int i = lines.length - 1; i >= 0; i--) { - String line = lines[i]; - - if (line.isEmpty()) { - continue; - } - - String[] split = line.split("\\|"); - String name = split[1].replaceAll("\\\\", ""); - String rankFrom = split[2]; - String rankTo = split[3]; - String date = split[4]; - -// if(rankTo.contains("Supporter+")) { -// Thread.dumpStack(); -// } - - TeamlerRankChange teamlerRankChange = new TeamlerRankChange(name, rankFrom, rankTo, date); - teamlerRankChanges.add(teamlerRankChange); - System.out.println(teamlerRankChange); - } - - return teamlerRankChanges; - } - - public static List getTeamlerResponsibilities() throws IOException { - String content = Files.readString(Path.of("src/main/resources", "members.md"), StandardCharsets.UTF_8); - content = Pattern.compile("^(?!-|###).*$", Pattern.MULTILINE).matcher(content).replaceAll(""); - content = Pattern.compile("^- Rang \\(ingame\\):.*$", Pattern.MULTILINE).matcher(content).replaceAll(""); - content = Pattern.compile("(\r\n)+", Pattern.MULTILINE).matcher(content).replaceAll("\n"); - - List teamlerResponsibilitiesList = new ArrayList<>(); - for (String s : content.split("###")) { - if (s.isEmpty() || (!s.contains("Hauptverantwortlich") && !s.contains("Nebenverantwortlich"))) continue; - - s = s.substring(s.indexOf("'") + 1); - s = s.substring(s.indexOf("'") + 2); - - String name = s.substring(0, s.indexOf("<")).replaceAll("\\\\_", "_"); - String hv = null; - String nv = null; - - s = s.substring(s.indexOf("-")); - - if (s.contains("Hauptverantwortlich")) { - hv = s.substring(s.indexOf("Hauptverantwortlich") + "Hauptverantwortlich".length() + 6, s.indexOf("\n")); - s = s.substring(s.indexOf("Hauptverantwortlich") + "Hauptverantwortlich\n".length() + 6 + hv.length()); - } - if (s.contains("Nebenverantwortlich")) { - nv = s.substring(s.indexOf("Nebenverantwortlich") + "Nebenverantwortlich".length() + 6, s.indexOf("\n")); - } - - System.out.println("name: " + name); - System.out.println("hv: " + hv); - System.out.println("nv: " + nv); - - TeamlerResponsibilities teamlerResponsibilities = new TeamlerResponsibilities(name, hv, nv); - teamlerResponsibilitiesList.add(teamlerResponsibilities); - } - - return teamlerResponsibilitiesList; - } - -} diff --git a/howto-dapp/src/main/java/de/timolia/howto/conversion/JsonBuilder.kt b/howto-dapp/src/main/java/de/timolia/howto/conversion/JsonBuilder.kt new file mode 100644 index 00000000..3810083f --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/conversion/JsonBuilder.kt @@ -0,0 +1,59 @@ +package de.timolia.howto.conversion + +import de.timolia.howto.rank.TeamlerRankChange +import java.io.IOException +import java.nio.file.Files +import java.nio.file.Path +import java.text.ParseException +import java.util.* +import java.util.regex.Pattern +import kotlin.Throws + +object JsonBuilder { + @Throws(IOException::class, ParseException::class) + fun getTeamlerRankChanges(): List { + var content = Files.readString(Path.of("src/main/resources", "changes.md")) + content = Pattern.compile("^([^|]|\\| ------|\\| Spieler).*$", Pattern.MULTILINE).matcher(content).replaceAll("") + content = Pattern.compile("(\r\n)+", Pattern.MULTILINE).matcher(content).replaceAll("\n") + content = Pattern.compile("[ \t]*\\|[ \t]*", Pattern.MULTILINE).matcher(content).replaceAll("|") + content = Pattern.compile("", Pattern.MULTILINE).matcher(content).replaceAll("") + content = Pattern.compile("", Pattern.MULTILINE).matcher(content).replaceAll("") + return content.split("\n").reversed().filter(String::isNotEmpty).map { + var (_, name, rankFrom, rankTo, date) = it.split("|") + name = name.replace("\\", "") + val teamlerRankChange = TeamlerRankChange(name, rankFrom, rankTo, date) + println(teamlerRankChange) + teamlerRankChange + } + } + + @Throws(IOException::class) + fun getTeamlerResponsibilities(): Iterable { + var content = Files.readString(Path.of("src/main/resources", "members.md")) + content = Pattern.compile("^(?!-|###).*$", Pattern.MULTILINE).matcher(content).replaceAll("") + content = Pattern.compile("^- Rang \\(ingame\\):.*$", Pattern.MULTILINE).matcher(content).replaceAll("") + content = Pattern.compile("(\r\n)+", Pattern.MULTILINE).matcher(content).replaceAll("\n") + return content.split("###") + .filter { it.contains("Hauptverantwortlich") || it.contains("Nebenverantwortlich") } + .map {s -> + var s = s + s = s.substring(s.indexOf("'") + 1) + s = s.substring(s.indexOf("'") + 2) + val name: String = s.substring(0, s.indexOf("<")).replace("\\\\_".toRegex(), "_") + var hv: String? = null + var nv: String? = null + s = s.substring(s.indexOf("-")) + if (s.contains("Hauptverantwortlich")) { + hv = s.substring(s.indexOf("Hauptverantwortlich") + "Hauptverantwortlich".length + 6, s.indexOf("\n")) + s = s.substring(s.indexOf("Hauptverantwortlich") + "Hauptverantwortlich\n".length + 6 + hv.length) + } + if (s.contains("Nebenverantwortlich")) { + nv = s.substring(s.indexOf("Nebenverantwortlich") + "Nebenverantwortlich".length + 6, s.indexOf("\n")) + } + println("name: $name") + println("hv: $hv") + println("nv: $nv") + TeamlerResponsibilities(name, hv, nv) + } + } +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/conversion/RankConversion.java b/howto-dapp/src/main/java/de/timolia/howto/conversion/RankConversion.java deleted file mode 100644 index ad0461db..00000000 --- a/howto-dapp/src/main/java/de/timolia/howto/conversion/RankConversion.java +++ /dev/null @@ -1,81 +0,0 @@ -package de.timolia.howto.conversion; - -import de.timolia.howto.models.Rank; - -import java.util.Arrays; -import java.util.Comparator; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -public class RankConversion { - - public static Rank getRank(String text) { - Map.Entry result = Arrays.stream(Rank.values()) - .collect(Collectors.toMap(Function.identity(), rank -> Math.max(getSimilarity(text, rank.getFemale()), getSimilarity(text, rank.getMale())))) - .entrySet() - .stream() - .max(Comparator.comparingDouble(Map.Entry::getValue)) - .filter(e -> e.getValue() > 0.1) - .orElse(null); - //System.out.println(result.getValue() + ": " + result.getKey().getName()); - - if (result == null) { - return null; - } - return result.getKey(); - - // < 0.1 - //return Arrays.stream(Scenarios.values()).min((o1, o2) -> Double.compare(TextUtils.getSimilarity(text, o2.getName()), TextUtils.getSimilarity(text, o1.getName()))).orElse(null); - } - - /** - * Calculates the similarity (a number within 0 and 1) between two strings. - */ - public static double getSimilarity(String s1, String s2) { - String longer = s1, shorter = s2; - if (s1.length() < s2.length()) { // longer should always have greater length - longer = s2; - shorter = s1; - } - int longerLength = longer.length(); - if (longerLength == 0) { - return 1.0; /* both strings are zero length */ - } - /* // If you have Apache Commons Text, you can use it to calculate the edit distance: - LevenshteinDistance levenshteinDistance = new LevenshteinDistance(); - return (longerLength - levenshteinDistance.apply(longer, shorter)) / (double) longerLength; */ - return (longerLength - editDistance(longer, shorter)) / (double) longerLength; - - } - - // Example implementation of the Levenshtein Edit Distance - // See http://rosettacode.org/wiki/Levenshtein_distance#Java - private static int editDistance(String s1, String s2) { - s1 = s1.toLowerCase(); - s2 = s2.toLowerCase(); - - int[] costs = new int[s2.length() + 1]; - for (int i = 0; i <= s1.length(); i++) { - int lastValue = i; - for (int j = 0; j <= s2.length(); j++) { - if (i == 0) - costs[j] = j; - else { - if (j > 0) { - int newValue = costs[j - 1]; - if (s1.charAt(i - 1) != s2.charAt(j - 1)) - newValue = Math.min(Math.min(newValue, lastValue), - costs[j]) + 1; - costs[j - 1] = lastValue; - lastValue = newValue; - } - } - } - if (i > 0) - costs[s2.length()] = lastValue; - } - return costs[s2.length()]; - } - -} diff --git a/howto-dapp/src/main/java/de/timolia/howto/conversion/SQLApi.java b/howto-dapp/src/main/java/de/timolia/howto/conversion/SQLApi.java deleted file mode 100644 index 3f45f48b..00000000 --- a/howto-dapp/src/main/java/de/timolia/howto/conversion/SQLApi.java +++ /dev/null @@ -1,80 +0,0 @@ -package de.timolia.howto.conversion; - -import de.timolia.howto.Dapp; - -import java.sql.*; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -public class SQLApi { - - private static Connection connection; - private static final Map usernames = new HashMap<>(); - private static final Map uuids = new HashMap<>(); - - private static void establishConnection() throws SQLException { - if (connection == null) { - connection = DriverManager.getConnection(Dapp.MYSQL_CON_STR, Dapp.MYSQL_USER, Dapp.MYSQL_PASS); - } - } - - - public static UUID getUuid(String name) { - if (usernames.containsKey(name)) { - return usernames.get(name); - } - - System.out.print("Fetching UUID of '" + name + "'... "); - try { - establishConnection(); - PreparedStatement prepareStatement = connection.prepareStatement("SELECT uuid FROM timolia_user_names WHERE name=? ORDER BY last_played DESC LIMIT 1"); - prepareStatement.setString(1, name); - ResultSet resultSet = prepareStatement.executeQuery(); - resultSet.next(); - - UUID uuid = UUID.fromString(resultSet.getString("uuid")); - usernames.put(name, uuid); - System.out.println("'" + uuid + "'"); - return uuid; - } catch (SQLException e) { - e.printStackTrace(); - throw new RuntimeException("Cannot find UUID of '" + name + "'"); - } - } - - public static String getName(UUID uuid) { - return getName(uuid, null); - } - - public static String getName(UUID uuid, String fallback) { - if (uuids.containsKey(uuid)) { - return uuids.get(uuid); - } - - System.out.print("Fetching name of '" + uuid + "'... "); - try { - establishConnection(); - //PreparedStatement prepareStatement = connection.prepareStatement("SELECT * FROM timolia_user_names WHERE uuid=? ORDER BY last_played DESC LIMIT 1"); - PreparedStatement prepareStatement = connection.prepareStatement("SELECT * FROM timolia_user WHERE uuid=?"); - prepareStatement.setString(1, uuid.toString()); - ResultSet resultSet = prepareStatement.executeQuery(); - resultSet.next(); - - String name = resultSet.getString("name"); - uuids.put(uuid, name); - System.out.println(name); - return name; - } catch (SQLException e) { - if (Dapp.isDevEnv && fallback != null) { - System.err.println("Cannot find name of '" + uuid + "', using '" + fallback + "'"); - uuids.put(uuid, fallback); - return fallback; - } - - e.printStackTrace(); - throw new RuntimeException("Cannot find name of '" + uuid + "'"); - } - } - -} diff --git a/howto-dapp/src/main/java/de/timolia/howto/conversion/TeamlerResponsibilities.kt b/howto-dapp/src/main/java/de/timolia/howto/conversion/TeamlerResponsibilities.kt new file mode 100644 index 00000000..562f37be --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/conversion/TeamlerResponsibilities.kt @@ -0,0 +1,21 @@ +package de.timolia.howto.conversion + +import de.timolia.howto.database.SQLApi +import java.util.* + +class TeamlerResponsibilities( + private val name: String?, + val hv: String?, + val nv: String? +) { + val uuid: UUID = SQLApi.getUuid(name)!! + + override fun toString(): String { + return "TeamlerResponsibilities{" + + "name='" + name + '\'' + + ", uuid=" + uuid + + ", hv='" + hv + '\'' + + ", nv='" + nv + '\'' + + '}' + } +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/conversion/models/TeamlerRankChange.java b/howto-dapp/src/main/java/de/timolia/howto/conversion/models/TeamlerRankChange.java deleted file mode 100644 index 3ab94a2f..00000000 --- a/howto-dapp/src/main/java/de/timolia/howto/conversion/models/TeamlerRankChange.java +++ /dev/null @@ -1,112 +0,0 @@ -package de.timolia.howto.conversion.models; - -import de.timolia.howto.conversion.RankConversion; -import de.timolia.howto.conversion.SQLApi; -import de.timolia.howto.models.Rank; -import org.apache.commons.lang3.Validate; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.UUID; - -public class TeamlerRankChange { - - private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd.MM.yyyy"); - - private final String name; - private final UUID uuid; - private final Rank rankFrom; - private final Rank rankTo; - private final Date date; - private final transient boolean hidden; - - public TeamlerRankChange(String name, String rankFrom, String rankTo, String date) throws ParseException { - this.name = name; - this.uuid = SQLApi.getUuid(name); - this.rankFrom = RankConversion.getRank(rankFrom); - this.rankTo = RankConversion.getRank(rankTo); - this.date = simpleDateFormat.parse(date); - this.hidden = false; - - Validate.notNull(this.rankFrom, "Der Rang von '" + name + "' ('" + rankFrom + "') existiert nicht"); - Validate.notNull(this.rankTo, "Der Rang von '" + name + "' ('" + rankTo + "') existiert nicht"); - } - - public TeamlerRankChange(String name, UUID uuid, Rank rankFrom, Rank rankTo, String date, boolean hidden) { - this.name = SQLApi.getName(uuid, name); - this.uuid = uuid; - this.rankFrom = rankFrom; - this.rankTo = rankTo; - this.date = toDate(date); - this.hidden = hidden; - - Validate.notNull(this.rankFrom, "Der Rang von '" + name + "' existiert nicht"); - Validate.notNull(this.rankTo, "Der Rang von '" + name + "' existiert nicht"); - } - - - public String getName() { - return name; - } - - public String getNameForMarkdown() { - return name.replaceAll("_", "\\\\_"); - } - - public UUID getUuid() { - return uuid; - } - - public Rank getRankFrom() { - return rankFrom; - } - - public Rank getRankTo() { - return rankTo; - } - - public Date getDate() { - return date; - } - - public boolean isHidden() { - return hidden; - } - - public String getReadableDate() { - return simpleDateFormat.format(date); - } - - public static String toString(Date date) { - if (date.equals(new Date(0))) { - return "initial"; - } - return simpleDateFormat.format(date); - } - - public static Date toDate(String date) { - if (date.equals("initial")) { - return new Date(0); - } - - try { - return simpleDateFormat.parse(date); - } catch (ParseException e) { - throw new RuntimeException(e); - } - } - - - @Override - public String toString() { - return "TeamlerRankChange{" + - "name='" + name + '\'' + - ", uuid=" + uuid + - ", rankFrom='" + rankFrom + '\'' + - ", rankTo='" + rankTo + '\'' + - ", date=" + simpleDateFormat.format(date) + - '}'; - } - -} diff --git a/howto-dapp/src/main/java/de/timolia/howto/conversion/models/TeamlerResponsibilities.java b/howto-dapp/src/main/java/de/timolia/howto/conversion/models/TeamlerResponsibilities.java deleted file mode 100644 index c4c452d7..00000000 --- a/howto-dapp/src/main/java/de/timolia/howto/conversion/models/TeamlerResponsibilities.java +++ /dev/null @@ -1,49 +0,0 @@ -package de.timolia.howto.conversion.models; - -import de.timolia.howto.conversion.SQLApi; - -import java.util.UUID; - -public class TeamlerResponsibilities { - - private final String name; - private final UUID uuid; - private final String hv; - private final String nv; - - public TeamlerResponsibilities(String name, String hv, String nv) { - this.name = name; - this.uuid = SQLApi.getUuid(name); - this.hv = hv; - this.nv = nv; - } - - - public String getName() { - return name; - } - - public UUID getUuid() { - return uuid; - } - - public String getHv() { - return hv; - } - - public String getNv() { - return nv; - } - - - @Override - public String toString() { - return "TeamlerResponsibilities{" + - "name='" + name + '\'' + - ", uuid=" + uuid + - ", hv='" + hv + '\'' + - ", nv='" + nv + '\'' + - '}'; - } - -} diff --git a/howto-dapp/src/main/java/de/timolia/howto/database/SQLApi.kt b/howto-dapp/src/main/java/de/timolia/howto/database/SQLApi.kt new file mode 100644 index 00000000..daf56cc2 --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/database/SQLApi.kt @@ -0,0 +1,61 @@ +package de.timolia.howto.database + +import java.sql.SQLException +import java.util.* +import kotlin.jvm.Volatile + +object SQLApi { + @Volatile + private var connection: SqlUserConnection? = null + + @Volatile + private var triedConnect = false + + private fun establishConnection(): SqlUserConnection { + if (!triedConnect) { + synchronized(SQLApi::class.java) { + if (!triedConnect) { + tryGuardedConnect() + } + } + } + return connection ?: throw RuntimeException("Earlier attempt connecting to sql failed") + } + + private fun tryGuardedConnect() { + try { + connection = SqlUserConnection.connect() + } catch (exception: SQLException) { + throw RuntimeException("Unable to establish sql connection", exception) + } finally { + triedConnect = true + } + } + + fun getUuid(name: String?): UUID? { + return try { + establishConnection().getUuid(name) + } catch (exception: RuntimeException) { + exception.printStackTrace() + throw exception + } + } + + fun getName(uuid: UUID?): String? { + return getName(uuid, null) + } + + fun getName(uuid: UUID?, fallback: String?): String? { + val connection: SqlUserConnection = try { + establishConnection() + } catch (exception: RuntimeException) { + if (fallback != null && SqlUserConnection.isDevEnv()) { + System.err.println("Unable to establish sql connection for $uuid fallback to $fallback") + exception.printStackTrace() + return fallback + } + throw RuntimeException("Unable to establish sql connection", exception) + } + return connection.getName(uuid, fallback) + } +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/database/SqlUserConnection.kt b/howto-dapp/src/main/java/de/timolia/howto/database/SqlUserConnection.kt new file mode 100644 index 00000000..324aba9b --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/database/SqlUserConnection.kt @@ -0,0 +1,65 @@ +package de.timolia.howto.database + +import java.sql.* +import java.util.* + +class SqlUserConnection private constructor(private val connection: Connection) { + private val usernames: MutableMap = HashMap() + private val uuids: MutableMap = HashMap() + + fun getUuid(name: String?): UUID? { + return usernames.computeIfAbsent(name, ::resolveUniqueId) + } + + private fun resolveUniqueId(name: String?): UUID { + return try { + val prepareStatement = connection.prepareStatement("SELECT uuid FROM timolia_user_names WHERE name=? ORDER BY last_played DESC LIMIT 1") + prepareStatement.setString(1, name) + val resultSet = prepareStatement.executeQuery() + if (!resultSet.next()) { + throw RuntimeException("Cannot find UUID of '$name'") + } + UUID.fromString(resultSet.getString("uuid")) + } catch (exception: SQLException) { + throw RuntimeException("Failed to fetch uuid for name=$name'", exception) + } + } + + fun getName(uuid: UUID?, fallback: String?): String? { + return uuids.computeIfAbsent(uuid) { uniqueId: UUID? -> resolveName(uniqueId, fallback) } + } + + private fun resolveName(uuid: UUID?, fallback: String?): String? { + try { + val prepareStatement = connection.prepareStatement("SELECT * FROM timolia_user WHERE uuid=?") + prepareStatement.setString(1, uuid.toString()) + val resultSet = prepareStatement.executeQuery() + if (resultSet.next()) { + return resultSet.getString("name") + } + if (fallback != null) { + println("No name for uuid $uuid falling back to $fallback") + return fallback + } + throw RuntimeException("Cannot find name of '$uuid'") + } catch (exception: SQLException) { + throw RuntimeException("Failed to fetch uuid for uuid=$uuid'", exception) + } + } + + companion object { + @Throws(SQLException::class) + fun connect(): SqlUserConnection { + val environmentSuffix = if (isDevEnv()) "DEV" else "LIVE" + val user = System.getenv("MYSQL_USER_$environmentSuffix") + val password = System.getenv("MYSQL_PASS_$environmentSuffix") + val connectionString = System.getenv("MYSQL_CON_STR_$environmentSuffix") + val connection = DriverManager.getConnection(connectionString, user, password) + return SqlUserConnection(connection) + } + + fun isDevEnv(): Boolean { + return System.getenv("MYSQL_USER_LIVE") == null + } + } +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/generator/FileWriter.kt b/howto-dapp/src/main/java/de/timolia/howto/generator/FileWriter.kt new file mode 100644 index 00000000..4e490038 --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/generator/FileWriter.kt @@ -0,0 +1,31 @@ +package de.timolia.howto.generator + +import de.timolia.howto.translate.Language +import de.timolia.howto.translate.Translate +import java.io.IOException +import java.nio.charset.Charset +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.StandardOpenOption +import kotlin.Throws + +class FileWriter(private val path: Path, private val translate: Translate) { + @Throws(IOException::class) + fun writeFile(name: String, text: String) { + for (language in Language.values()) { + val translation = translate.forLanguage(language) + val fileName = name + "." + language.key() + ".md" + val content = translation.replaceAll(text) + writeFile(path.resolve(fileName), content) + } + } + + companion object { + @Throws(IOException::class) + private fun writeFile(path: Path, text: String) { + path.toFile().parentFile.mkdirs() + Files.writeString(path, text, Charset.defaultCharset(), StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE) + println("Wrote file '$path'") + } + } +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/generator/PageRankChange.java b/howto-dapp/src/main/java/de/timolia/howto/generator/PageRankChange.java deleted file mode 100644 index 8e4a08a3..00000000 --- a/howto-dapp/src/main/java/de/timolia/howto/generator/PageRankChange.java +++ /dev/null @@ -1,83 +0,0 @@ -package de.timolia.howto.generator; - -import de.timolia.howto.conversion.models.TeamlerRankChange; -import de.timolia.howto.models.Teamler; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.List; -import java.util.Locale; - -public class PageRankChange { - - public static String generate(List teamlers) { - - ArrayList rankChanges = new ArrayList<>(); - for (Teamler teamler : teamlers) { - rankChanges.addAll(teamler.getRankChanges(false)); - } - - rankChanges.sort((t1, t2) -> { - if (!t1.getDate().equals(t2.getDate())) { - return t2.getDate().compareTo(t1.getDate()); - } -// if(t1.getRankFrom().equals(t2.getRankFrom())) { -// Teamler teamler1 = teamlers.stream().filter(t -> t.getUuid().equals(t1.getUuid())).findFirst().orElse(null); -// Teamler teamler2 = teamlers.stream().filter(t -> t.getUuid().equals(t2.getUuid())).findFirst().orElse(null); -// return t1.getRankFrom().getString(teamler1.getSex()).compareToIgnoreCase(t2.getRankFrom().getString(teamler2.getSex())); -// } - if (!t1.getRankTo().equals(t2.getRankTo())) { - Teamler teamler1 = teamlers.stream().filter(t -> t.getUuid().equals(t1.getUuid())).findFirst().orElse(null); - Teamler teamler2 = teamlers.stream().filter(t -> t.getUuid().equals(t2.getUuid())).findFirst().orElse(null); - return t1.getRankTo().getString(teamler1.getSex()).compareToIgnoreCase(t2.getRankTo().getString(teamler2.getSex())); - } - return t1.getName().compareToIgnoreCase(t2.getName()); - }); - - StringBuilder sb = new StringBuilder(); - sb - .append("%page.rank-change.first%") - .append("\n") - .append("\n"); - - String lastYear = ""; - String lastMonth = ""; - for (TeamlerRankChange teamlerRankChange : rankChanges) { - Teamler teamler = teamlers.stream().filter(t -> t.getUuid().equals(teamlerRankChange.getUuid())).findFirst().orElse(null); - - Calendar cal = Calendar.getInstance(); - cal.setTime(teamlerRankChange.getDate()); - String month = cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.GERMAN) + " " + cal.get(Calendar.YEAR); - String year = cal.get(Calendar.YEAR) + ""; - - if (!year.equals(lastYear)) { - lastYear = year; - sb.append("\n").append("\n").append("# ").append(year).append("\n"); - } - if (!month.equals(lastMonth)) { - lastMonth = month; - sb.append("\n"); - sb.append("### ").append(month).append("").append("\n"); - sb.append("| %player% | %page.rank-change.rank-previous% | %page.rank-change.rank-new% | %date% |").append("\n"); - sb.append("| ------ | ------ | ------ | ------ |").append("\n"); - } - - sb - .append("| ") - .append(teamlerRankChange.getNameForMarkdown()) - .append(" | ") - .append("").append(teamlerRankChange.getRankFrom().getString(teamler.getSex())).append("") - .append(" | ") - .append("").append(teamlerRankChange.getRankTo().getString(teamler.getSex())).append("") - .append(" | ") - .append(teamlerRankChange.getReadableDate()) - .append(" |") - .append("\n"); - //sb.append(teamlerRankChange).append("\n"); - } - - sb.append("\n"); - - return sb.toString(); - } -} diff --git a/howto-dapp/src/main/java/de/timolia/howto/generator/PageRankChange.kt b/howto-dapp/src/main/java/de/timolia/howto/generator/PageRankChange.kt new file mode 100644 index 00000000..7af16500 --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/generator/PageRankChange.kt @@ -0,0 +1,64 @@ +package de.timolia.howto.generator + +import de.timolia.howto.rank.TeamlerRankChange +import de.timolia.howto.teamler.Sex +import de.timolia.howto.teamler.Teamler +import java.util.* + +object PageRankChange { + fun generate(teamlers: List): String { + val rankChanges = arrayListOf() + for (teamler in teamlers) { + rankChanges.addAll(teamler.getRankChanges(false)) + } + rankChanges.sortWith { t1, t2 -> + if (t1.date != t2.date) { + return@sortWith t2.date.compareTo(t1.date) + } + if (t1.rankTo != t2.rankTo) { + val teamler1 = teamlers.firstOrNull { t -> t.uuid == t1.uuid } + val teamler2 = teamlers.firstOrNull { t -> t.uuid == t2.uuid } + return@sortWith t1.rankTo.getString(teamler1?.sex ?: Sex.undefined).compareTo(t2.rankTo.getString(teamler2?.sex ?: Sex.undefined), ignoreCase = true) + } + t1.name.compareTo(t2.name, ignoreCase = true) + } + val sb = StringBuilder() + sb + .append("%page.rank-change.first%") + .append("\n") + .append("\n") + var lastYear: String? = "" + var lastMonth: String? = "" + for (teamlerRankChange in rankChanges) { + val teamler = teamlers.firstOrNull { t -> t.uuid == teamlerRankChange.uuid } + val cal = Calendar.getInstance() + cal.time = teamlerRankChange.date + val month = cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.GERMAN) + " " + cal[Calendar.YEAR] + val year = cal[Calendar.YEAR].toString() + if (year != lastYear) { + lastYear = year + sb.append("\n").append("\n").append("# ").append(year).append("\n") + } + if (month != lastMonth) { + lastMonth = month + sb.append("\n") + sb.append("### ").append(month).append("").append("\n") + sb.append("| %player% | %page.rank-change.rank-previous% | %page.rank-change.rank-new% | %date% |").append("\n") + sb.append("| ------ | ------ | ------ | ------ |").append("\n") + } + sb + .append("| ") + .append(teamlerRankChange.getNameForMarkdown()) + .append(" | ") + .append("").append(teamlerRankChange.rankFrom.getString(teamler?.sex ?: Sex.undefined)).append("") + .append(" | ") + .append("").append(teamlerRankChange.rankTo.getString(teamler?.sex ?: Sex.undefined)).append("") + .append(" | ") + .append(teamlerRankChange.getReadableDate()) + .append(" |") + .append("\n") + } + sb.append("\n") + return sb.toString() + } +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/generator/PageResponsibilities.java b/howto-dapp/src/main/java/de/timolia/howto/generator/PageResponsibilities.java deleted file mode 100644 index 65f196c9..00000000 --- a/howto-dapp/src/main/java/de/timolia/howto/generator/PageResponsibilities.java +++ /dev/null @@ -1,171 +0,0 @@ -package de.timolia.howto.generator; - -import de.timolia.howto.LanguageUtil; -import de.timolia.howto.Utils; -import de.timolia.howto.models.Language; -import de.timolia.howto.models.Teamler; - -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -public class PageResponsibilities { - - public static String generate(List teamlers) { - - LinkedHashMap> responsibilities = new LinkedHashMap<>() {{ - put("%page.responsibilities.project-team-orga%", new LinkedHashMap<>() {{ - put("%page.responsibilities.teamleader%", "%page.responsibilities.teamleader.desc%"); - put("%page.responsibilities.project-team-orga.apply.builder%", null); - put("%page.responsibilities.project-team-orga.apply.development%", null); - put("%page.responsibilities.project-team-orga.apply.support%", "%page.responsibilities.project-team-orga.apply.support.desc%"); - put("%page.responsibilities.project-team-orga.howto%", "%page.responsibilities.project-team-orga.howto.desc%"); - put("%page.responsibilities.project-team-orga.tournament%", "%page.responsibilities.project-team-orga.tournament.desc%"); - //put("%page.responsibilities.project-team-orga.uhc%", "%page.responsibilities.project-team-orga.uhc.desc%"); - put("%page.responsibilities.project-team-orga.youtuber%", "%page.responsibilities.project-team-orga.youtuber.desc%"); - }}); - put("%page.responsibilities.communication-platforms%", new LinkedHashMap<>() {{ - put("%page.responsibilities.communication-platforms.community-discord%", "%page.responsibilities.communication-platforms.community-discord.desc%"); - //put("%page.responsibilities.communication-platforms.bug-reports%", null); - put("%page.responsibilities.communication-platforms.appeal%", null); - put("%page.responsibilities.communication-platforms.falsely-banned%", null); - put("%page.responsibilities.communication-platforms.socialmedia%", "%page.responsibilities.communication-platforms.socialmedia.desc%"); - put("%page.responsibilities.communication-platforms.teamspeak%", "%page.responsibilities.communication-platforms.teamspeak.desc%"); - }}); - put("%page.responsibilities.other-responsibilities%", new LinkedHashMap<>() {{ - put("%page.responsibilities.other-responsibilities.graphicdesign%", null); - put("%page.responsibilities.other-responsibilities.map-submissions%", null); - put("%page.responsibilities.other-responsibilities.monthly-winner%", null); - //put("%page.responsibilities.other-responsibilities.translation%", null); - }}); - }}; - - StringBuilder sb = new StringBuilder(); - sb.append("%page.responsibilities.info%"); - - for (Map.Entry> categories : responsibilities.entrySet()) { - String categoryName = categories.getKey(); - LinkedHashMap subcategories = categories.getValue(); - - sb - .append("\n") - .append("\n").append("# ").append(categoryName); - - for (Map.Entry e : subcategories.entrySet()) { - String name = LanguageUtil.translate(Language.DE, e.getKey()); - String description = e.getValue(); - - sb - .append("\n") - .append("\n").append("### **").append(name).append("**"); - if (description != null) { - sb.append("\n").append(description).append("\n"); - } - - List hv = teamlers.stream() - .filter(teamler -> teamler.hasResponsibilityMain(name)) - .sorted(Teamler::compare) - .collect(Collectors.toList()); - List nv = teamlers.stream() - .filter(teamler -> teamler.hasResponsibilitySecondary(name)) - .sorted(Teamler::compare) - .collect(Collectors.toList()); - - String titleCustom = null; - - LinkedList> hvCustom = new LinkedList<>(); - LinkedList> nvCustom = new LinkedList<>(); - - // custom stuff - if (e.getKey().equals("%page.responsibilities.bug-reports%")) { - nvCustom.add(new Utils.KeyValuePair<>("%page.responsibilities.custom.bug-reports.modsanddevs%", null)); - } else if (e.getKey().equals("%page.responsibilities.sm%")) { - titleCustom = "Projekte u. Verantwortungsgrad"; - for (Teamler teamler : teamlers.stream().filter(teamler -> teamler.hasResponsibilityMain("Twitter")).sorted(Teamler::compare).collect(Collectors.toList())) { - nvCustom.add(new Utils.KeyValuePair<>("|" + teamler.getNameForMarkdown() + "", "%page.responsibilities.custom.sm.twitter.hv%")); - } - for (Teamler teamler : teamlers.stream().filter(teamler -> teamler.hasResponsibilitySecondary("Twitter")).sorted(Teamler::compare).collect(Collectors.toList())) { - nvCustom.add(new Utils.KeyValuePair<>("|" + teamler.getNameForMarkdown() + "", "%page.responsibilities.custom.sm.twitter.nv%")); - } - for (Teamler teamler : teamlers.stream().filter(teamler -> teamler.hasResponsibilityMain("Bauteam-Twitter")).sorted(Teamler::compare).collect(Collectors.toList())) { - nvCustom.add(new Utils.KeyValuePair<>("|" + teamler.getNameForMarkdown() + "", "%page.responsibilities.custom.sm.twitter-builder.hv%")); - } - for (Teamler teamler : teamlers.stream().filter(teamler -> teamler.hasResponsibilitySecondary("Bauteam-Twitter")).sorted(Teamler::compare).collect(Collectors.toList())) { - nvCustom.add(new Utils.KeyValuePair<>("|" + teamler.getNameForMarkdown() + "", "%page.responsibilities.custom.sm.twitter-builder.nv%")); - } - } else if (e.getKey().equals("%page.responsibilities.teamleader%")) { - titleCustom = "%page.responsibilities.custom.teamleader.title%"; - // |J4mPr0 | Management des gesamten Timolia-Teams | - // |Jukplays | Management des Bau-Teams | - for (Teamler teamler : teamlers.stream().filter(teamler -> teamler.hasResponsibilityMain("Management des Timolia-Teams")).sorted(Teamler::compare).collect(Collectors.toList())) { - hvCustom.add(new Utils.KeyValuePair<>("|" + teamler.getNameForMarkdown() + "", "%page.responsibilities.custom.teamleader.whole-team%")); - } - for (Teamler teamler : teamlers.stream().filter(teamler -> teamler.hasResponsibilityMain("Management des Bau-Teams")).sorted(Teamler::compare).collect(Collectors.toList())) { - hvCustom.add(new Utils.KeyValuePair<>("|" + teamler.getNameForMarkdown() + "", "%page.responsibilities.custom.teamleader.builder%")); - } - for (Teamler teamler : teamlers.stream().filter(teamler -> teamler.hasResponsibilityMain("Management des Content-Teams")).sorted(Teamler::compare).collect(Collectors.toList())) { - hvCustom.add(new Utils.KeyValuePair<>("|" + teamler.getNameForMarkdown() + "", "%page.responsibilities.custom.teamleader.content%")); - } - for (Teamler teamler : teamlers.stream().filter(teamler -> teamler.hasResponsibilityMain("Management des Development-Teams")).sorted(Teamler::compare).collect(Collectors.toList())) { - hvCustom.add(new Utils.KeyValuePair<>("|" + teamler.getNameForMarkdown() + "", "%page.responsibilities.custom.teamleader.development%")); - } - } else if (e.getKey().equals("%page.responsibilities.yter%")) { - titleCustom = "%page.responsibilities.custom.yter.title%"; - } - - - if (titleCustom == null) { - sb.append("\n").append("| %page.responsibilities.teamler% | %page.responsibilities.responsib% |"); - } else { - sb.append("\n").append("| %page.responsibilities.teamler% | ").append(titleCustom).append(" |"); - } - - sb.append("\n").append("| ------ | ------ |"); - - if (hvCustom.isEmpty()) { - for (Teamler teamler : hv) { - sb.append("\n").append("|").append(teamler.getNameForMarkdown()).append(" | %page.responsibilities.hv% |"); - } - } else { - for (Utils.KeyValuePair hvEntry : hvCustom) { - String k = hvEntry.getKey(); - String v = hvEntry.getValue(); - if (v == null) { - sb.append("\n").append(k).append(" | %page.responsibilities.hv% |"); - } else { - sb.append("\n").append(k).append(" | ").append(v).append(" |"); - } - } - } - - if (!nv.isEmpty() || !nvCustom.isEmpty()) { - sb.append("\n").append("| | |"); - if (nvCustom.isEmpty()) { - for (Teamler teamler : nv) { - sb.append("\n").append("|").append(teamler.getNameForMarkdown()).append(" | %page.responsibilities.nv% |"); - } - } else { - for (Utils.KeyValuePair nvEntry : nvCustom) { - String k = nvEntry.getKey(); - String v = nvEntry.getValue(); - if (v == null) { - sb.append("\n").append("|").append(k).append(" | %page.responsibilities.nv% |"); - } else { - sb.append("\n").append(k).append(" | ").append(v).append(" |"); - } - } - } - } - - - } - } - - sb.append("\n"); - - return sb.toString(); - } - -} diff --git a/howto-dapp/src/main/java/de/timolia/howto/generator/PageResponsibilities.kt b/howto-dapp/src/main/java/de/timolia/howto/generator/PageResponsibilities.kt new file mode 100644 index 00000000..fa0769f4 --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/generator/PageResponsibilities.kt @@ -0,0 +1,137 @@ +package de.timolia.howto.generator + +import de.timolia.howto.Dapp +import de.timolia.howto.teamler.Teamler +import de.timolia.howto.responsibility.Responsibility +import de.timolia.howto.responsibility.ResponsibilityType +import de.timolia.howto.translate.Language +import java.util.* + +object PageResponsibilities { + fun generate(teamlers: List): String { + val responsibilities: LinkedHashMap> = object : LinkedHashMap>() { + init { + put("%page.responsibilities.project-team-orga%", object : LinkedHashMap() { + init { + put("%page.responsibilities.teamleader%", "%page.responsibilities.teamleader.desc%") + put("%page.responsibilities.project-team-orga.apply.builder%", null) + put("%page.responsibilities.project-team-orga.apply.development%", null) + put("%page.responsibilities.project-team-orga.apply.support%", "%page.responsibilities.project-team-orga.apply.support.desc%") + put("%page.responsibilities.project-team-orga.howto%", "%page.responsibilities.project-team-orga.howto.desc%") + put("%page.responsibilities.project-team-orga.tournament%", "%page.responsibilities.project-team-orga.tournament.desc%") + //put("%page.responsibilities.project-team-orga.uhc%", "%page.responsibilities.project-team-orga.uhc.desc%"); + put("%page.responsibilities.project-team-orga.youtuber%", "%page.responsibilities.project-team-orga.youtuber.desc%") + } + }) + put("%page.responsibilities.communication-platforms%", object : LinkedHashMap() { + init { + put("%page.responsibilities.communication-platforms.community-discord%", "%page.responsibilities.communication-platforms.community-discord.desc%") + //put("%page.responsibilities.communication-platforms.bug-reports%", null); + put("%page.responsibilities.communication-platforms.appeal%", null) + put("%page.responsibilities.communication-platforms.falsely-banned%", null) + put("%page.responsibilities.communication-platforms.socialmedia%", "%page.responsibilities.communication-platforms.socialmedia.desc%") + put("%page.responsibilities.communication-platforms.teamspeak%", "%page.responsibilities.communication-platforms.teamspeak.desc%") + } + }) + put("%page.responsibilities.other-responsibilities%", object : LinkedHashMap() { + init { + put("%page.responsibilities.other-responsibilities.graphicdesign%", null) + put("%page.responsibilities.other-responsibilities.map-submissions%", null) + put("%page.responsibilities.other-responsibilities.monthly-winner%", null) + //put("%page.responsibilities.other-responsibilities.translation%", null); + } + }) + } + } + val sb = StringBuilder() + sb.append("%page.responsibilities.info%") + for ((categoryName, subcategories) in responsibilities) { + sb + .append("\n") + .append("\n").append("# ").append(categoryName) + val nameConverter = Dapp.translate.forLanguage(Language.DE) + for (e in subcategories.entries) { + val name = nameConverter.replaceAll(e.key) + val description = e.value + sb.append("\n").append("\n").append("### **").append(name).append("**") + if (description != null) { + sb.append("\n").append(description).append("\n") + } + val hv = teamlers + .filter { teamler -> teamler.hasResponsibilityMain(name) } + .sortedWith { obj, o -> obj.compare(o) } + val nv = teamlers + .filter { teamler -> teamler.hasResponsibilitySecondary(name) } + .sortedWith { obj, o -> obj.compare(o) } + var titleCustom: String? = null + val hvCustom = LinkedList() + val nvCustom = LinkedList() + when (e.key) { + "%page.responsibilities.bug-reports%" -> nvCustom.add(Responsibility.simple(ResponsibilityType.NV, "%page.responsibilities.custom.bug-reports.modsanddevs%")) + "%page.responsibilities.sm%" -> { + titleCustom = "Projekte u. Verantwortungsgrad" + for (teamler in teamlers.filter { teamler -> teamler.hasResponsibilityMain("Twitter") }.sortedWith { obj, o -> obj.compare(o) }) { + nvCustom.add(Responsibility.concreteTeamster(teamler, "%page.responsibilities.custom.sm.twitter.hv%")) + } + for (teamler in teamlers.filter { teamler -> teamler.hasResponsibilitySecondary("Twitter") }.sortedWith { obj, o -> obj.compare(o) }) { + nvCustom.add(Responsibility.concreteTeamster(teamler, "%page.responsibilities.custom.sm.twitter.nv%")) + } + for (teamler in teamlers.filter { teamler -> teamler.hasResponsibilityMain("Bauteam-Twitter") }.sortedWith { obj, o -> obj.compare(o) }) { + nvCustom.add(Responsibility.concreteTeamster(teamler, "%page.responsibilities.custom.sm.twitter-builder.hv%")) + } + for (teamler in teamlers.filter { teamler -> teamler.hasResponsibilitySecondary("Bauteam-Twitter") }.sortedWith { obj, o -> obj.compare(o) }) { + nvCustom.add(Responsibility.concreteTeamster(teamler, "%page.responsibilities.custom.sm.twitter-builder.nv%")) + } + } + + "%page.responsibilities.teamleader%" -> { + titleCustom = "%page.responsibilities.custom.teamleader.title%" + for (teamler in teamlers.filter { teamler -> teamler.hasResponsibilityMain("Management des Timolia-Teams") }.sortedWith { obj, o -> obj.compare(o) }) { + hvCustom.add(Responsibility.concreteTeamster(teamler, "%page.responsibilities.custom.teamleader.whole-team%")) + } + for (teamler in teamlers.filter { teamler -> teamler.hasResponsibilityMain("Management des Bau-Teams") }.sortedWith { obj, o -> obj.compare(o) }) { + hvCustom.add(Responsibility.concreteTeamster(teamler, "%page.responsibilities.custom.teamleader.builder%")) + } + for (teamler in teamlers.filter { teamler -> teamler.hasResponsibilityMain("Management des Content-Teams") }.sortedWith { obj, o -> obj.compare(o) }) { + hvCustom.add(Responsibility.concreteTeamster(teamler, "%page.responsibilities.custom.teamleader.content%")) + } + for (teamler in teamlers.filter { teamler -> teamler.hasResponsibilityMain("Management des Development-Teams") }.sortedWith { obj, o -> obj.compare(o) }) { + hvCustom.add(Responsibility.concreteTeamster(teamler, "%page.responsibilities.custom.teamleader.development%")) + } + } + + "%page.responsibilities.yter%" -> titleCustom = "%page.responsibilities.custom.yter.title%" + } + if (titleCustom == null) { + sb.append("\n").append("| %page.responsibilities.teamler% | %page.responsibilities.responsib% |") + } else { + sb.append("\n").append("| %page.responsibilities.teamler% | ").append(titleCustom).append(" |") + } + sb.append("\n").append("| ------ | ------ |") + if (hvCustom.isEmpty()) { + for (teamler in hv) { + hvCustom.add(Responsibility.concreteTeamster(ResponsibilityType.HV, teamler)) + } + } + for (hvEntry in hvCustom) { + sb.append("\n") + hvEntry.renderTo(sb) + } + if (nv.isNotEmpty() || !nvCustom.isEmpty()) { + sb.append("\n") + if (nvCustom.isEmpty()) { + for (teamler in nv) { + hvCustom.add(Responsibility.concreteTeamster(ResponsibilityType.NV, teamler)) + } + } + for (nvEntry in nvCustom) { + sb.append("\n") + nvEntry.renderTo(sb) + } + } + } + } + sb.append("\n") + return sb.toString() + } +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/generator/PageTeamMembers.java b/howto-dapp/src/main/java/de/timolia/howto/generator/PageTeamMembers.java deleted file mode 100644 index 8164e085..00000000 --- a/howto-dapp/src/main/java/de/timolia/howto/generator/PageTeamMembers.java +++ /dev/null @@ -1,95 +0,0 @@ -package de.timolia.howto.generator; - -import de.timolia.howto.models.Rank; -import de.timolia.howto.models.Teamler; -import org.apache.commons.lang3.Validate; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -public class PageTeamMembers { - - public static String generate(List teamlers) { - - teamlers = teamlers.stream().filter(teamler -> teamler.getRankCurrent().isInTeam()).collect(Collectors.toList()); - - //return t1.getName().compareToIgnoreCase(t2.getName()); - teamlers.sort(Teamler::compare); - - List> a = teamlers.stream().collect(Collectors.groupingBy(Teamler::getRankCurrent, Collectors.counting())) - .entrySet().stream().sorted((e1, e2) -> e1.getKey().compare(e2.getKey())).collect(Collectors.toList()); - - - List ranks = Arrays.stream(Rank.values()).filter(rank -> rank.getDescription() != null).sorted(Rank::compare).collect(Collectors.toList()); - - StringBuilder sb = new StringBuilder(); - - sb.append("%page.members.first-1%").append(teamlers.size()).append("%page.members.first-2%\n"); - List rankStrings = ranks.stream().map(rank -> "" + rank.getMale() + "").collect(Collectors.toList()); - for (int i = 0; i < rankStrings.size(); i++) { - sb.append(rankStrings.get(i)); - if (i < rankStrings.size() - 2) { - sb.append(", "); - } else if (i == rankStrings.size() - 2) { - sb.append(" %and% "); - } - } - sb - .append("%page.members.first-3%") - .append("\n") - .append("\n").append("%page.members.first-4%") - .append("\n") - .append("\n").append("![%page.members.first-5%](img/content-ranks.png)"); - - for (Rank rank : ranks) { - - sb - .append("\n") - .append("\n") - .append("\n") - .append("\n").append("## ").append(rank.getMale()) - .append("\n") - .append("\n").append(rank.getDescription()) - .append("\n"); - - for (Teamler teamler : teamlers.stream().filter(teamler -> teamler.getRankCurrent().equals(rank)).collect(Collectors.toList())) { - - Validate.isTrue(teamler.getResponsibilitiesMain() == null || !teamler.getResponsibilitiesMain().contains(null), "Der Spieler '" + teamler.getName() + "' hat eine leere responsibilities_main, Komma zu viel?"); - Validate.isTrue(teamler.getResponsibilitiesMainHidden() == null || !teamler.getResponsibilitiesMainHidden().contains(null), "Der Spieler '" + teamler.getName() + "' hat eine leere responsibilities_main_hidden, Komma zu viel?"); - Validate.isTrue(teamler.getResponsibilitiesSecondary() == null || !teamler.getResponsibilitiesSecondary().contains(null), "Der Spieler '" + teamler.getName() + "' hat eine leere responsibilities_secondary, Komma zu viel?"); - Validate.isTrue(teamler.getResponsibilitiesSecondaryHidden() == null || !teamler.getResponsibilitiesSecondaryHidden().contains(null), "Der Spieler '" + teamler.getName() + "' hat eine leere responsibilities_secondary_hidden, Komma zu viel?"); - Validate.isTrue(teamler.getFields() == null || !teamler.getFields().contains(null), "Der Spieler '" + teamler.getName() + "' hat eine leere fields, Komma zu viel?"); - - sb - .append("\n") - .append("\n") - .append("### ").append(teamler.getNameForMarkdown()).append("") - .append("\n").append("- %page.members.rank-ingame%: ").append(rank.getString(teamler.getSex())); - if (teamler.getResponsibilitiesMain() != null) { - sb - .append("\n") - .append("- %page.members.hv%: ").append(teamler.getResponsibilitiesMain().stream().sorted(String::compareToIgnoreCase).collect(Collectors.joining(", "))); - //.append("- Hauptverantwortlich: ").append(String.join(", ", teamler.getResponsibilitiesMain())); - } - if (teamler.getResponsibilitiesSecondary() != null) { - sb - .append("\n") - .append("- %page.members.nv%: ").append(teamler.getResponsibilitiesSecondary().stream().sorted(String::compareToIgnoreCase).collect(Collectors.joining(", "))); - //.append("- Nebenverantwortlich: ").append(String.join(", ", teamler.getResponsibilitiesSecondary())); - } - if(teamler.getFields() != null){ - sb - .append("\n") - .append("- %page.members.fields%: ").append(teamler.getFields().stream().sorted(String::compareToIgnoreCase).collect(Collectors.joining(", "))); - } - } - } - - sb.append("\n"); - - return sb.toString(); - } - -} diff --git a/howto-dapp/src/main/java/de/timolia/howto/generator/PageTeamMembers.kt b/howto-dapp/src/main/java/de/timolia/howto/generator/PageTeamMembers.kt new file mode 100644 index 00000000..ad0d36fd --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/generator/PageTeamMembers.kt @@ -0,0 +1,68 @@ +package de.timolia.howto.generator + +import de.timolia.howto.rank.Rank +import de.timolia.howto.teamler.Teamler +import java.util.* +import java.util.stream.Collectors + +class PageTeamMembers( + private val teamlers: List, + val sb: StringBuilder = StringBuilder() +) { + fun generate(): String { + val teamlers = teamlers + .filter { teamler -> teamler.getRankCurrent().inTeam } + .sortedWith(Teamler::compare) + .toMutableList() + val ranks = Rank.values().filter { rank -> rank.description != null }.sortedWith(Rank::compare).toList() + sb.append("%page.members.first-1%").append(teamlers.size).append("%page.members.first-2%\n") + val rankStrings = ranks.map { rank -> "${rank.male}" } + for (i in rankStrings.indices) { + sb.append(rankStrings[i]) + if (i < rankStrings.size - 2) { + sb.append(", ") + } else if (i == rankStrings.size - 2) { + sb.append(" %and% ") + } + } + sb + .append("%page.members.first-3%") + .append("\n") + .append("\n").append("%page.members.first-4%") + .append("\n") + .append("\n").append("![%page.members.first-5%](img/content-ranks.png)") + for (rank in ranks) { + sb + .append("\n") + .append("\n") + .append("\n") + .append("\n").append("## ").append(rank.male) + .append("\n") + .append("\n").append(rank.description) + .append("\n") + for (teamler in teamlers.filter { teamler -> teamler.getRankCurrent() == rank }) { + sb + .append("\n") + .append("\n") + .append("### ").append(teamler.getNameForMarkdown()).append("") + .append("\n").append("- %page.members.rank-ingame%: ").append(rank.getString(teamler.sex)) + teamler.responsibilitiesMain?.let { + appendStringList("page.members.hv", it) + } + teamler.responsibilitiesSecondary?.let { + appendStringList("page.members.nv", it) + } + teamler.fields?.let { + appendStringList("page.members.fields", it) + } + } + } + sb.append("\n") + return sb.toString() + } + + private fun appendStringList(name: String, strings: List) { + sb.append("\n").append("- %${name}%: ") + strings.sortedWith { obj, str -> obj.compareTo(str, ignoreCase = true) }.joinTo(sb) + } +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/models/Language.java b/howto-dapp/src/main/java/de/timolia/howto/models/Language.java deleted file mode 100644 index 1a8be8ae..00000000 --- a/howto-dapp/src/main/java/de/timolia/howto/models/Language.java +++ /dev/null @@ -1,8 +0,0 @@ -package de.timolia.howto.models; - -public enum Language { - - DE, - EN - -} diff --git a/howto-dapp/src/main/java/de/timolia/howto/models/LanguageString.java b/howto-dapp/src/main/java/de/timolia/howto/models/LanguageString.java deleted file mode 100644 index bfce2a6b..00000000 --- a/howto-dapp/src/main/java/de/timolia/howto/models/LanguageString.java +++ /dev/null @@ -1,38 +0,0 @@ -package de.timolia.howto.models; - -public class LanguageString { - - private final Language language; - private final String key; - private final String value; - - public LanguageString(Language language, String key, String value) { - this.language = language; - this.key = key; - this.value = value; - } - - - public Language getLanguage() { - return language; - } - - public String getKey() { - return key; - } - - public String getValue() { - return value; - } - - - @Override - public String toString() { - return "LanguageString{" + - "language=" + language + - ", key='" + key + '\'' + - ", value='" + value + '\'' + - '}'; - } - -} diff --git a/howto-dapp/src/main/java/de/timolia/howto/models/Rank.java b/howto-dapp/src/main/java/de/timolia/howto/models/Rank.java deleted file mode 100644 index e85ae129..00000000 --- a/howto-dapp/src/main/java/de/timolia/howto/models/Rank.java +++ /dev/null @@ -1,106 +0,0 @@ -package de.timolia.howto.models; - -public enum Rank { - - administrator( 161, true, "administrator", "Administrator", "Administratorin", "%rank.administrator.description%"), - administrator_city( 160, true, "administrator", "Administrator City", null), - builder( 80, true, "builder", "Builder", "Builderin", "%rank.builder.description%"), - builder_plus( 85, true, "builder-plus", "Builder+", null, "%rank.builder_plus.description%"), - creator( 70, true, "creator", "Creator", null), - content( 71, true, "content", "Content", null, "%rank.content.description%"), - developer( 135, true, "developer", "Developer", null, "%rank.developer.description%"), - developer_city( 131, true, "developer", "Developer City", null), - developer_games( 130, true, "developer", "Developer Games", null), - developer_plus( 140, true, "developer-plus", "Developer+", null, "%rank.developer_plus.description%"), - expert( 50, false, "expert", "Expert", null), - head_builder( 90 , true, "headbuilder", "HeadBuilder", null, "%rank.head_builder.description%"), - mvp( 30, false, "mvp", "MVP", null), - mvp_plus( 40, false, "mvp", "MVP+", null), - management( 180, true, "management", "Management", null), - moderator( 125, true, "moderator", "Moderator", "Moderatorin", "%rank.moderator.description%"), - moderator_city( 121, true, "moderator", "Moderator City", null), - moderator_games( 120, true, "moderator", "Moderator Games", "Moderatorin Games"), - native_expert( 55, false, "expert", "Native Expert", null), - native_mvp( 35, false, "mvp", "Native MVP", null), - native_mvp_plus( 45, false, "mvp", "Native MVP+", null), - native_youtuber( 60, false, "youtuber", "Native YouTuber", null), - youtuber( 59, false, "youtuber", "YouTuber", null), - pro( 10, false, "pro", "Pro", null), - pro_plus( 20, false, "pro", "Pro+", null), - spieler( 0, false, "user", "Spieler", "Spielerin"), - supporter( 105, true, "supporter", "Supporter", "Supporterin", "%rank.supporter.description%"), - supporter_city( 102, true, "supporter", "Supporter City", "Supporterin City"), - supporter_games( 101, true, "supporter", "Supporter Games", "Supporterin Games"), - supporter_plus( 110, true, "supporter-plus", "Supporter+", "Supporterin+", "%rank.supporter_plus.description%"), - supporter_city_games(100, true, "supporter", "Supporter City & Games", "Supporterin City & Games"), - sysadmin( 150, true, "sysadmin", "SysAdmin", null); - - private final int value; - private final boolean inTeam; - private final String male; - private final String female; - private final String cssClass; - private final String description; - - Rank(int value, boolean inTeam, String cssClass, String male, String female) { - this.value = value; - this.inTeam = inTeam; - this.male = male; - this.female = female; - this.cssClass = cssClass; - this.description = null; - } - - Rank(int value, boolean inTeam, String cssClass, String male, String female, String description) { - this.value = value; - this.inTeam = inTeam; - this.male = male; - this.female = female; - this.cssClass = cssClass; - this.description = description; - } - - public String getString(Sex sex) { - if (sex.equals(Sex.female)) { - if (this.female != null) { - return this.female; - } else { - return this.male; - } - } else if (sex.equals(Sex.male)) { - return this.male; - } else { - return this.male; - } - } - - - public int getValue() { - return value; - } - - public boolean isInTeam() { - return inTeam; - } - - public String getMale() { - return male; - } - - public String getFemale() { - return female == null ? "undefined" : female; - } - - public String getCssClass() { - return cssClass; - } - - public String getDescription() { - return description; - } - - public int compare(Rank o) { - return Integer.compare(o.value, this.value); - } - -} diff --git a/howto-dapp/src/main/java/de/timolia/howto/models/Sex.java b/howto-dapp/src/main/java/de/timolia/howto/models/Sex.java deleted file mode 100644 index c4b3ad61..00000000 --- a/howto-dapp/src/main/java/de/timolia/howto/models/Sex.java +++ /dev/null @@ -1,9 +0,0 @@ -package de.timolia.howto.models; - -public enum Sex { - - female, - male, - undefined - -} diff --git a/howto-dapp/src/main/java/de/timolia/howto/models/Teamler.java b/howto-dapp/src/main/java/de/timolia/howto/models/Teamler.java deleted file mode 100644 index 5397bc77..00000000 --- a/howto-dapp/src/main/java/de/timolia/howto/models/Teamler.java +++ /dev/null @@ -1,188 +0,0 @@ -package de.timolia.howto.models; - -import de.timolia.howto.conversion.SQLApi; -import de.timolia.howto.conversion.models.TeamlerRankChange; -import org.apache.commons.lang3.Validate; - -import java.text.ParseException; -import java.text.RuleBasedCollator; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public class Teamler { - - private String name; - private final UUID uuid; - private final Sex sex; - private List responsibilitiesMain; - private final List responsibilitiesMainHidden; - private List responsibilitiesSecondary; - private final List responsibilitiesSecondaryHidden; - private final List fields; - private final LinkedHashMap rankHistory; - private transient List rankChanges = null; - private transient Rank rankCurrent = null; - - public Teamler(UUID uuid, Sex sex, List responsibilitiesMain, List responsibilitiesSecondary, List fields, LinkedHashMap rankHistory) { - this.name = SQLApi.getName(uuid); - this.uuid = uuid; - this.sex = sex; - this.responsibilitiesMain = responsibilitiesMain; - this.responsibilitiesMainHidden = null; - this.responsibilitiesSecondary = responsibilitiesSecondary; - this.responsibilitiesSecondaryHidden = null; - this.fields = fields; - this.rankHistory = rankHistory; - } - - public String getName() { - return name; - } - - public String getNameForMarkdown() { - return name.replaceAll("_", "\\\\_"); - } - - public UUID getUuid() { - return uuid; - } - - public Sex getSex() { - return sex; - } - - public List getResponsibilitiesMain() { - return responsibilitiesMain; - } - - public void setResponsibilitiesMain(List responsibilitiesMain) { - this.responsibilitiesMain = responsibilitiesMain; - } - - public List getResponsibilitiesMainHidden() { - return responsibilitiesMainHidden; - } - - public List getResponsibilitiesSecondary() { - return responsibilitiesSecondary; - } - - public void setResponsibilitiesSecondary(List responsibilitiesSecondary) { - this.responsibilitiesSecondary = responsibilitiesSecondary; - } - - public List getResponsibilitiesSecondaryHidden() { - return responsibilitiesSecondaryHidden; - } - - public List getFields() { - return fields; - } - - public HashMap getRankHistory() { - return rankHistory; - } - - public List getRankChanges(boolean includeHidden) { - //if(rankChanges == null) { - rankChanges = new ArrayList<>(); - if (rankHistory == null || rankHistory.isEmpty()) { - return rankChanges; - } - - for (int i = 0; i < rankHistory.size(); i++) { - Rank rank = (Rank) rankHistory.values().toArray()[i]; - Validate.notNull(rank, "Der " + (i + 1) + ". Rang von '" + name + "' existiert nicht"); - } - - List dates = rankHistory.keySet().stream().map(s -> s.replace("hidden-", "")).map(TeamlerRankChange::toDate).sorted().collect(Collectors.toList()); - for (int i = Math.min(1, dates.size() - 1); i < dates.size(); i++) { - boolean hidden = false; - String rankOldKey = TeamlerRankChange.toString(dates.get(Math.max(i - 1, 0))); - if (!rankHistory.containsKey(rankOldKey) && rankHistory.containsKey("hidden-" + rankOldKey)) { - rankOldKey = "hidden-" + rankOldKey; - //hidden = true; - } - Rank rank_old = rankHistory.get(rankOldKey); - -// if(Math.max(i - 1, 0) + 1 > dates.size() - 1) { -// System.out.println("asd"); -// } - - String rankNewKey = TeamlerRankChange.toString(dates.get(i)); - if (!rankHistory.containsKey(rankNewKey) && rankHistory.containsKey("hidden-" + rankNewKey)) { - rankNewKey = "hidden-" + rankNewKey; - hidden = true; - } - Rank rank_new = rankHistory.get(rankNewKey); - - if (includeHidden || !hidden && !rankNewKey.equals("initial")) { - TeamlerRankChange teamlerRankChange = new TeamlerRankChange(name, uuid, rank_old, rank_new, TeamlerRankChange.toString(dates.get(i)), hidden); - rankChanges.add(teamlerRankChange); - } - } - //} - - return rankChanges; - } - - public Rank getRankCurrent() { - if (rankCurrent == null) { - List teamlerRankChanges = getRankChanges(true); - TeamlerRankChange lastRankChange = teamlerRankChanges.get(teamlerRankChanges.size() - 1); - rankCurrent = lastRankChange.getRankTo(); - } - return rankCurrent; - } - - public int compare(Teamler o) { - if (!this.getRankCurrent().equals(o.getRankCurrent())) { - // compare by rank - return this.getRankCurrent().compare(o.getRankCurrent()); - } - - // compare by name - String rules = "< '_'"; - try { - RuleBasedCollator ruleBasedCollator = new RuleBasedCollator(rules); - return ruleBasedCollator.compare(this.getName().toLowerCase(), o.getName().toLowerCase()); - } catch (ParseException e) { - e.printStackTrace(); - throw new RuntimeException(); - } - } - - public boolean hasResponsibilityMain(String responsibility) { - return hasResponsibility(responsibility, Stream.concat(responsibilitiesMain == null ? Stream.empty() : responsibilitiesMain.stream(), responsibilitiesMainHidden == null ? Stream.empty() : responsibilitiesMainHidden.stream()).collect(Collectors.toList())); - } - - public boolean hasResponsibilitySecondary(String responsibility) { - return hasResponsibility(responsibility, Stream.concat(responsibilitiesSecondary == null ? Stream.empty() : responsibilitiesSecondary.stream(), responsibilitiesSecondaryHidden == null ? Stream.empty() : responsibilitiesSecondaryHidden.stream()).collect(Collectors.toList())); - } - - private boolean hasResponsibility(String responsibility, List responsibilityList) { - if (!getRankCurrent().isInTeam() && !responsibilityList.isEmpty()) { - throw new RuntimeException("'" + name + "' has responsibilities but is not in team anymore"); - } - - return responsibilityList != null && (responsibilityList.contains(responsibility) || responsibilityList.contains(responsibility + " Forum")); - } - - public void updateName() { - this.name = SQLApi.getName(uuid, name); - } - - @Override - public String toString() { - return "Teamler{" + - "name='" + name + '\'' + - ", uuid=" + uuid + - ", sex=" + sex + - ", responsibilitiesMain=" + responsibilitiesMain + - ", responsibilitiesSecondary=" + responsibilitiesSecondary + - ", rankHistory=" + rankHistory + - '}'; - } - -} diff --git a/howto-dapp/src/main/java/de/timolia/howto/rank/Rank.kt b/howto-dapp/src/main/java/de/timolia/howto/rank/Rank.kt new file mode 100644 index 00000000..1b42f83f --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/rank/Rank.kt @@ -0,0 +1,59 @@ +package de.timolia.howto.rank + +import de.timolia.howto.teamler.Sex + +enum class Rank( + private val value: Int, + val inTeam: Boolean, + val cssClass: String, + val male: String, + private val female: String?, + val description: String? = null +) { + administrator(161, true, "administrator", "Administrator", "Administratorin", "%rank.administrator.description%"), + administrator_city(160, true, "administrator", "Administrator City", null), + builder(80, true, "builder", "Builder", "Builderin", "%rank.builder.description%"), + builder_plus(85, true, "builder-plus", "Builder+", null, "%rank.builder_plus.description%"), + creator(70, true, "creator", "Creator", null), + content(71, true, "content", "Content", null, "%rank.content.description%"), + developer(135, true, "developer", "Developer", null, "%rank.developer.description%"), + developer_city(131, true, "developer", "Developer City", null), + developer_games(130, true, "developer", "Developer Games", null), + developer_plus(140, true, "developer-plus", "Developer+", null, "%rank.developer_plus.description%"), + expert(50, false, "expert", "Expert", null), + head_builder(90, true, "headbuilder", "HeadBuilder", null, "%rank.head_builder.description%"), + mvp(30, false, "mvp", "MVP", null), + mvp_plus(40, false, "mvp", "MVP+", null), + management(180, true, "management", "Management", null), + moderator(125, true, "moderator", "Moderator", "Moderatorin", "%rank.moderator.description%"), + moderator_city(121, true, "moderator", "Moderator City", null), + moderator_games(120, true, "moderator", "Moderator Games", "Moderatorin Games"), + native_expert(55, false, "expert", "Native Expert", null), + native_mvp(35, false, "mvp", "Native MVP", null), + native_mvp_plus(45, false, "mvp", "Native MVP+", null), + native_youtuber(60, false, "youtuber", "Native YouTuber", null), + youtuber(59, false, "youtuber", "YouTuber", null), + pro(10, false, "pro", "Pro", null), + pro_plus(20, false, "pro", "Pro+", null), + spieler(0, false, "user", "Spieler", "Spielerin"), + supporter(105, true, "supporter", "Supporter", "Supporterin", "%rank.supporter.description%"), + supporter_city(102, true, "supporter", "Supporter City", "Supporterin City"), + supporter_games(101, true, "supporter", "Supporter Games", "Supporterin Games"), + supporter_plus(110, true, "supporter-plus", "Supporter+", "Supporterin+", "%rank.supporter_plus.description%"), + supporter_city_games(100, true, "supporter", "Supporter City & Games", "Supporterin City & Games"), + sysadmin(150, true, "sysadmin", "SysAdmin", null); + + fun getString(sex: Sex): String { + return if (sex == Sex.female && female != null) { + female + } else male + } + + fun getFemale(): String { + return female ?: "undefined" + } + + fun compare(o: Rank): Int { + return o.value.compareTo(value) + } +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/rank/RankConversion.kt b/howto-dapp/src/main/java/de/timolia/howto/rank/RankConversion.kt new file mode 100644 index 00000000..19f3d3a3 --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/rank/RankConversion.kt @@ -0,0 +1,59 @@ +package de.timolia.howto.rank + +import java.util.* +import java.util.function.Function +import java.util.stream.Collectors + +object RankConversion { + fun getRank(text: String): Rank? { + return Arrays.stream(Rank.values()) + .collect(Collectors.toMap(Function.identity()) { rank -> getSimilarity(text, rank.getFemale()).coerceAtLeast(getSimilarity(text, rank.male)) }) + .entries + .stream() + .max(Comparator.comparingDouble { (_, value) -> value }) + .filter { e -> e.value > 0.1 } + .map { (key, _) -> key } + .orElse(null) + } + + /** + * Calculates the similarity (a number within 0 and 1) between two strings. + */ + private fun getSimilarity(s1: String, s2: String): Double { + var longer = s1 + var shorter = s2 + if (s1.length < s2.length) { // longer should always have greater length + longer = s2 + shorter = s1 + } + val longerLength = longer.length + return if (longerLength == 0) { + 1.0 /* both strings are zero length */ + } else (longerLength - editDistance(longer, shorter)) / longerLength.toDouble() + } + + // Example implementation of the Levenshtein Edit Distance + // See http://rosettacode.org/wiki/Levenshtein_distance#Java + private fun editDistance(s1: String, s2: String): Int { + var s1 = s1 + var s2 = s2 + s1 = s1.lowercase(Locale.getDefault()) + s2 = s2.lowercase(Locale.getDefault()) + val costs = IntArray(s2.length + 1) + for (i in 0..s1.length) { + var lastValue = i + for (j in 0..s2.length) { + if (i == 0) costs[j] = j else { + if (j > 0) { + var newValue = costs[j - 1] + if (s1[i - 1] != s2[j - 1]) newValue = newValue.coerceAtMost(lastValue).coerceAtMost(costs[j]) + 1 + costs[j - 1] = lastValue + lastValue = newValue + } + } + } + if (i > 0) costs[s2.length] = lastValue + } + return costs[s2.length] + } +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/rank/TeamlerRankChange.kt b/howto-dapp/src/main/java/de/timolia/howto/rank/TeamlerRankChange.kt new file mode 100644 index 00000000..ad87c758 --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/rank/TeamlerRankChange.kt @@ -0,0 +1,72 @@ +package de.timolia.howto.rank + +import de.timolia.howto.database.SQLApi +import java.text.ParseException +import java.text.SimpleDateFormat +import java.util.* + +class TeamlerRankChange { + val name: String + val uuid: UUID + val rankFrom: Rank + val rankTo: Rank + val date: Date + + @Transient + private val hidden: Boolean + + constructor(name: String, rankFrom: String, rankTo: String, date: String) { + this.name = name + uuid = SQLApi.getUuid(name)!! + this.rankFrom = RankConversion.getRank(rankFrom) ?: throw IllegalArgumentException("Der Rang von '$name' ('$rankFrom') existiert nicht") + this.rankTo = RankConversion.getRank(rankTo) ?: throw IllegalArgumentException("Der Rang von '$name' ('$rankTo') existiert nicht") + this.date = simpleDateFormat.parse(date) + hidden = false + } + + constructor(name: String?, uuid: UUID, rankFrom: Rank, rankTo: Rank, date: String, hidden: Boolean) { + this.name = SQLApi.getName(uuid, name)!! + this.uuid = uuid + this.rankFrom = rankFrom + this.rankTo = rankTo + this.date = toDate(date) + this.hidden = hidden + } + + fun getNameForMarkdown(): String { + return name.replace("_".toRegex(), "\\\\_") + } + + fun getReadableDate(): String { + return simpleDateFormat.format(date) + } + + override fun toString(): String { + return "TeamlerRankChange{" + + "name='" + name + '\'' + + ", uuid=" + uuid + + ", rankFrom='" + rankFrom + '\'' + + ", rankTo='" + rankTo + '\'' + + ", date=" + simpleDateFormat.format(date) + + '}' + } + + companion object { + private val simpleDateFormat: SimpleDateFormat = SimpleDateFormat("dd.MM.yyyy") + fun toString(date: Date?): String { + return if (date == Date(0)) { + "initial" + } else simpleDateFormat.format(date) + } + + fun toDate(date: String): Date { + return if (date == "initial") { + Date(0) + } else try { + simpleDateFormat.parse(date) + } catch (e: ParseException) { + throw RuntimeException(e) + } + } + } +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/responsibility/Responsibility.kt b/howto-dapp/src/main/java/de/timolia/howto/responsibility/Responsibility.kt new file mode 100644 index 00000000..11760160 --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/responsibility/Responsibility.kt @@ -0,0 +1,38 @@ +package de.timolia.howto.responsibility + +import de.timolia.howto.teamler.Teamler + +fun interface Responsibility { + fun renderTo(builder: StringBuilder) + + companion object { + fun simple(type: ResponsibilityType, teamler: String): Responsibility { + return Responsibility { builder -> + builder + .append("|") + .append(teamler) + .append(" | ") + .append(type.defaultKey()) + .append(" |") + } + } + + fun concreteTeamster(type: ResponsibilityType, teamler: Teamler): Responsibility { + return concreteTeamster(teamler, type.defaultKey()) + } + + fun concreteTeamster(teamler: Teamler, translationKey: String): Responsibility { + return Responsibility { builder -> + builder + .append("|") + .append(teamler.getNameForMarkdown()) + .append("") + .append(" | ") + .append(translationKey) + .append(" |") + } + } + } +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/responsibility/ResponsibilityType.kt b/howto-dapp/src/main/java/de/timolia/howto/responsibility/ResponsibilityType.kt new file mode 100644 index 00000000..7860cd79 --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/responsibility/ResponsibilityType.kt @@ -0,0 +1,10 @@ +package de.timolia.howto.responsibility + +enum class ResponsibilityType { + HV, + NV; + + fun defaultKey(): String { + return "%page.responsibilities.${name.lowercase()}%" + } +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/teamler/Sex.kt b/howto-dapp/src/main/java/de/timolia/howto/teamler/Sex.kt new file mode 100644 index 00000000..4ef06d8a --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/teamler/Sex.kt @@ -0,0 +1,7 @@ +package de.timolia.howto.teamler + +enum class Sex { + female, + male, + undefined +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/teamler/Teamler.kt b/howto-dapp/src/main/java/de/timolia/howto/teamler/Teamler.kt new file mode 100644 index 00000000..c62f0a50 --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/teamler/Teamler.kt @@ -0,0 +1,127 @@ +package de.timolia.howto.teamler + +import de.timolia.howto.database.SQLApi +import de.timolia.howto.rank.Rank +import de.timolia.howto.rank.TeamlerRankChange +import org.apache.commons.lang3.Validate +import java.text.ParseException +import java.text.RuleBasedCollator +import java.util.* + +class Teamler( + val uuid: UUID, + val sex: Sex, + var responsibilitiesMain: List?, + var responsibilitiesSecondary: List?, + val fields: List?, + private val rankHistory: LinkedHashMap? +) { + private var name: String + private val responsibilitiesMainHidden: List? = null + private val responsibilitiesSecondaryHidden: List? = null + + @Transient + private var rankCurrent: Rank? = null + + init { + name = SQLApi.getName(uuid)!! + } + + fun getNameForMarkdown() = name.replace("_", "\\_") + + fun getRankChanges(includeHidden: Boolean): MutableList { + val rankChanges = mutableListOf() + if (rankHistory.isNullOrEmpty()) { + return rankChanges + } + for (i in 0 until rankHistory.size) { + val rank = rankHistory.values.toTypedArray()[i] + Validate.notNull(rank, "Der " + (i + 1) + ". Rang von '" + name + "' existiert nicht") + } + val dates = rankHistory.keys + .map { s -> s.replace("hidden-", "") } + .map { date -> TeamlerRankChange.toDate(date) } + .sorted() + for (i in 1.coerceAtMost(dates.size - 1) until dates.size) { + var hidden = false + var rankOldKey: String = TeamlerRankChange.toString(dates[(i - 1).coerceAtLeast(0)]) + if (!rankHistory.containsKey(rankOldKey) && rankHistory.containsKey("hidden-$rankOldKey")) { + rankOldKey = "hidden-$rankOldKey" + } + val rankOld = rankHistory[rankOldKey] + var rankNewKey: String = TeamlerRankChange.toString(dates[i]) + if (!rankHistory.containsKey(rankNewKey) && rankHistory.containsKey("hidden-$rankNewKey")) { + rankNewKey = "hidden-$rankNewKey" + hidden = true + } + val rankNew = rankHistory[rankNewKey] + if (includeHidden || !hidden && rankNewKey != "initial") { + val teamlerRankChange = TeamlerRankChange(name, uuid, rankOld!!, rankNew!!, TeamlerRankChange.toString(dates[i]), hidden) + rankChanges.add(teamlerRankChange) + } + } + return rankChanges + } + + fun getRankCurrent(): Rank { + if (rankCurrent == null) { + val teamlerRankChanges = getRankChanges(true) + val lastRankChange = teamlerRankChanges[teamlerRankChanges.size - 1] + rankCurrent = lastRankChange.rankTo + } + return rankCurrent!! + } + + fun compare(o: Teamler): Int { + if (getRankCurrent() != o.getRankCurrent()) { + // compare by rank + return getRankCurrent().compare(o.getRankCurrent()) + } + + // compare by name + val rules = "< '_'" + return try { + val ruleBasedCollator = RuleBasedCollator(rules) + ruleBasedCollator.compare(name.lowercase(Locale.getDefault()), o.name.lowercase(Locale.getDefault())) + } catch (e: ParseException) { + e.printStackTrace() + throw RuntimeException(e) + } + } + + fun hasResponsibilityMain(responsibility: String?): Boolean { + return hasResponsibility( + responsibility, + (responsibilitiesMain ?: emptyList()) + (responsibilitiesMainHidden ?: emptyList()) + ) + } + + fun hasResponsibilitySecondary(responsibility: String?): Boolean { + return hasResponsibility( + responsibility, + (responsibilitiesSecondary ?: emptyList()) + (responsibilitiesSecondaryHidden ?: emptyList()) + ) + } + + private fun hasResponsibility(responsibility: String?, responsibilityList: List): Boolean { + if (!getRankCurrent().inTeam && responsibilityList.isNotEmpty()) { + throw RuntimeException("'$name' has responsibilities but is not in team anymore") + } + return responsibilityList.contains(responsibility) || responsibilityList.contains("$responsibility Forum") + } + + fun updateName() { + name = SQLApi.getName(uuid, name)!! + } + + override fun toString(): String { + return "Teamler{" + + "name='" + name + '\'' + + ", uuid=" + uuid + + ", sex=" + sex + + ", responsibilitiesMain=" + responsibilitiesMain + + ", responsibilitiesSecondary=" + responsibilitiesSecondary + + ", rankHistory=" + rankHistory + + '}' + } +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/translate/Language.kt b/howto-dapp/src/main/java/de/timolia/howto/translate/Language.kt new file mode 100644 index 00000000..e8b21b34 --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/translate/Language.kt @@ -0,0 +1,8 @@ +package de.timolia.howto.translate + +enum class Language { + DE, + EN; + + fun key() = name.lowercase() +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/translate/Translate.kt b/howto-dapp/src/main/java/de/timolia/howto/translate/Translate.kt new file mode 100644 index 00000000..1aa2a4e7 --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/translate/Translate.kt @@ -0,0 +1,51 @@ +package de.timolia.howto.translate + +import java.io.IOException +import java.io.UncheckedIOException +import java.nio.file.Files +import java.nio.file.Path +import java.util.* +import kotlin.Throws +import kotlin.io.path.extension +import kotlin.io.path.nameWithoutExtension + +class Translate { + private val translations = EnumMap>(Language::class.java) + @Throws(IOException::class) + fun loadDirectory(path: Path) { + Files.list(path).forEach { file: Path -> + try { + mayLoadFile(file) + } catch (e: IOException) { + throw UncheckedIOException("Failed to load translation from $file", e) + } + } + } + + @Throws(IOException::class) + private fun mayLoadFile(path: Path) { + if (path.extension != "properties") { + return + } + val languageName = path.nameWithoutExtension + val language = Language.valueOf(languageName.uppercase()) + println(languageName) + val properties = Properties() + properties.load(Files.newBufferedReader(path)) + translations[language] = properties.entries + .map { property -> Translation(language, property.key.toString(), property.value.toString()) } + .toMutableList() + } + + fun forLanguage(language: Language): TranslationContext { + val translations = translations[language] + ?: throw IllegalArgumentException("No translations for language $language") + return TranslationContext { content -> + var content = content + for (translation in translations) { + content = translation.replace(content) + } + content + } + } +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/translate/Translation.kt b/howto-dapp/src/main/java/de/timolia/howto/translate/Translation.kt new file mode 100644 index 00000000..75c4d2bd --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/translate/Translation.kt @@ -0,0 +1,15 @@ +package de.timolia.howto.translate + +class Translation(private val language: Language, private val key: String, private val value: String) { + fun replace(text: String) = text.replace(replacementKey(), value) + + private fun replacementKey() = "%$key%" + + override fun toString(): String { + return "LanguageString{" + + "language=" + language + + ", key='" + key + '\'' + + ", value='" + value + '\'' + + '}' + } +} diff --git a/howto-dapp/src/main/java/de/timolia/howto/translate/TranslationContext.kt b/howto-dapp/src/main/java/de/timolia/howto/translate/TranslationContext.kt new file mode 100644 index 00000000..00ca51c2 --- /dev/null +++ b/howto-dapp/src/main/java/de/timolia/howto/translate/TranslationContext.kt @@ -0,0 +1,5 @@ +package de.timolia.howto.translate + +fun interface TranslationContext { + fun replaceAll(content: String): String +}