Compare commits

..
164 Commits
Author SHA1 Message Date
Julian Arndt 67a0576e4d Merge remote-tracking branch 'origin/main' 2024-01-05 10:04:54 +01:00
Julian Arndt 42c390e4ce Fix Supercup Jenkinsfile 2024-01-05 10:03:50 +01:00
Julian eb996dd004 Add FC Girona 2023-12-17 20:41:01 +01:00
Julian Arndt f599aa1954 Add Sporting Braga 2023-09-27 16:51:01 +02:00
Julian Arndt 145aa5083c Only print errors if errors available 2023-09-27 16:48:26 +02:00
Julian Arndt 35e2fd44a5 Add Kopenhagen 2023-09-18 09:51:48 +02:00
Julian Arndt ba68057c0f Rework rounds parser to support wrongly sorted league rounds 2023-09-10 17:40:12 +02:00
Julian Arndt b411f5d57f Only update result if api football match is finished 2023-08-20 11:55:53 +02:00
Julian Arndt 29f00f39aa Setup rest of season 2024 2023-08-14 14:35:30 +02:00
Julian Arndt 23cef6f545 Fix matches results updater 2023-08-14 10:03:44 +02:00
Julian 2acc6acafe Add template config for Tippliga 2023-08-06 18:51:29 +02:00
Julian cbc4b4ff76 Add teams for wtl pokal 2023-08-06 18:51:12 +02:00
Julian fbca245326 Add Europa League and fix pipeline 2023-08-05 21:21:56 +02:00
Julian 2514200eeb Add teams for wtl pokal 2023-07-30 18:49:02 +02:00
Julian 7c90434f0f Fix api rate limit 2023-07-30 16:41:13 +02:00
Julian d2ed44cc9a Fix pipeline 2023-07-30 16:28:33 +02:00
Julian 04f0188c3f Add league config for 2024 2023-07-30 16:18:59 +02:00
Julian a06efd5355 Fix bugs 2023-06-06 16:01:02 +02:00
Julian 9cf286db39 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	src/main/java/de/jeyp91/tippliga/TLWMatchesResultsUpdater.java
#	src/test/java/de/jeyp91/tippliga/TLWMatchesResultsUpdaterTest.java
2023-06-06 15:49:54 +02:00
Julian 4dcd994ac9 Add auto update of results 2023-06-06 15:48:06 +02:00
Julian 98b9321c12 Add auto update of results 2023-06-06 15:45:25 +02:00
Julian 7b721a5592 Merge remote-tracking branch 'origin/main' 2023-06-05 23:20:15 +02:00
Julian 10c90e7d04 Add admin login 2023-06-05 23:19:27 +02:00
Julian Arndt b1c95784ef Add VfB Oldenburg 2023-05-22 16:38:06 +02:00
Julian Arndt d30ec92bb5 Clean up pipelines 2023-04-13 10:40:35 +02:00
Julian Arndt 6ac9203fa1 Fix wrong trigger 2023-04-13 10:30:02 +02:00
Julian b96b34e1a1 first part of auto results 2023-04-10 22:11:10 +02:00
Julian ee7a3004b3 Add support for third delivery date 2023-04-10 19:19:15 +02:00
Julian 4a024c4476 Improve logging to telegram 2023-04-10 19:18:43 +02:00
Julian 4c3f18f852 Fix error 2023-04-10 13:48:04 +02:00
Julian 12164c03ae Parse overtime goals 2023-04-10 13:39:45 +02:00
Julian d078a182a1 Fix gradle build 2023-04-10 13:10:13 +02:00
Julian ed69935657 Fix typo in Jenkinsfile 2023-04-10 13:01:33 +02:00
Julian 3d4fd84a0a Update Java version 2023-04-10 12:57:00 +02:00
Julian 6e82e05298 Add all missing Jenkinsfiles 2023-04-10 12:49:47 +02:00
Julian 3b3f8e7162 Add build Jenkinsfile to git 2023-04-10 12:31:44 +02:00
Julian 19e928e723 Update dependencies 2023-04-10 11:59:56 +02:00
Julian Arndt ef7f36982a Fix duplicate id 2023-01-09 17:24:16 +01:00
Julian Arndt 7c869b8410 Add Feyenoord 2023-01-09 10:30:48 +01:00
Julian Arndt 79d41f0f8a Add Netherlands Eredivisie 2023-01-09 10:18:53 +01:00
Julian 7516d802ca Test 2023-01-08 22:06:07 +01:00
Julian 76adb595d5 Add two teams 2023-01-08 21:22:45 +01:00
Julian 102f2b8ba3 Merge remote-tracking branch 'origin/main' 2022-12-22 12:58:54 +01:00
Julian 12aec6c37f Add Fenerbahce 2022-12-22 12:58:16 +01:00
Julian Arndt 5ea6511a48 Fix typo 2022-12-20 09:56:29 +01:00
Julian 95d71fa813 Add six new teams 2022-12-19 22:37:09 +01:00
Julian 4220fd06cb Merge remote-tracking branch 'origin/main' 2022-12-18 15:50:21 +01:00
Julian 632a39cd5d Add turkey 2022-12-18 15:49:05 +01:00
Julian Arndt decf60fb0a Fix duplicate google calendar events 2022-11-15 10:14:09 +01:00
Julian 7c5bbe65e5 Fix tests 2022-11-07 18:18:17 +01:00
Julian 3f10de8225 Reset target version 2022-11-07 18:12:25 +01:00
Julian dac3f31a37 Update dependencies and add support for google calendar html event description 2022-11-07 18:00:29 +01:00
Julian 87c3dd21c6 Add Sporting Lissabon, Maccabi Haifa and Celtic Glasgow 2022-10-23 22:18:20 +02:00
Julian d7296a5634 Fix config for Partizan Belgrad 2022-10-05 21:55:12 +02:00
Julian a9fcf76a85 Add FK Partizan Belgrad 2022-10-05 21:51:52 +02:00
Julian 37e5317d72 Remove warnings 2022-08-05 16:41:44 +02:00
Julian c301923c24 Change back line seperators 2022-08-05 15:21:00 +02:00
Julian 752b3253d9 Fix find event bug 2022-08-05 15:17:50 +02:00
Julian 3095dbd0e5 Improve matcher to find event 2022-08-05 14:53:28 +02:00
Julian e286d1029c Replace line seperator for google event descriptions 2022-08-05 14:51:11 +02:00
Julian 26b7545517 Improve google event update logic and add logging 2022-08-05 14:00:43 +02:00
Julian 63ff6838de Rework Google Auth and add Supercup 2022-08-05 13:25:26 +02:00
Julian f5ef53aefd Add Supercups and Europa League 2022-08-05 10:52:09 +02:00
Julian 6ca8693258 Reset token 2022-08-04 21:10:42 +02:00
Julian b5fb2d6842 Update google credentials 2022-08-04 19:07:28 +02:00
Julian 0c63d45dd6 Improve Google Calendar Logic 2022-08-04 13:36:24 +02:00
Julian 61d6597578 Retrieve forum id for checksum provider dynamically 2022-07-31 18:05:48 +02:00
Julian c76a972286 Season 2023 2022-07-31 17:50:01 +02:00
Julian 34f906f622 Add leagues for 2023 2022-07-22 12:19:39 +02:00
Julian Arndt e7a74694ba Add Rangers, Nizza and Brentford 2022-04-29 11:23:11 +02:00
Julian 13effb5d59 Fix duplicate events 2022-04-10 20:20:43 +02:00
Julian ea2697e114 Add support for google calendar 2022-03-16 14:03:09 +01:00
Julian 8ba07bab8e Add Galatasaray 2022-03-13 00:33:03 +01:00
Julian 6099b55f6c Add Benfica Lissabon and OSC Lille 2022-02-05 11:28:43 +01:00
Julian Arndt 363dd073e8 Add Stade Rennes 2021-12-17 15:08:03 +01:00
Julian Arndt d9616956ee Add Viktoria Berlin 2021-10-07 15:22:04 +02:00
Julian 71546bd499 Update library versions to get rid of warning 2021-08-29 16:42:38 +02:00
Julian 67ea5c7d97 Add Borussia Dortmund II to team id matchter config 2021-08-04 22:08:35 +02:00
Julian f349b92973 Add BFC Dynamo 2021-07-31 08:45:29 +02:00
Julian Arndt f9c06971f0 Add UEFA Europa League to 2022 league config 2021-07-29 13:42:53 +02:00
Julian Arndt c833f373bd Remove debug logging 2021-07-29 12:08:21 +02:00
Julian Arndt 54f1129021 update prod sql url 2021-07-29 12:07:01 +02:00
Julian Arndt 0d640bd61d Update PostChecksum with season 2022 2021-07-19 15:10:08 +02:00
Julian Arndt b76e125d31 Merge commit '1c99d0a4681b983cd51233e050311ca99691740e'
# Conflicts:
#	src/main/java/de/jeyp91/tippligaforum/MatchesListForumUpdater.java
2021-07-19 15:07:16 +02:00
Julian Arndt 2f0385f1f5 Updates for season 2022 2021-07-19 15:05:48 +02:00
Julian 1c99d0a468 Only update forum posts if post id was found 2021-06-22 16:13:37 +02:00
Julian 952f869f59 Improve logging for MatchesListForumUpdater 2021-06-21 14:19:42 +02:00
Julian c959d62116 Reset sql connection to prod 2021-06-05 21:42:59 +02:00
Julian 089b8eba08 Add support for EM Tippspiel 2021-06-05 21:38:11 +02:00
Julian af28e5cb6f disable ssl for sql 2021-05-09 21:59:27 +02:00
Julian 287b96f03b Fix sql 2021-05-09 21:19:45 +02:00
Julian 76db3ba9d3 Try to fix sql error 2021-05-09 21:19:21 +02:00
Julian Arndt 5ef306c853 Add RC Lens to team id matcher 2021-05-04 09:32:32 +02:00
Julian 3945b471b2 Fix tipper pair config matchday 34 2021-04-21 21:22:30 +02:00
Julian Arndt f8b53cfe52 Add more teams 2021-03-29 09:46:59 +02:00
Julian 824e0f35be Add support for mulitple identical matches like WTL Pokal final 2021-03-20 15:27:29 +01:00
Julian d54a7089c8 Add ability for additional delivery dates 2021-03-20 15:07:45 +01:00
Julian 14b45f638d Add new teams 2021-03-08 10:31:19 +01:00
Julian 70db634f10 Add Hellas Verona to Team ID Matcher Config 2021-02-25 17:12:09 +01:00
Julian cbcaeda25f Fix Tipper Match Par config 2021-02-03 20:56:35 +01:00
Julian 23ad175f98 Fix error handling 2021-01-14 10:37:34 +01:00
Julian 6fe026ee74 Retry with pause for rounds 2021-01-13 12:56:12 +01:00
Julian 4f638c3111 Fix small error 2021-01-11 10:37:51 +01:00
Julian 0578c6ecbc Add wait and retry for API Football minute rate limit 2021-01-11 10:28:33 +01:00
Julian 221a2157cf Add Atalanta Bergamo and Lazio Rom 2021-01-10 22:29:48 +01:00
Julian 50ba1198c7 Improve error handling 2021-01-10 22:22:49 +01:00
Julian 4bd7af39a8 Catch zero results for API Football 2021-01-10 22:03:48 +01:00
Julian 37030a67ec Improve error handling for getting matches 2021-01-10 21:59:17 +01:00
Julian b100e4e2e8 Add error handling everywhere 2021-01-10 21:34:27 +01:00
Julian a6145eed64 Remove exit code 1 2021-01-10 21:17:43 +01:00
Julian dbd2eb1737 Improve logging 2021-01-10 21:02:35 +01:00
Julian 27193999fc Add error handling for missing match ids 2021-01-10 20:38:26 +01:00
Julian 87c0383db8 Add generic error handling for API Football 2021-01-10 20:38:11 +01:00
Julian dd9c8cc0af Add additional check for error 2021-01-10 19:44:16 +01:00
Julian c1e8c901cd Add new teams to team id matcher 2021-01-06 10:38:35 +01:00
Julian 780bcf0c98 Add Test for updating single rounds 2021-01-06 10:22:31 +01:00
Julian 341f914b35 Add error handling for minute limit 2021-01-06 10:12:47 +01:00
Julian Arndt 10e6348dcf Improve match list in forum to match tlw league config 2020-11-10 11:26:39 +01:00
Julian Arndt f1ce35dcdf Change format of matches list to match tlw league configuration 2020-11-10 11:02:30 +01:00
Julian c53511939d Add check for wrong endpoint for APIFootball 2020-11-09 22:03:20 +01:00
Julian 5474e2a4d1 Merge remote-tracking branch 'origin/master' 2020-11-09 20:39:05 +01:00
Julian 7367c5c86f Add post checksum mode 2020-11-09 20:38:31 +01:00
Julian Arndt 2fcee30597 Disable all calls to API-Football in tests 2020-11-09 09:28:00 +01:00
Julian 8cfb2a325a Remove Gist 2020-11-08 23:04:32 +01:00
Julian 5862a99d73 Remove system.out.println in testcases 2020-11-05 10:18:53 +01:00
Julian fbbac7fdb0 Fix small comparison issue and improve error messages 2020-11-04 21:51:14 +01:00
Julian 7e09e96cb1 Remove gist request comment 2020-11-04 21:26:30 +01:00
Julian d42edcf01c Improve error output and add team id matcher template creator 2020-11-04 21:22:27 +01:00
Julian 2f411aae67 Remove actual update 2020-10-31 22:58:48 +01:00
Julian d54e8991d7 Improve match list creator 2020-10-31 22:58:06 +01:00
Julian 7f98b928bd Add support for API Football config without result and placeholder as fallback 2020-10-31 21:46:30 +01:00
Julian 7d9fc5aac1 Update database only if matchday is in future 2020-10-31 20:51:56 +01:00
Julian 53af82a429 Add wtl pokal test 2020-10-31 20:34:57 +01:00
Julian 3a5df3cae6 Add show table update, add matches list creator 2020-10-31 20:26:47 +01:00
Julian 57baee27bd Fix multiple execute queries 2020-10-28 21:09:48 +01:00
Julian 1e9ee8127c Add check for limit excetion for api football and fix bug in switch in app 2020-10-25 21:50:46 +01:00
Julian 306bf69107 Disable gist updater test 2020-10-25 21:20:54 +01:00
Julian d8e70fb1b0 Add beautiful output 2020-10-25 14:33:49 +01:00
Julian 6579d3c003 Add log level config 2020-10-18 22:30:57 +02:00
Julian 72a6140925 Add testcode 2020-10-18 22:22:06 +02:00
Julian 81b68b27f7 Improve error handling 2020-10-18 22:20:56 +02:00
Julian 2f66771b0d Add update api 2020-10-18 22:18:01 +02:00
Julian c7e9cd092f Disable execution of queries 2020-10-18 21:59:34 +02:00
Julian b09d7ed474 Add logging 2020-10-18 21:59:19 +02:00
Julian cdb1f92893 Fix gradle for Jenkins 2020-10-18 20:51:10 +02:00
Julian 1b7bcbf9b0 Prepare Jenkins stuff 2020-10-18 20:50:00 +02:00
Julian 93cbcb75a4 Fix gist 2020-10-18 20:48:23 +02:00
Julian 16d5baabef Move gist username password to config file 2020-10-18 19:04:44 +02:00
Julian 91e5ed50b7 Fix from delivery dates 2020-10-18 19:04:26 +02:00
Julian 126b9778c0 Remove Timezone bullshit 2020-10-17 09:55:04 +02:00
Julian cb01b7bcb7 Finish gist 2020-10-17 01:20:51 +02:00
Julian e4186457e2 Move fixtures to gist 2020-10-14 23:10:22 +02:00
Julian ae2be9c425 Add support for gist 2020-10-12 23:03:36 +02:00
Julian d8af0b3d6c Add support for parameters to start and update gradle to compile full jar 2020-10-12 23:03:26 +02:00
Julian f22f9a929b Add api football files updater 2020-10-07 22:14:13 +02:00
Julian bce0f3800c Improve matchdays updater 2020-10-04 14:50:10 +02:00
Julian 8828f4477a Add matchdays updater 2020-10-04 14:49:42 +02:00
Julian 5b4667e8ae Update matchdata 2020-10-04 12:31:08 +02:00
Julian 557cd59c8f Clean up shit 2020-10-04 12:23:43 +02:00
Julian e57f79c18b Improve updater 2020-10-04 11:53:30 +02:00
Julian babfe66872 Add updater for matches and teams 2020-10-04 00:42:35 +02:00
Julian Arndt 9c88c28151 Refactor Line separator for Mac and add APIFootballProvider 2020-09-29 17:43:05 +02:00
Julian a484010285 Refactor and clean up code 2020-09-27 23:27:07 +02:00
Julian 283efc775b First version with ability to create database for new season 2020-09-27 19:05:20 +02:00
103 changed files with 1151 additions and 6604 deletions
-2
View File
@@ -5,5 +5,3 @@
/target/
src/main/main.iml
src/test/test.iml
bin
.env
-80
View File
@@ -1,80 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "APIFootballUpdater",
"request": "launch",
"mainClass": "de.jeyp91.App",
"envFile": "${workspaceFolder}/.env",
"args": ["--mode", "APIFootballUpdater", "--season", "2027", "--league", "1", "--configFile", "Tippliga"]
},
{
"type": "java",
"name": "MatchesCreatorFootball",
"request": "launch",
"mainClass": "de.jeyp91.App",
"envFile": "${workspaceFolder}/.env",
"args": ["--mode", "MatchesCreatorFootball", "--season", "2027", "--league", "1", "--configFile", "Tippliga"]
},
{
"type": "java",
"name": "MatchesUpdaterFootball",
"request": "launch",
"mainClass": "de.jeyp91.App",
"envFile": "${workspaceFolder}/.env",
"args": ["--mode", "MatchesUpdaterFootball", "--season", "2027", "--league", "1", "--configFile", "Tippliga"]
},
{
"type": "java",
"name": "MatchdaysUpdater",
"request": "launch",
"mainClass": "de.jeyp91.App",
"envFile": "${workspaceFolder}/.env",
"args": ["--mode", "MatchdaysUpdater", "--season", "2027", "--league", "1", "--configFile", "Tippliga"]
},
{
"type": "java",
"name": "MatchesResultsUpdater",
"request": "launch",
"mainClass": "de.jeyp91.App",
"envFile": "${workspaceFolder}/.env",
"args": ["--mode", "MatchesResultsUpdater", "--season", "2027", "--league", "1", "--configFile", "Tippliga"]
},
{
"type": "java",
"name": "MatchesListGistUpdater",
"request": "launch",
"mainClass": "de.jeyp91.App",
"envFile": "${workspaceFolder}/.env",
"args": ["--mode", "MatchesListGistUpdater", "--season", "2027", "--league", "1", "--configFile", "Tippliga"]
},
{
"type": "java",
"name": "TeamsUpdater",
"request": "launch",
"mainClass": "de.jeyp91.App",
"envFile": "${workspaceFolder}/.env",
"args": ["--mode", "TeamsUpdater", "--season", "2027", "--league", "1", "--configFile", "Tippliga"]
},
{
"type": "java",
"name": "WhatsAppNotifier",
"request": "launch",
"mainClass": "de.jeyp91.App",
"envFile": "${workspaceFolder}/.env",
"args": ["--mode", "WhatsAppNotifier", "--season", "2027", "--league", "1", "--configFile", "Tippliga"]
},
{
"type": "java",
"name": "SeasonPreparation",
"request": "launch",
"mainClass": "de.jeyp91.App",
"envFile": "${workspaceFolder}/.env",
"args": ["--mode", "SeasonPreparation", "--season", "2027", "--league", "0", "--configFile", "Dummy"]
}
]
}
-10
View File
@@ -1,10 +0,0 @@
{
"java.compile.nullAnalysis.mode": "automatic",
"java.configuration.updateBuildConfiguration": "interactive",
"java.test.config": {
"envFile": "${workspaceFolder}/.env"
},
"java.debug.settings.onBuildFailureProceed": true,
"jdk.jdkhome": "/Users/julian/.local/share/mise/installs/java/22.0.2",
"java.debug.settings.console": "internalConsole"
}
-91
View File
@@ -1,91 +0,0 @@
<!-- headroom:rtk-instructions -->
# RTK (Rust Token Killer) - Token-Optimized Commands
When running shell commands, **always prefix with `rtk`**. This reduces context
usage by 60-90% with zero behavior change. If rtk has no filter for a command,
it passes through unchanged — so it is always safe to use.
## Key Commands
```bash
# Git (59-80% savings)
rtk git status rtk git diff rtk git log
# Files & Search (60-75% savings)
rtk ls <path> rtk read <file> rtk grep <pattern>
rtk find <pattern> rtk diff <file>
# Build (80-90% savings) — shows errors only
rtk ./gradlew build rtk ./gradlew compileJava
# Test (90-99% savings) — shows failures only
rtk ./gradlew test
# Analysis (70-90% savings)
rtk err <cmd> rtk log <file> rtk json <file>
rtk summary <cmd> rtk deps rtk env
# GitHub (26-87% savings)
rtk gh pr view <n> rtk gh run list rtk gh issue list
# Infrastructure (85% savings)
rtk docker ps rtk kubectl get rtk docker logs <c>
```
## Rules
- In command chains, prefix each segment: `rtk git add . && rtk git commit -m "msg"`
- For debugging, use raw command without rtk prefix
- `rtk proxy <cmd>` runs command without filtering but tracks usage
<!-- /headroom:rtk-instructions -->
---
# TLW Database Tool — Agent Guide
## Project Overview
Java CLI tool managing the Tippliga Würzburg football prediction league. Syncs match data from API-Football, manages MySQL database (phpBB forum), pushes Google Calendar events, sends WhatsApp reminders via OpenAI-generated messages, and uploads fixtures to S3.
## Build & Test
```bash
./gradlew build # compile + test + jar
./gradlew test # run all tests
./gradlew clean test # clean build + test
./gradlew jar # build fat JAR (all deps bundled)
./gradlew dependencies # list dependency tree
```
## Run Modes (CLI)
```
-m MatchdaysUpdater - Update delivery dates from match times
-m MatchesCreatorFootball - Create match schedule from API-Football
-m MatchesUpdaterFootball - Update match team/datetime from API-Football
-m MatchesResultsUpdater - Push match results to website
-m TeamsUpdater - Add missing teams to DB
-m APIFootballUpdater - Fetch fixtures/rounds from API-Football → S3
-m MatchesListGistUpdater - Update forum posts with fixture lists
-m PostChecksum - Print checksum of a config post
-m WhatsAppNotifier - Send WhatsApp reminders for missing bets
```
Required: `-s <season> -l <league> -c <configFile>`
## Architecture
```
App.java (CLI entry)
├── apifootball/ — API-Football HTTP client, match model, S3 caching
├── googlecalendar/ — Google Calendar API CRUD for matchday events
├── teamidmatcher/ — BiMap: Tippliga team ID ↔ API-Football team ID
├── tippliga/ — Domain models & operations (match, matchday, team, league)
├── tippligaforum/ — MySQL DB connector, phpBB forum post management
└── whatsapp/ — OpenAI-generated reminders, WhatsApp API sender
```
## Code Conventions
- Package: `de.jeyp91.*`
- SQL columns referenced by ordinal position (constants like `final int SEASON = 1`)
- Logger via SLF4J: `LoggerFactory.getLogger(Class.class)`
- Config stored as JSON in phpBB forum posts (not local files)
- API keys / secrets in environment variables
## Testing
- JUnit 4 + TestNG
- Tests in `src/test/java/de/jeyp91/`
- Run single test: `./gradlew test --tests "de.jeyp91.apifootball.APIFootballMatchTest"`
-136
View File
@@ -1,136 +0,0 @@
# TLW Database Tool
CLI tool for **Tippliga Würzburg** football prediction league administration. Syncs match data from [API-Football](https://www.api-football.com/), manages a MySQL database backing a phpBB forum, pushes Google Calendar events, sends WhatsApp reminders with AI-generated messages via OpenAI, and uploads fixture data to S3.
## Architecture
```
App.java (CLI entry with argparse4j)
├── apifootball/ — API-Football HTTP client, match model, S3 caching
│ ├── APIFootballUpdater Fetch raw fixtures/rounds → S3
│ ├── APIFootballConnector Singleton, reads cached S3 data, resolves matchdays
│ ├── APIFootballMatch API-Football match model (extends BaseMatch)
│ └── APIFootballMatchesProvider Resolves config entries to match lists
├── googlecalendar/ — Google Calendar API CRUD
│ ├── GoogleCalendarConnector OAuth2 + service setup
│ ├── CalendarConfigProvider Reads calendar ID/URL from JSON resource
│ └── TippligaGoogleEventManager Create/update/delete matchday events
├── teamidmatcher/ — Bi-directional ID mapping
│ ├── TeamIDMatcher HashBiMap: Tippliga team ID ↔ API-Football ID
│ └── TeamIDMatcherTemplateCreator Generates config template from API teams
├── tippliga/ — Domain models & operations
│ ├── TLWMatch / TLWMatchday / TLWTeam / TLWLeague (DB-mapped models)
│ ├── TLWMatchesCreatorFootball Build match schedule from API data
│ ├── TLWMatchesCreatorTipperLeague Build tipper-vs-tipper league matches
│ ├── TLWMatchesCreatorTipperPokal Build knockout tournament matches
│ ├── TLWMatchesUpdaterFootball Update teams/datetimes from API
│ ├── TLWMatchesResultsUpdater Push finished match results to website
│ ├── TLWMatchdaysCreator Compute delivery dates from match times
│ ├── TLWMatchdaysUpdater Write delivery date updates to DB + Calendar
│ ├── TLWTeamsCreator / TLWTeamsUpdater Team management
│ └── TLWMatchesManagerBase Shared helpers (date math, match matching)
├── tippligaforum/ — MySQL + phpBB integration
│ ├── TippligaSQLConnector Singleton JDBC connector (all queries)
│ ├── TippligaConfigProvider Reads JSON config from forum posts
│ ├── TippligaWebsiteConnector HTTP client for admin result updates
│ └── MatchesListCreator / MatchesListForumUpdater Fixture list posts
└── whatsapp/ — WhatsApp reminder system
├── WhatsAppNotifier Sends messages via WhatsApp API
├── OpenAIConnector Generates reminder text via GPT-3.5
└── WhatsAppReminder Record: user, matchday, missing bets
BaseMatch — Abstract match with status/comparison/shared fields
S3Provider — AWS S3 read/write for cached API-Football JSON
ResourceProvider — Reads JSON config files from classpath resources
StatusHolder — Global error flag
```
## Setup
### Prerequisites
- Java 17+
- MySQL database (phpBB with Tippliga extension)
- API-Football API key (free tier)
- Google Calendar API service account + credentials file
- AWS S3 bucket for fixture caching
- WhatsApp API endpoint
### Environment Variables
| Variable | Description |
|---|---|
| `TLW_DATABASE_USERNAME` | MySQL username |
| `TLW_DATABASE_PASSWORD` | MySQL password |
| `FORUM_USERNAME` | phpBB admin username (for website connector) |
| `FORUM_PASSWORD` | phpBB admin password |
| `OPENAI_TOKEN` | OpenAI API token (GPT reminders) |
| `TLW_WHATSAPP_HOST` | WhatsApp API host |
| `TLW_WHATSAPP_PORT` | WhatsApp API port |
| `TLW_WHATSAPP_API_KEY` | WhatsApp API key |
| `AWS_ACCESS_KEY_ID` | AWS credentials (S3) |
| `AWS_SECRET_ACCESS_KEY` | AWS credentials (S3) |
### Resources
Place these in `src/main/resources/`:
- `Tippliga/Team_ID_Matcher_Config.json` — team ID mapping
- `Tippliga/Ligen_v3.json` — league definitions
- `Google_Calendar_Config.json` — calendar IDs
- `Tippliga_Configs/<config>.json` — per-season match configs
Configs are stored as phpBB forum posts (JSON wrapped in `[code]` BBCode).
## Usage
```bash
# Build fat JAR
./gradlew jar
# Run modes (all require -s <season> -l <league> -c <configFile>)
java -jar build/libs/tlw-database-tool-1.0.jar -m MatchdaysUpdater -s 2025 -l 1 -c tl_2025
```
### CLI Modes
| Mode | Function |
|---|---|
| `MatchdaysUpdater` | Update delivery dates from match times, sync Google Calendar |
| `MatchesCreatorFootball` | Create match schedule from API-Football |
| `MatchesUpdaterFootball` | Update match teams/datetimes from API-Football |
| `MatchesResultsUpdater` | Push finished results to website |
| `TeamsUpdater` | Add missing teams to DB |
| `APIFootballUpdater` | Fetch raw fixtures/rounds → S3 |
| `MatchesListGistUpdater` | Update forum posts with fixture lists |
| `PostChecksum` | Print MD5 checksum of a config post |
| `WhatsAppNotifier` | Send WhatsApp reminders for missing bets |
### Build Commands
```bash
./gradlew build # compile + test + jar
./gradlew test # run all tests
./gradlew clean test # clean build + test
./gradlew jar # build fat JAR
./gradlew dependencies # list dependency tree
```
## Code Conventions
- Package: `de.jeyp91.*`
- SQL columns referenced by ordinal position in ResultSet (constants like `final int SEASON = 1`)
- Logger via SLF4J: `LoggerFactory.getLogger(Class.class)`
- Match status constants inherited from `BaseMatch`
- Config JSON stored in phpBB forum posts, loaded via `TippligaConfigProvider`
- Secrets in environment variables only
## Testing
- JUnit 4 + TestNG
- Tests under `src/test/java/de/jeyp91/`
- Run single test: `./gradlew test --tests "de.jeyp91.apifootball.APIFootballMatchTest"`
## How It Works (Data Flow)
1. **APIFootballUpdater** fetches fixtures/rounds from API-Football → caches in S3
2. **APIFootballConnector** reads cached S3 data, resolves API matchdays to Tippliga matchdays
3. **TLWMatchesCreatorFootball** config on which API matches map to which Tippliga matchdays → SQL INSERT
4. **TLWMatchdaysCreator** computes delivery deadlines from match times
5. **TLWMatchdaysUpdater** writes deadlines to DB + creates/updates Google Calendar events
6. **TLWMatchesUpdaterFootball** updates team IDs, datetimes from latest API data
7. **TLWMatchesResultsUpdater** pushes finished match results to the website via HTTP
8. **WhatsAppNotifier** queries DB for users with missing bets, generates GPT reminders, sends via WhatsApp API
+18 -38
View File
@@ -2,13 +2,12 @@
* This file was generated by the Gradle 'init' task.
*/
plugins {
id 'com.github.ben-manes.versions' version '0.52.0'
id 'java'
id 'application'
}
apply plugin: 'java'
apply plugin: 'application'
mainClassName = 'App'
sourceCompatibility = 11
targetCompatibility = 11
version = '1.0'
compileJava.options.encoding = 'UTF-8'
compileTestJava.options.encoding = 'UTF-8'
@@ -19,42 +18,23 @@ repositories {
}
dependencies {
implementation 'mysql:mysql-connector-java:8.0.33'
implementation 'mysql:mysql-connector-java:8.0.32'
implementation 'org.apache.httpcomponents:httpclient:4.5.14'
implementation 'com.googlecode.json-simple:json-simple:1.1.1'
implementation 'com.google.code.gson:gson:2.11.0'
implementation 'com.google.auth:google-auth-library-oauth2-http:1.31.0'
implementation 'com.google.api-client:google-api-client:2.7.2'
implementation 'com.google.apis:google-api-services-calendar:v3-rev20250115-2.0.0'
implementation 'com.google.guava:guava:33.4.0-jre'
implementation 'commons-cli:commons-cli:1.9.0'
implementation 'com.google.code.gson:gson:2.10.1'
implementation platform('com.amazonaws:aws-java-sdk-bom:1.12.429')
implementation 'com.amazonaws:aws-java-sdk-s3:1.12.429'
implementation 'com.google.auth:google-auth-library-oauth2-http:1.16.0'
implementation 'com.google.api-client:google-api-client:2.2.0'
implementation 'com.google.apis:google-api-services-calendar:v3-rev20220715-2.0.0'
implementation 'com.google.guava:guava:31.1-jre'
implementation 'commons-cli:commons-cli:1.5.0'
implementation 'net.sourceforge.argparse4j:argparse4j:0.9.0'
implementation 'org.slf4j:slf4j-api:1.6.1'
implementation 'org.slf4j:slf4j-simple:1.6.1'
implementation 'javax.xml.bind:jaxb-api:2.4.0-b180830.0359'
implementation 'software.amazon.awssdk:s3:2.30.6'
implementation 'org.apache.logging.log4j:log4j-api:2.20.0'
implementation 'org.apache.logging.log4j:log4j-core:2.20.0'
implementation 'javax.xml.bind:jaxb-api:2.3.1'
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.testng:testng:7.10.2'
}
def envFile = file('.env')
if (envFile.exists()) {
def envVars = [:]
envFile.readLines().each { line ->
def trimmed = line.trim()
if (trimmed && !trimmed.startsWith('#')) {
def parts = trimmed.split('=', 2)
if (parts.size() == 2) {
def key = parts[0].trim()
def value = parts[1].trim()
if (value.startsWith('"') && value.endsWith('"')) {
value = value.substring(1, value.length() - 1)
}
envVars[key] = value
}
}
}
test { environment envVars }
testImplementation 'org.testng:testng:7.7.0'
}
jar {
@@ -70,4 +50,4 @@ jar {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
duplicatesStrategy = DuplicatesStrategy.INCLUDE
}
}
-39
View File
@@ -1,39 +0,0 @@
# apifootball — API-Football Integration
Fetches, caches, and serves match data from [API-Football](https://www.api-football.com/). Raw JSON is cached in S3 to avoid repeated API calls.
## Classes
### APIFootballUpdater
HTTP client that fetches raw JSON from API-Football and writes to S3.
- `updateAllFixtures(season)` — fetches all leagues' fixtures
- `updateAllRounds(season)` — fetches all leagues' round metadata
- `getRawData(requestPath, season, league)` — calls API-Football with rate-limit retry
- `getLeagues()` — reads league IDs from `Ligen_v3.json` resource
Handles the Tippliga↔API-Football season offset: for most leagues, Tippliga season N corresponds to API-Football season N-1 (except World Cup `league=1` and Euro `league=4`).
### APIFootballConnector
Singleton that reads cached S3 JSON and resolves API data into `APIFootballMatch` objects.
- `getMatchDataByLeagueAndMatchday(league, matchday)` — all matches for a matchday
- `getMatchDataByLeagueAndMatchID(league, id)` — single match by API fixture ID
- `getMatchdays(leagueId)` — round metadata from S3
- `getTeamsForLeague(season, league)` — live team list from API
### APIFootballMatch
Extends `BaseMatch`. Parses a raw API-Football JSON fixture object.
Parses: fixture ID, league ID, team IDs + names, round string, datetime, status, fulltime/extratime/penalty scores.
Key method: `getMatchdayFromRoundString(season, round, leagueId)` — converts API round names (e.g. `"Regular Season - 1"`) to Tippliga matchday numbers. Falls back to the rounds JSON for non-regular-season formats.
### APIFootballMatchesProvider
High-level resolver that reads matchday config (from the JSON config file) and returns flat `APIFootballMatch` lists.
Supports two config entry types:
- `AllMatchesOfMatchday` — fetch all matches for a given API league+matchday
- `SingleMatch` — fetch a specific match by API league+fixture ID
Honors `showTable` and `ko` flags from config.
-29
View File
@@ -1,29 +0,0 @@
# googlecalendar — Google Calendar Integration
Manages matchday deadline events in Google Calendar. Each matchday can have up to 3 delivery deadlines (1st, 2nd, 3rd chance).
## Classes
### GoogleCalendarConnector
Sets up the Google Calendar API service using a service account.
- Reads service account credentials from `tippliga-4e0def9ef447.json` (classpath resource)
- Uses `CalendarScopes.CALENDAR` scope
- Returns authenticated `com.google.api.services.calendar.Calendar` service
### CalendarConfigProvider
Reads calendar ID and URL from `Google_Calendar_Config.json` resource. Currently hardcoded to league 1.
### TippligaGoogleEventManager
CRUD operations for matchday deadline events.
- `createOrUpdateEventsForMatchday(matchday)` — creates/updates up to 3 events per matchday
- `createNewEvent()` / `updateEvent()` / `deleteEvent()` — individual event operations
- `deleteAllEvents(season)` — wipe all events for a season
- `updateAllMatchdays(matchdays)` — batch update; automatically deletes events for removed delivery dates
Event details:
- **Summary**: `"Tippliga Spieltag N tippen!"` (or custom matchday name)
- **Description**: season, league, matchday, delivery deadline number
- **Location**: `https://tippliga-wuerzburg.de/app.php/football/bet`
- **Time**: delivery deadline datetime, Europe/Berlin timezone
-25
View File
@@ -1,25 +0,0 @@
# teamidmatcher — Team ID Mapping
Maintains a bi-directional mapping between Tippliga (phpBB) team IDs and API-Football team IDs. Uses a Guava `HashBiMap` loaded from `Team_ID_Matcher_Config.json`.
## Classes
### TeamIDMatcher
Singleton `HashBiMap<Integer, Integer>` mapping Tippliga IDs ↔ API-Football IDs.
- `getApiFootballIdFromTippligaId(id)` — Tippliga → API-Football
- `getTippligaIdFromApiFootballId(match, homeguest)` — API-Football → Tippliga, for a given match and team side
- `getTeamNameFromTippligaId(id)` — human-readable team name
Sets `StatusHolder.setError()` if a lookup fails. Used by `TLWMatch`, `TLWMatchesUpdaterFootball`, `TLWMatchesResultsUpdater`.
Config format (`Team_ID_Matcher_Config.json`):
```json
[
{ "tippligaID": 1, "teamname": "Team Name", "apiFootballID": 12345 },
...
]
```
### TeamIDMatcherTemplateCreator
Utility that fetches teams from API-Football for a given league and generates a JSON config template. Useful when setting up new seasons — outputs skeleton entries with `apiFootballID` pre-filled, `tippligaID` left blank.
-99
View File
@@ -1,99 +0,0 @@
# tippliga — Domain Models & Operations
Core domain package with match, matchday, team, and league models plus operations for creating, updating, and managing the prediction league schedule. All extend `TLWMatchesManagerBase` or `TLWMatchesCreatorBase`.
## Base Classes
### BaseMatch (`de.jeyp91.BaseMatch`)
Abstract class with shared match state: team IDs, goals (home/guest/overtime/penalty), datetime, status, KO flag, show-table flag, and a `COMPARISON` enum (`IDENTICAL`, `DIFFERENT`, `DIFFERENT_DATETIME`, `DIFFERENT_RESULT`).
Status constants:
- `STATUS_NOTSTARTED = 0`
- `STATUS_STARTED = 1`
- `STATUS_PROVISIONAL_RESULT_AVAILABLE = 2`
- `STATUS_FINISHED = 3`
- `STATUS_NOT_EVALUATED = 4`
### TLWMatchesCreatorBase
Abstract creator with `TLWMatches` list, `getSQLInsertString()` generating `REPLACE INTO` queries, `getMatchesForMatchday()`, and `getNumberOfMatchdays()`.
### TLWMatchesManagerBase
Shared helpers used by updaters:
- Date parsing from TLW (`yyyy-MM-dd HH:mm:ss`) and API-Football (`yyyy-MM-dd'T'HH:mm:ss`) formats
- `getFirstMatchtimeTLW()` / `getFirstMatchtimeAPIFootball()` — earliest match in a list
- `getDaysDifference()` — calendar day diff
- `getMatchesStartingFromSecondDay()` / `getMatchesStartingFromSecondWeek()` — filter helpers for delivery date computation
- `getMatchingMatch()` — matches an API match to a TLW match by home/guest team IDs
## Domain Models
### TLWMatch (extends BaseMatch)
Full match model mapped from `phpbb_footb_matches` table. Multiple constructors:
- From `ResultSet` (DB query)
- From `APIFootballMatch` + `TeamIDMatcher` (API sync)
- Manual constructors for creators
- Copy constructor
Key methods:
- `getSQLQueryInsert()` / `getSQLQueryReplace()` — generates SQL values
- `updateMatch(APIFootballMatch)` — updates teams, goals, datetime from API data
- `isSameMatchPlaceholder()` — matches placeholder config entries to existing matches
### TLWMatchday
Mapped from `phpbb_footb_matchdays`. Fields: season, league, matchday, status, 3 delivery dates, matchday name, match count.
### TLWTeam
Mapped from `phpbb_footb_teams`. Fields: season, league, team ID, name, short name, symbol, group ID, matchday.
### TLWLeague
Mapped from `phpbb_footb_leagues`. Fields: season, league ID, league name, short name.
## Operations
### TLWMatchesCreatorFootball
Builds match schedule from API-Football data and JSON config. For each matchday config entry:
1. Resolves API matches via `APIFootballMatchesProvider`
2. Creates `TLWMatch` objects with team IDs matched via `TeamIDMatcher`
3. Fills remaining slots with placeholder matches (empty teams)
Handles `deliveryDateMode`: in `"single"` mode, matches beyond the first day get `status = -1` to prevent early betting on later matches.
### TLWMatchesCreatorTipperLeague
Creates matches for tipper-vs-tipper leagues (where tippers are "teams"). Reads pairing config from `Tipper_Match_Pair_Config.json` and tipper-team mapping from `Tipper_Team_Config.json`.
### TLWMatchesCreatorTipperPokal
Creates single-matchday knockout tournament matches from a tipper list config. Each pair of tippers is one match with `koMatch = 1` and `showTable = false`.
### TLWMatchesUpdaterFootball
Compares current DB matches with latest API data and generates SQL UPDATE statements. Only operates on matchdays where the first match is still in the future. Updates:
- Team IDs (via `TeamIDMatcher`)
- Match datetimes
- Status flags (0 = current matchday, -1 = next-day match, -2 = later)
- `show_table` / `ko_match` flags
Also handles:
- `addMissingMatches()` — inserts API matches not yet in DB (finds placeholder slots by datetime/formula)
- `addPlaceholderMatches()` — adds config-defined placeholders for TBD matchups
### TLWMatchesResultsUpdater
For finished matches, compares DB goals with API goals and pushes updates to the website via `TippligaWebsiteConnector`. Detects changes to:
- Full-time goals
- Overtime goals (for KO matches with `betKOType = 2`)
- Penalty → overtime mapping (for `betKOType = 1` or `3`)
- Status transitions from provisional to confirmed
### TLWMatchdaysCreator
Computes delivery dates (betting deadlines) from match times. Supports two modes:
- **"single"**: one deadline = first match time
- **"multiple"** (default): 3 deadlines — first match, first match of second day, first match of second week
Also handles `additionalDeliveryDate` config flags for special matchday events.
### TLWMatchdaysUpdater
Compares original DB matchdays with recomputed deadlines and generates SQL UPDATEs and Google Calendar syncs. Only updates future matchdays (deadline in the past is skipped).
### TLWTeamsCreator
Extracts unique team IDs from a list of matches and generates `REPLACE INTO phpbb_footb_teams` SQL, preserving group and matchday info from match data.
### TLWTeamsUpdater
Detects teams referenced in matches but not yet present in the league's team table. Generates INSERT SQL to add them (copies team metadata from existing entries in other seasons/leagues).
-48
View File
@@ -1,48 +0,0 @@
# tippligaforum — MySQL & phpBB Integration
Database connector, config loader, website HTTP client, and forum post management.
## Classes
### TippligaSQLConnector
Singleton JDBC connector to the phpBB MySQL database (`d0144ddb`). Connects to production via credentials from environment variables, with a fallback to localhost.
All major queries in one class:
- `getTeams()`, `getMatches()`, `getMatchdays()`, `getLeague()` — read domain objects
- `getUpdatedMatchdaysBasedOnMatches()` — complex SQL that computes delivery deadlines from match times (uses `DATEDIFF` to split deadlines across days/weeks)
- `getNextWhatsAppReminders(hours)` — multi-table query finding users with missing bets on upcoming matchdays, joins with reminder tracking to avoid duplicates
- `updatePost()` / `getPost()` / `getChecksumOfPost()` — phpBB post CRUD
- `executeQuery()` / `executeUpdate()` — raw SQL access
- `markWhatsAppReminderAsSent()` — logs sent reminders
Post updates use the phpBB checksum mechanism: `post_checksum` = MD5 of XML-escaped post text.
### TippligaConfigProvider
Reads JSON configuration from phpBB forum posts. Configs are stored as topics under the `Admin → Tippliga-Config → <season>` forum hierarchy.
- `getTippligaConfig(config)` — fetches post, strips `[code]` BBCode wrapper, parses JSON
- `getChecksumOfConfigPost(configFile)` — reads post checksum for integrity verification
### TippligaWebsiteConnector
HTTP client that logs into the phpBB frontend + admin panel and submits match results. Used by `TLWMatchesResultsUpdater`.
Login flow:
1. GET login page → extract `creation_time`, `form_token`, `sid` from hidden fields
2. POST credentials → capture session cookies
3. GET admin panel → extract admin credential token
4. POST admin login with `password_<credential>` parameter
Result submission:
1. GET results management page → extract CSRF tokens
2. POST form with season, league, matchday, match scores (home, guest, overtime)
### MatchesListCreator
Generates a JSON match list config from raw API-Football fixture data (read from S3). Creates `SingleMatch` config entries with matchday, matchtime, team names, and fixture IDs. Used by `MatchesListForumUpdater` to create fixture list forum posts.
### MatchesListForumUpdater
For each league:
1. Creates `MatchesListCreator` from S3 fixture data
2. Formats as pretty-printed JSON
3. Wraps in `[code]` BBCode
4. Finds the correct forum post (under `Admin → Tippliga-Config → <season> → Ligen → <country> <league>`)
5. Updates the post text via `TippligaSQLConnector`
-40
View File
@@ -1,40 +0,0 @@
# whatsapp — WhatsApp Reminder System
Sends personalized WhatsApp reminders to users who haven't submitted their bets before the deadline. Uses OpenAI GPT-3.5 to generate natural-language reminder messages.
## Classes
### WhatsAppNotifier
Orchestrates the reminder workflow:
1. Queries DB for upcoming reminders at 2 checkpoints: **24 hours** and **2 hours** before deadline
2. For each reminder, generates a message via `OpenAIConnector`
3. Sends via WhatsApp API (HTTP POST to configurable host:port)
4. Marks sent reminders in DB to avoid duplicates
Requires env vars: `TLW_WHATSAPP_HOST`, `TLW_WHATSAPP_PORT`, `TLW_WHATSAPP_API_KEY`.
### OpenAIConnector
Caches and generates reminder text via OpenAI Chat Completions API (model `gpt-3.5-turbo-0125`).
Prompt structure:
- **System prompt** (German): "Generate a message reminding someone to submit missing tips. Must sound like a friend. Use correct singular/plural."
- **User input**: JSON with league name, matchday name, delivery day, time
- **Output template** has 2 variants — 24h deadline uses a friendly intro, 2h deadline emphasizes urgency
Message format:
```
Hey <username>,
<AI-generated intro>
Bitte gib die fehlenden Tipps bis <today/morgen> um <HH:MM> ab.
Du kannst deine Tipps wie immer unter https://tippliga-wuerzburg.de/app.php/football/bet abgeben.
Viele Grüße
Die Tippliga Admins
```
Messages are cached per (league + matchday + delivery) key to avoid repeated API calls.
### WhatsAppReminder
Java `record` with fields: season, league, leagueName, matchday, matchdayName, deliveryDate, todayTomorrow, time, remainingHours, userId, username, phoneNumber, missingBets.
Maps directly to the SQL query result from `TippligaSQLConnector.getNextWhatsAppReminders()`.
-2
View File
@@ -1,2 +0,0 @@
#This file is generated by updateDaemonJvm
toolchainVersion=22
+1 -1
View File
@@ -1,5 +1,5 @@
#Tue May 26 17:58:07 CEST 2020
distributionUrl=https://services.gradle.org/distributions/gradle-8.12.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-all.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
+6 -10
View File
@@ -10,21 +10,20 @@ pipeline {
stage('Execute') {
steps {
script {
String jdkPath = tool name: 'OpenJDK22', type: 'jdk'
String jdkPath = tool name: 'OpenJDK19', type: 'jdk'
withCredentials([
usernamePassword(credentialsId: 'aws', usernameVariable: 'AWS_ACCESS_KEY_ID', passwordVariable: 'AWS_SECRET_ACCESS_KEY'),
usernamePassword(credentialsId: 'aws', usernameVariable: 'AWS_ACCESS_KEY_ID', passwordVariable: 'AWS_SECRET_KEY'),
usernamePassword(credentialsId: 'forum_database', usernameVariable: 'TLW_DATABASE_USERNAME', passwordVariable: 'TLW_DATABASE_PASSWORD'),
usernamePassword(credentialsId: 'forum_user', usernameVariable: 'FORUM_USERNAME', passwordVariable: 'FORUM_PASSWORD')
]) {
withEnv([
"JAVA_HOME=${jdkPath}/jdk-22.0.2"
"JAVA_HOME=${jdkPath}/jdk-19.0.2"
]) {
try {
sh "java --version"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode APIFootballUpdater --season ${season} --league 1 --configFile Tippliga >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesListGistUpdater --season ${season} --league 1 --configFile Tippliga >> log.txt 2>&1"
sh "java -jar build/libs/tlw-database-tool-1.0.jar --mode APIFootballUpdater --season ${season} --league 1 --configFile Tippliga 2>&1 >> log.txt"
sh "java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesListGistUpdater --season ${season} --league 1 --configFile Tippliga 2>&1 >> log.txt"
} catch (Exception e) {
telegramSendManual("TLW-Database-Tool crashed in APIFootballUpdater!")
telegramSendManual("TLW-Database-Tool crashed!")
}
String outputString = readFile 'log.txt'
if(outputString != "") {
@@ -44,9 +43,6 @@ pipeline {
echo 'Trigger jobs'
build wait: false, job: 'TippligaUpdater'
build wait: false, job: 'WTLPokalUpdater'
build wait: false, job: 'SupercupUpdater'
build wait: false, job: 'RelegationUpdater'
build wait: false, job: 'LigaCupUpdater'
}
}
}
+5 -5
View File
@@ -10,19 +10,19 @@ pipeline {
stage('GetAndWriteChecksum') {
steps {
script {
String jdkPath = tool name: 'OpenJDK22', type: 'jdk'
String jdkPath = tool name: 'OpenJDK19', type: 'jdk'
withCredentials([
usernamePassword(credentialsId: 'aws', usernameVariable: 'AWS_ACCESS_KEY_ID', passwordVariable: 'AWS_SECRET_ACCESS_KEY'),
usernamePassword(credentialsId: 'aws', usernameVariable: 'AWS_ACCESS_KEY_ID', passwordVariable: 'AWS_SECRET_KEY'),
usernamePassword(credentialsId: 'forum_database', usernameVariable: 'TLW_DATABASE_USERNAME', passwordVariable: 'TLW_DATABASE_PASSWORD'),
usernamePassword(credentialsId: 'forum_user', usernameVariable: 'FORUM_USERNAME', passwordVariable: 'FORUM_PASSWORD')
]) {
withEnv([
"JAVA_HOME=${jdkPath}/jdk-22.0.2"
"JAVA_HOME=${jdkPath}/jdk-19.0.2"
]) {
String checksum_tippliga = sh returnStdout: true, script: "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode PostChecksum --season ${season} --league 1 --configFile Tippliga 2>&1"
String checksum_tippliga = sh returnStdout: true, script: "java -jar build/libs/tlw-database-tool-1.0.jar --mode PostChecksum --season ${season} --league 1 --configFile Tippliga 2>&1"
writeFile file: 'checksum_tippliga.txt', text: checksum_tippliga
archiveArtifacts artifacts: 'checksum_tippliga.txt', followSymlinks: false
String checksum_wtlpokal = sh returnStdout: true, script: "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode PostChecksum --season ${season} --league 1 --configFile WTL-Pokal 2>&1"
String checksum_wtlpokal = sh returnStdout: true, script: "java -jar build/libs/tlw-database-tool-1.0.jar --mode PostChecksum --season ${season} --league 1 --configFile WTL-Pokal 2>&1"
writeFile file: 'checksum_wtlpokal.txt', text: checksum_wtlpokal
archiveArtifacts artifacts: 'checksum_wtlpokal.txt', followSymlinks: false
}
-82
View File
@@ -1,82 +0,0 @@
pipeline {
agent any
stages {
stage('Restore tlw-database-tool') {
steps {
copyArtifacts filter: '**/tlw-database-tool-1.0.jar', fingerprintArtifacts: true, projectName: 'build tlw-database-tool', selector: lastSuccessful(), target: '.'
}
}
stage('Execute') {
steps {
script {
String jdkPath = tool name: 'OpenJDK22', type: 'jdk'
withCredentials([
usernamePassword(credentialsId: 'aws', usernameVariable: 'AWS_ACCESS_KEY_ID', passwordVariable: 'AWS_SECRET_ACCESS_KEY'),
usernamePassword(credentialsId: 'forum_database', usernameVariable: 'TLW_DATABASE_USERNAME', passwordVariable: 'TLW_DATABASE_PASSWORD'),
usernamePassword(credentialsId: 'forum_user', usernameVariable: 'FORUM_USERNAME', passwordVariable: 'FORUM_PASSWORD'),
string(credentialsId: 'google_calendar_private_key_id', variable: 'GOOGLE_CALENDAR_TIPPLIGA_SERVICE_ACCOUNT_PRIVATE_KEY_ID'),
string(credentialsId: 'google_calendar_private_key', variable: 'GOOGLE_CALENDAR_TIPPLIGA_SERVICE_ACCOUNT_PRIVATE_KEY')
]) {
withEnv([
"JAVA_HOME=${jdkPath}/jdk-22.0.2"
]) {
try {
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesResultsUpdater --season ${season} --league 49 --configFile WM-Tippspiel >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesUpdaterFootball --season ${season} --league 49 --configFile WM-Tippspiel >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchdaysUpdater --season ${season} --league 49 --configFile WM-Tippspiel >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode TeamsUpdater --season ${season} --league 49 --configFile WM-Tippspiel >> log.txt 2>&1"
} catch (Exception e) {
telegramSendManual("TLW-Database-Tool crashed in LigaCupUpdater!")
}
String outputString = readFile 'log.txt'
if(outputString != "") {
ArrayList<String> outputList = outputString.replace("\n\n", "\n").split('\n').toList()
outputList = clean(outputList)
outputList.each {
telegramSendManual(it)
}
}
}
}
}
}
}
}
post {
always {
deleteDir()
}
failure {
telegramSendManual("Build failed!\n${env.BUILD_URL}console")
}
}
}
private ArrayList<String> clean(ArrayList<String> orig) {
ArrayList<String> cleaned = new ArrayList<String>()
orig.each{line ->
if(line.indexOf(" [main] INFO de.jeyp91 - ") >= 0) {
line = line.substring(20, line.size())
}
if(line.indexOf(" [main] ERROR de.jeyp91") >= 0) {
line = line.substring(20, line.size())
}
cleaned.add(line)
}
return cleaned.unique()
}
def telegramSendManual(String text) {
def encodedMessage = URLEncoder.encode(text, "UTF-8")
println encodedMessage
httpRequest(
httpMode: 'GET',
contentType: 'APPLICATION_JSON',
responseHandle: 'NONE',
url: "https://api.telegram.org/bot1298223079:AAEplcQpfzFG59qNYAYuSbJKtB9HMXCCE_U/sendMessage?text=$encodedMessage&chat_id=459231986&disable_web_page_preview=true",
wrapAsMultipart: false,
consoleLogResponseBody: true
)
}
-82
View File
@@ -1,82 +0,0 @@
pipeline {
agent any
stages {
stage('Restore tlw-database-tool') {
steps {
copyArtifacts filter: '**/tlw-database-tool-1.0.jar', fingerprintArtifacts: true, projectName: 'build tlw-database-tool', selector: lastSuccessful(), target: '.'
}
}
stage('Execute') {
steps {
script {
String jdkPath = tool name: 'OpenJDK22', type: 'jdk'
withCredentials([
usernamePassword(credentialsId: 'aws', usernameVariable: 'AWS_ACCESS_KEY_ID', passwordVariable: 'AWS_SECRET_ACCESS_KEY'),
usernamePassword(credentialsId: 'forum_database', usernameVariable: 'TLW_DATABASE_USERNAME', passwordVariable: 'TLW_DATABASE_PASSWORD'),
usernamePassword(credentialsId: 'forum_user', usernameVariable: 'FORUM_USERNAME', passwordVariable: 'FORUM_PASSWORD'),
string(credentialsId: 'google_calendar_private_key_id', variable: 'GOOGLE_CALENDAR_TIPPLIGA_SERVICE_ACCOUNT_PRIVATE_KEY_ID'),
string(credentialsId: 'google_calendar_private_key', variable: 'GOOGLE_CALENDAR_TIPPLIGA_SERVICE_ACCOUNT_PRIVATE_KEY')
]) {
withEnv([
"JAVA_HOME=${jdkPath}/jdk-22.0.2"
]) {
try {
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesResultsUpdater --season ${season} --league 47 --configFile Relegation >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesUpdaterFootball --season ${season} --league 47 --configFile Relegation >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchdaysUpdater --season ${season} --league 47 --configFile Relegation >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode TeamsUpdater --season ${season} --league 47 --configFile Relegation >> log.txt 2>&1"
} catch (Exception e) {
telegramSendManual("TLW-Database-Tool crashed in RelegationUpdater!")
}
String outputString = readFile 'log.txt'
if(outputString != "") {
ArrayList<String> outputList = outputString.replace("\n\n", "\n").split('\n').toList()
outputList = clean(outputList)
outputList.each {
telegramSendManual(it)
}
}
}
}
}
}
}
}
post {
always {
deleteDir()
}
failure {
telegramSendManual("Build failed!\n${env.BUILD_URL}console")
}
}
}
private ArrayList<String> clean(ArrayList<String> orig) {
ArrayList<String> cleaned = new ArrayList<String>()
orig.each{line ->
if(line.indexOf(" [main] INFO de.jeyp91 - ") >= 0) {
line = line.substring(20, line.size())
}
if(line.indexOf(" [main] ERROR de.jeyp91") >= 0) {
line = line.substring(20, line.size())
}
cleaned.add(line)
}
return cleaned.unique()
}
def telegramSendManual(String text) {
def encodedMessage = URLEncoder.encode(text, "UTF-8")
println encodedMessage
httpRequest(
httpMode: 'GET',
contentType: 'APPLICATION_JSON',
responseHandle: 'NONE',
url: "https://api.telegram.org/bot1298223079:AAEplcQpfzFG59qNYAYuSbJKtB9HMXCCE_U/sendMessage?text=$encodedMessage&chat_id=459231986&disable_web_page_preview=true",
wrapAsMultipart: false,
consoleLogResponseBody: true
)
}
+9 -11
View File
@@ -10,24 +10,22 @@ pipeline {
stage('Execute') {
steps {
script {
String jdkPath = tool name: 'OpenJDK22', type: 'jdk'
String jdkPath = tool name: 'OpenJDK19', type: 'jdk'
withCredentials([
usernamePassword(credentialsId: 'aws', usernameVariable: 'AWS_ACCESS_KEY_ID', passwordVariable: 'AWS_SECRET_ACCESS_KEY'),
usernamePassword(credentialsId: 'aws', usernameVariable: 'AWS_ACCESS_KEY_ID', passwordVariable: 'AWS_SECRET_KEY'),
usernamePassword(credentialsId: 'forum_database', usernameVariable: 'TLW_DATABASE_USERNAME', passwordVariable: 'TLW_DATABASE_PASSWORD'),
usernamePassword(credentialsId: 'forum_user', usernameVariable: 'FORUM_USERNAME', passwordVariable: 'FORUM_PASSWORD'),
string(credentialsId: 'google_calendar_private_key_id', variable: 'GOOGLE_CALENDAR_TIPPLIGA_SERVICE_ACCOUNT_PRIVATE_KEY_ID'),
string(credentialsId: 'google_calendar_private_key', variable: 'GOOGLE_CALENDAR_TIPPLIGA_SERVICE_ACCOUNT_PRIVATE_KEY')
usernamePassword(credentialsId: 'forum_user', usernameVariable: 'FORUM_USERNAME', passwordVariable: 'FORUM_PASSWORD')
]) {
withEnv([
"JAVA_HOME=${jdkPath}/jdk-22.0.2"
"JAVA_HOME=${jdkPath}/jdk-19.0.2"
]) {
try {
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesResultsUpdater --season ${season} --league 45 --configFile Supercup >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesUpdaterFootball --season ${season} --league 45 --configFile Supercup >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchdaysUpdater --season ${season} --league 45 --configFile Supercup >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode TeamsUpdater --season ${season} --league 45 --configFile Supercup >> log.txt 2>&1"
sh "java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesUpdaterFootball --season ${season} --league 45 --configFile Supercup 2>&1 >> log.txt"
sh "java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchdaysUpdater --season ${season} --league 45 --configFile Supercup 2>&1 >> log.txt"
sh "java -jar build/libs/tlw-database-tool-1.0.jar --mode TeamsUpdater --season ${season} --league 45 --configFile Supercup 2>&1 >> log.txt"
sh "java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesResultsUpdater --season ${season} --league 45 --configFile Supercup 2>&1 >> log.txt"
} catch (Exception e) {
telegramSendManual("TLW-Database-Tool crashed in SupercupUpdater!")
telegramSendManual("TLW-Database-Tool crashed!")
}
String outputString = readFile 'log.txt'
if(outputString != "") {
+14 -16
View File
@@ -10,31 +10,29 @@ pipeline {
stage('Execute') {
steps {
script {
String jdkPath = tool name: 'OpenJDK22', type: 'jdk'
String jdkPath = tool name: 'OpenJDK19', type: 'jdk'
withCredentials([
usernamePassword(credentialsId: 'aws', usernameVariable: 'AWS_ACCESS_KEY_ID', passwordVariable: 'AWS_SECRET_ACCESS_KEY'),
usernamePassword(credentialsId: 'aws', usernameVariable: 'AWS_ACCESS_KEY_ID', passwordVariable: 'AWS_SECRET_KEY'),
usernamePassword(credentialsId: 'forum_database', usernameVariable: 'TLW_DATABASE_USERNAME', passwordVariable: 'TLW_DATABASE_PASSWORD'),
usernamePassword(credentialsId: 'forum_user', usernameVariable: 'FORUM_USERNAME', passwordVariable: 'FORUM_PASSWORD'),
string(credentialsId: 'google_calendar_private_key_id', variable: 'GOOGLE_CALENDAR_TIPPLIGA_SERVICE_ACCOUNT_PRIVATE_KEY_ID'),
string(credentialsId: 'google_calendar_private_key', variable: 'GOOGLE_CALENDAR_TIPPLIGA_SERVICE_ACCOUNT_PRIVATE_KEY')
usernamePassword(credentialsId: 'forum_user', usernameVariable: 'FORUM_USERNAME', passwordVariable: 'FORUM_PASSWORD')
]) {
withEnv([
"JAVA_HOME=${jdkPath}/jdk-22.0.2"
"JAVA_HOME=${jdkPath}/jdk-19.0.2"
]) {
try {
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesResultsUpdater --season ${season} --league 1 --configFile Tippliga >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesUpdaterFootball --season ${season} --league 1 --configFile Tippliga >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchdaysUpdater --season ${season} --league 1 --configFile Tippliga >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode TeamsUpdater --season ${season} --league 1 --configFile Tippliga >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesResultsUpdater --season ${season} --league 2 --configFile Tippliga >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesUpdaterFootball --season ${season} --league 2 --configFile Tippliga >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchdaysUpdater --season ${season} --league 2 --configFile Tippliga >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode TeamsUpdater --season ${season} --league 2 --configFile Tippliga >> log.txt 2>&1"
sh "ls build/libs"
sh "java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesUpdaterFootball --season ${season} --league 1 --configFile Tippliga 2>&1 >> log.txt"
sh "java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchdaysUpdater --season ${season} --league 1 --configFile Tippliga 2>&1 >> log.txt"
sh "java -jar build/libs/tlw-database-tool-1.0.jar --mode TeamsUpdater --season ${season} --league 1 --configFile Tippliga 2>&1 >> log.txt"
sh "java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesResultsUpdater --season ${season} --league 1 --configFile Tippliga 2>&1 >> log.txt"
sh "java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesUpdaterFootball --season ${season} --league 2 --configFile Tippliga 2>&1 >> log.txt"
sh "java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchdaysUpdater --season ${season} --league 2 --configFile Tippliga 2>&1 >> log.txt"
sh "java -jar build/libs/tlw-database-tool-1.0.jar --mode TeamsUpdater --season ${season} --league 2 --configFile Tippliga 2>&1 >> log.txt"
sh "java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesResultsUpdater --season ${season} --league 2 --configFile Tippliga 2>&1 >> log.txt"
} catch (Exception e) {
telegramSendManual("TLW-Database-Tool crashed in TippligaUpdater!")
telegramSendManual("TLW-Database-Tool crashed!")
}
String outputString = readFile 'log.txt'
echo "Output: ${outputString}"
if(outputString != "") {
ArrayList<String> outputList = outputString.replace("\n\n", "\n").split('\n').toList()
outputList = clean(outputList)
+9 -11
View File
@@ -10,24 +10,22 @@ pipeline {
stage('Execute') {
steps {
script {
String jdkPath = tool name: 'OpenJDK22', type: 'jdk'
String jdkPath = tool name: 'OpenJDK19', type: 'jdk'
withCredentials([
usernamePassword(credentialsId: 'aws', usernameVariable: 'AWS_ACCESS_KEY_ID', passwordVariable: 'AWS_SECRET_ACCESS_KEY'),
usernamePassword(credentialsId: 'aws', usernameVariable: 'AWS_ACCESS_KEY_ID', passwordVariable: 'AWS_SECRET_KEY'),
usernamePassword(credentialsId: 'forum_database', usernameVariable: 'TLW_DATABASE_USERNAME', passwordVariable: 'TLW_DATABASE_PASSWORD'),
usernamePassword(credentialsId: 'forum_user', usernameVariable: 'FORUM_USERNAME', passwordVariable: 'FORUM_PASSWORD'),
string(credentialsId: 'google_calendar_private_key_id', variable: 'GOOGLE_CALENDAR_TIPPLIGA_SERVICE_ACCOUNT_PRIVATE_KEY_ID'),
string(credentialsId: 'google_calendar_private_key', variable: 'GOOGLE_CALENDAR_TIPPLIGA_SERVICE_ACCOUNT_PRIVATE_KEY')
usernamePassword(credentialsId: 'forum_user', usernameVariable: 'FORUM_USERNAME', passwordVariable: 'FORUM_PASSWORD')
]) {
withEnv([
"JAVA_HOME=${jdkPath}/jdk-22.0.2"
"JAVA_HOME=${jdkPath}/jdk-19.0.2"
]) {
try {
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesResultsUpdater --season ${season} --league 48 --configFile WTL-Pokal >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesUpdaterFootball --season ${season} --league 48 --configFile WTL-Pokal >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchdaysUpdater --season ${season} --league 48 --configFile WTL-Pokal >> log.txt 2>&1"
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode TeamsUpdater --season ${season} --league 48 --configFile WTL-Pokal >> log.txt 2>&1"
sh "java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesUpdaterFootball --season ${season} --league 48 --configFile WTL-Pokal 2>&1 >> log.txt"
sh "java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchdaysUpdater --season ${season} --league 48 --configFile WTL-Pokal 2>&1 >> log.txt"
sh "java -jar build/libs/tlw-database-tool-1.0.jar --mode TeamsUpdater --season ${season} --league 48 --configFile WTL-Pokal 2>&1 >> log.txt"
sh "java -jar build/libs/tlw-database-tool-1.0.jar --mode MatchesResultsUpdater --season ${season} --league 48 --configFile WTL-Pokal 2>&1 >> log.txt"
} catch (Exception e) {
telegramSendManual("TLW-Database-Tool crashed in WTLPokalUpdater!")
telegramSendManual("TLW-Database-Tool crashed!")
}
String outputString = readFile 'log.txt'
if(outputString != "") {
-83
View File
@@ -1,83 +0,0 @@
pipeline {
agent any
stages {
stage('Restore tlw-database-tool') {
steps {
copyArtifacts filter: '**/tlw-database-tool-1.0.jar', fingerprintArtifacts: true, projectName: 'build tlw-database-tool', selector: lastSuccessful(), target: '.'
}
}
stage('Execute') {
steps {
script {
String jdkPath = tool name: 'OpenJDK22', type: 'jdk'
withCredentials([
usernamePassword(credentialsId: 'aws', usernameVariable: 'AWS_ACCESS_KEY_ID', passwordVariable: 'AWS_SECRET_ACCESS_KEY'),
usernamePassword(credentialsId: 'forum_database', usernameVariable: 'TLW_DATABASE_USERNAME', passwordVariable: 'TLW_DATABASE_PASSWORD'),
usernamePassword(credentialsId: 'forum_user', usernameVariable: 'FORUM_USERNAME', passwordVariable: 'FORUM_PASSWORD'),
string(credentialsId: 'WhatsApp_Token', variable: 'TLW_WHATSAPP_API_KEY'),
string(credentialsId: 'OPENAI_TOKEN', variable: 'OPENAI_TOKEN')
]) {
withEnv([
"JAVA_HOME=${jdkPath}/jdk-22.0.2",
"TLW_WHATSAPP_HOST=https://tlw-whatsapp.codeam.io"
]) {
try {
sh "$JAVA_HOME/bin/java -jar build/libs/tlw-database-tool-1.0.jar --mode WhatsAppNotifier --season ${season} --league 1 --configFile Tippliga >> log.txt 2>&1"
} catch (Exception e) {
telegramSendManual("TLW-Database-Tool crashed in WhatsAppReminder!")
}
String outputString = readFile 'log.txt'
if(outputString != "") {
ArrayList<String> outputList = outputString.replace("\n\n", "\n").split('\n').toList()
outputList = clean(outputList)
outputList.each {
telegramSendManual(it)
}
}
}
}
}
}
}
}
post {
always {
deleteDir()
}
failure {
telegramSendManual("Build failed!\n${env.BUILD_URL}console")
}
}
}
private ArrayList<String> clean(ArrayList<String> orig) {
ArrayList<String> cleaned = new ArrayList<String>()
orig.each{line ->
if(line.indexOf(" [main] INFO de.jeyp91 - ") >= 0) {
line = line.substring(20, line.size())
}
if(line.indexOf(" [main] ERROR de.jeyp91") >= 0) {
line = line.substring(20, line.size())
}
cleaned.add(line)
}
return cleaned.unique()
}
def telegramSendManual(String text) {
sleep 1
if(text) {
def encodedMessage = URLEncoder.encode(text, "UTF-8")
println encodedMessage
httpRequest(
httpMode: 'GET',
contentType: 'APPLICATION_JSON',
responseHandle: 'NONE',
url: "https://api.telegram.org/bot1298223079:AAEplcQpfzFG59qNYAYuSbJKtB9HMXCCE_U/sendMessage?text=$encodedMessage&chat_id=459231986&disable_web_page_preview=true",
wrapAsMultipart: false,
consoleLogResponseBody: true
)
}
}
+3 -6
View File
@@ -10,14 +10,14 @@ pipeline {
stage('Build') {
steps {
script {
String jdkPath = tool name: 'OpenJDK22', type: 'jdk'
String jdkPath = tool name: 'OpenJDK19', type: 'jdk'
withCredentials([
usernamePassword(credentialsId: 'aws', usernameVariable: 'AWS_ACCESS_KEY_ID', passwordVariable: 'AWS_SECRET_ACCESS_KEY'),
usernamePassword(credentialsId: 'aws', usernameVariable: 'AWS_ACCESS_KEY_ID', passwordVariable: 'AWS_SECRET_KEY'),
usernamePassword(credentialsId: 'forum_database', usernameVariable: 'TLW_DATABASE_USERNAME', passwordVariable: 'TLW_DATABASE_PASSWORD'),
usernamePassword(credentialsId: 'forum_user', usernameVariable: 'FORUM_USERNAME', passwordVariable: 'FORUM_PASSWORD')
]) {
withEnv([
"JAVA_HOME=${jdkPath}/jdk-22.0.2"
"JAVA_HOME=${jdkPath}/jdk-19.0.2"
]) {
sh returnStdout: false, script: "./gradlew build -x test"
}
@@ -35,9 +35,6 @@ pipeline {
echo 'Trigger jobs'
build wait: false, job: 'TippligaUpdater'
build wait: false, job: 'WTLPokalUpdater'
build wait: false, job: 'SupercupUpdater'
build wait: false, job: 'RelegationUpdater'
build wait: false, job: 'LigaCupUpdater'
}
}
}
-2
View File
@@ -1,2 +0,0 @@
[tools]
java = "22.0.2"
+41 -43
View File
@@ -1,23 +1,22 @@
package de.jeyp91;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.jeyp91.apifootball.APIFootballUpdater;
import de.jeyp91.tippliga.TLWMatchdaysUpdater;
import de.jeyp91.tippliga.TLWMatchesCreatorFootball;
import de.jeyp91.tippliga.TLWMatchesResultsUpdater;
import de.jeyp91.tippliga.TLWMatchesUpdaterFootball;
import de.jeyp91.tippliga.TLWTeamsUpdater;
import de.jeyp91.googlecalendar.TippligaGoogleEventManager;
import de.jeyp91.tippligaforum.MatchesListForumUpdater;
import de.jeyp91.tippligaforum.SeasonForumPostsCreator;
import de.jeyp91.tippliga.*;
import de.jeyp91.tippligaforum.TippligaConfigProvider;
import de.jeyp91.tippligaforum.TippligaSQLConnector;
import de.jeyp91.whatsapp.WhatsAppNotifier;
import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.Namespace;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.Configurator;
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuilder;
import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
/**
* Hello world!
@@ -29,62 +28,61 @@ public class App {
private static int season;
private static int league;
private static String configFile;
private static final Logger logger = LoggerFactory.getLogger(App.class);
private static final Logger logger = LogManager.getLogger(App.class);
public static void main(String[] args) {
// SLF4J does not require explicit configuration here
// Configuration can be done via an external configuration file (e.g., logback.xml)
ConfigurationBuilder<BuiltConfiguration> builder
= ConfigurationBuilderFactory.newConfigurationBuilder();
RootLoggerComponentBuilder rootLogger
= builder.newRootLogger(Level.ERROR);
builder.add(rootLogger);
Configurator.initialize(builder.build());
Configurator.setRootLevel(Level.INFO);
initOptions(args);
String sql = "";
String beautifulInfo = "";
switch (mode) {
case "MatchdaysUpdater" -> {
switch(mode) {
case "MatchdaysUpdater":
TLWMatchdaysUpdater matchdaysUpdater = new TLWMatchdaysUpdater(season, league, configFile);
sql = matchdaysUpdater.getUpdateSql();
beautifulInfo = matchdaysUpdater.getBeautifulInfo();
matchdaysUpdater.updateGoogleCalendar();
}
case "MatchesCreatorFootball" -> {
break;
case "MatchesCreatorFootball":
TLWMatchesCreatorFootball creator = new TLWMatchesCreatorFootball(season, league, configFile);
sql = creator.getSQLInsertString();
}
case "MatchesUpdaterFootball" -> {
break;
case "MatchesUpdaterFootball":
TLWMatchesUpdaterFootball tlwMatchesUpdaterFootball = new TLWMatchesUpdaterFootball(season, league, configFile);
sql = tlwMatchesUpdaterFootball.getUpdateSQL();
beautifulInfo = tlwMatchesUpdaterFootball.getBeautifulInfo();
}
case "MatchesResultsUpdater" -> {
break;
case "MatchesResultsUpdater":
TLWMatchesResultsUpdater tlwMatchesResultsUpdater = new TLWMatchesResultsUpdater(season, league, configFile);
beautifulInfo = tlwMatchesResultsUpdater.getBeautifulInfo();
}
case "TeamsUpdater" -> {
break;
case "TeamsUpdater":
TLWTeamsUpdater teamsUpdater = new TLWTeamsUpdater(season, league, configFile);
sql = teamsUpdater.getInsertSQL();
}
case "APIFootballUpdater" -> {
break;
case "APIFootballUpdater":
APIFootballUpdater apiFootballUpdater = new APIFootballUpdater();
apiFootballUpdater.updateAllFixtures(season);
apiFootballUpdater.updateAllRounds(season);
}
case "MatchesListGistUpdater" -> {
MatchesListForumUpdater matchesListForumUpdater = new MatchesListForumUpdater();
break;
case "MatchesListGistUpdater":
MatchesListForumUpdater matchesListForumUpdater = new MatchesListForumUpdater(season);
matchesListForumUpdater.updateAllLeagues(season);
}
case "SeasonPreparation" -> {
SeasonForumPostsCreator creator = new SeasonForumPostsCreator(season);
creator.createAllPosts();
}
case "PostChecksum" -> {
break;
case "PostChecksum":
TippligaConfigProvider configProvider = new TippligaConfigProvider(season);
String checksum = configProvider.getChecksumOfConfigPost(configFile);
System.out.println(checksum);
}
case "WhatsAppNotifier" -> {
WhatsAppNotifier notifier = new WhatsAppNotifier();
notifier.sendNotifications();
}
default -> {
}
break;
default:
break;
}
if(!StatusHolder.getError() && !sql.equals("")) {
TippligaSQLConnector con = TippligaSQLConnector.getInstance();
@@ -101,7 +99,7 @@ public class App {
parser.addArgument("-m", "--mode")
.dest("mode")
.choices("MatchdaysUpdater", "MatchesCreatorFootball", "MatchesUpdaterFootball", "MatchesResultsUpdater", "TeamsUpdater", "APIFootballUpdater", "MatchesListGistUpdater", "PostChecksum", "WhatsAppNotifier", "SeasonPreparation")
.choices("MatchdaysUpdater", "MatchesCreatorFootball", "MatchesUpdaterFootball", "MatchesResultsUpdater", "TeamsUpdater", "APIFootballUpdater", "MatchesListGistUpdater", "PostChecksum")
.help("")
.required(true)
.type(String.class);
-18
View File
@@ -28,8 +28,6 @@ public abstract class BaseMatch {
protected Integer matchday = null;
protected String matchDatetime = null;
protected Integer status = null;
protected Integer koMatch = 0;
protected Integer showTable = 0;
protected COMPARISON updateStatus = COMPARISON.IDENTICAL;
public Integer getMatchday() {
@@ -88,22 +86,6 @@ public abstract class BaseMatch {
return this.status;
}
public Integer getShowTable() {
return this.showTable;
}
public void setShowTable(boolean showTable) {
this.showTable = showTable ? 0 : 1;
}
public Boolean getKoMatch() {
return this.koMatch == 1;
}
public void setKoMatch(Boolean koMatch) {
this.koMatch = koMatch ? 0 : 1;
}
public void setUpdateStatus(COMPARISON newStatus) { this.updateStatus = newStatus; }
public COMPARISON getUpdateStatus() {
@@ -27,8 +27,8 @@ public class ResourceProvider {
return array;
}
public static JSONArray getLigenConfig() {
return getJSONArrayFromResource("Tippliga/Ligen_v3.json");
public static JSONArray getLigenConfig(int season) {
return getJSONArrayFromResource("Tippliga/" + season + "_Ligen.json");
}
public static JSONArray getTeamIDMatcherConfig() {
+53 -68
View File
@@ -1,110 +1,95 @@
package de.jeyp91;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectInputStream;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.auth.credentials.EnvironmentVariableCredentialsProvider;
import software.amazon.awssdk.core.exception.SdkClientException;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.NoSuchKeyException;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.S3Exception;
public class S3Provider {
private static final Region AWS_DEFAULT_REGION = Region.EU_CENTRAL_1;
private static final Regions AWS_DEFAULT_REGION = Regions.EU_CENTRAL_1;
private static final String BUCKET_NAME = "tlw-database-tool-api-football-data";
private final S3Client s3;
private static final Logger logger = LoggerFactory.getLogger(S3Provider.class);
public S3Provider() {
s3 = S3Client.builder()
.region(AWS_DEFAULT_REGION)
.credentialsProvider(EnvironmentVariableCredentialsProvider.create())
.build();
}
private void writeToS3(String filename, String content) {
final AmazonS3 s3 = AmazonS3ClientBuilder
.standard()
.withRegion(AWS_DEFAULT_REGION)
.build();
try {
this.s3.putObject(
PutObjectRequest.builder()
.bucket(BUCKET_NAME)
.key(filename)
.build(),
RequestBody.fromString(content)
);
} catch (S3Exception e) {
System.err.println(e.awsErrorDetails().errorMessage());
s3.putObject(BUCKET_NAME, filename, content);
} catch (AmazonServiceException e) {
System.err.println(e.getErrorMessage());
}
}
public void writeFixturesToS3(int season, int league, String content) {
writeToS3(v3Filepath("fixtures", season, league), content);
public void writeFixturesToS3(int league, String content) {
writeToS3("fixtures/" + league + ".json", content);
}
public void writeRoundsToS3(int season, int league, String content) {
writeToS3(v3Filepath("rounds", season, league), content);
public void writeRoundsToS3(int league, String content) {
writeToS3("rounds/" + league + ".json", content);
}
private String getFileFromS3(String filename) {
final AmazonS3 s3 = AmazonS3ClientBuilder
.standard()
.withRegion(AWS_DEFAULT_REGION)
.build();
StringBuilder builder = new StringBuilder();
try {
GetObjectRequest getObjectRequest = GetObjectRequest.builder()
.bucket(BUCKET_NAME)
.key(filename)
.build();
BufferedReader reader = new BufferedReader(new InputStreamReader(
this.s3.getObject(getObjectRequest), StandardCharsets.UTF_8));
S3Object o = s3.getObject(BUCKET_NAME, filename);
S3ObjectInputStream s3is = o.getObjectContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(s3is));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
} catch (SdkClientException | IOException e) {
e.printStackTrace();
} catch (NoSuchKeyException e) {
logger.error(filename + " not found in S3.");
} catch (Exception e) {
e.printStackTrace();
throw e;
}
return builder.toString();
}
public JSONObject getFixturesJSONFromS3(int season, int league) {
return stringToJSONObject(getFileFromS3(v3Filepath("fixtures", season, league)));
String getFixturesStringFromS3(int league) {
return getFileFromS3("fixtures/" + league + ".json");
}
public JSONObject getRoundsJSONFromS3(int season, int league) {
return stringToJSONObject(getFileFromS3(v3Filepath("rounds", season, league)));
}
private JSONObject stringToJSONObject(String rawData) {
if(rawData.isEmpty()) {
return null;
}
public JSONObject getFixturesJSONFromS3(int league) {
String fixturesString = getFixturesStringFromS3(league);
JSONParser parser = new JSONParser();
JSONObject data = null;
JSONObject jsonObject = null;
try {
data = (JSONObject) parser.parse(rawData);
jsonObject = (JSONObject) parser.parse(fixturesString);
} catch (ParseException e) {
/* TODO */
e.printStackTrace();
}
return data;
return jsonObject;
}
private String v3Filepath (String prefix, int season, int league) {
return "v3/" + prefix + "_" + season + "_" + league + ".json";
}
private String getRoundsStringFromS3(int league) {
return getFileFromS3("rounds/" + league + ".json");
}
public JSONObject getRoundsJSONFromS3(int league) {
String fixturesString = getRoundsStringFromS3(league);
JSONParser parser = new JSONParser();
JSONObject jsonObject = null;
try {
jsonObject = (JSONObject) parser.parse(fixturesString);
} catch (ParseException e) {
/* TODO */
e.printStackTrace();
}
return jsonObject;
}
}
@@ -1,15 +1,14 @@
package de.jeyp91.apifootball;
import java.util.ArrayList;
import java.util.HashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.jeyp91.S3Provider;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import de.jeyp91.S3Provider;
import java.util.ArrayList;
import java.util.HashMap;
public class APIFootballConnector {
@@ -17,7 +16,7 @@ public class APIFootballConnector {
private final int season;
private final HashMap<Integer, JSONObject> rounds = new HashMap<>();
private final HashMap<Integer, JSONObject> matches = new HashMap<>();
private static final Logger logger = LoggerFactory.getLogger(APIFootballConnector.class);
private static final Logger logger = LogManager.getLogger(APIFootballConnector.class);
private APIFootballConnector(int season) {
this.season = season;
@@ -34,7 +33,7 @@ public class APIFootballConnector {
APIFootballMatch matchWithID = null;
ArrayList<APIFootballMatch> allMatches = getMatchesFromLeagueFromFile(this.season, league);
ArrayList<APIFootballMatch> allMatches = getMatchesFromLeagueFromFile(league);
for (APIFootballMatch singleMatch : allMatches) {
if (singleMatch.getAPIFootBallMatchID() == id) {
matchWithID = singleMatch;
@@ -49,7 +48,7 @@ public class APIFootballConnector {
ArrayList<APIFootballMatch> matchesOfMatchday = new ArrayList<>();
ArrayList<APIFootballMatch> allMatches = getMatchesFromLeagueFromFile(this.season, league);
ArrayList<APIFootballMatch> allMatches = getMatchesFromLeagueFromFile(league);
for (APIFootballMatch singleMatch : allMatches) {
if (singleMatch.getMatchday() == matchday) {
matchesOfMatchday.add(singleMatch);
@@ -59,15 +58,15 @@ public class APIFootballConnector {
return matchesOfMatchday;
}
public ArrayList<APIFootballMatch> getMatchesFromLeagueFromFile(int season, int leagueId) {
public ArrayList<APIFootballMatch> getMatchesFromLeagueFromFile(int leagueId) {
ArrayList<APIFootballMatch> matchesList = new ArrayList<>();
S3Provider prov = new S3Provider();
if(!this.matches.containsKey(leagueId)) {
this.matches.put(leagueId, prov.getFixturesJSONFromS3(season, leagueId));
this.matches.put(leagueId, prov.getFixturesJSONFromS3(leagueId));
}
JSONObject matchesObject = this.matches.get(leagueId);
JSONArray matchArray = (JSONArray) (matchesObject.get("response"));
JSONObject matches = this.matches.get(leagueId);
JSONArray matchArray = (JSONArray) (((JSONObject)matches.get("api")).get("fixtures"));
for(int i = 0; i < matchArray.size(); i++) {
try {
@@ -84,18 +83,19 @@ public class APIFootballConnector {
public JSONObject getMatchdays(int leagueId) {
S3Provider prov = new S3Provider();
if(!this.rounds.containsKey(leagueId)) {
this.rounds.put(leagueId, prov.getRoundsJSONFromS3(this.season, leagueId));
this.rounds.put(leagueId, prov.getRoundsJSONFromS3(leagueId));
}
return this.rounds.get(leagueId);
}
public JSONObject getTeamsForLeague(int season, int league) throws Exception {
String requestPath = "teams";
String content = new APIFootballUpdater().getRawData(requestPath, season, league);
public JSONObject getTeamsForLeague(int league) throws Exception {
String url = "https://v2.api-football.com/teams/league/" + league;
String content = new APIFootballUpdater().getRawData(url);
return stringToJSONObject(content);
}
public static JSONObject stringToJSONObject(String rawData) {
JSONParser parser = new JSONParser();
JSONObject data = null;
try {
@@ -1,31 +1,36 @@
package de.jeyp91.apifootball;
import de.jeyp91.BaseMatch;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import de.jeyp91.BaseMatch;
public class APIFootballMatch extends BaseMatch {
private int matchId;
private int leagueId;
private String teamNameHome;
private String teamNameGuest;
private String round;
private Boolean showTable = null;
public APIFootballMatch(JSONObject json, int season) throws Exception {
this.matchId = Integer.parseInt(((JSONObject) json.get("fixture")).get("id").toString());
this.leagueId = Integer.parseInt(((JSONObject) json.get("league")).get("id").toString());
this.teamIdHome = Integer.valueOf(((JSONObject) ((JSONObject) json.get("teams")).get("home")).get("id").toString());
this.teamIdGuest = Integer.valueOf(((JSONObject) ((JSONObject) json.get("teams")).get("away")).get("id").toString());
this.teamNameHome = ((JSONObject) ((JSONObject) json.get("teams")).get("home")).get("name").toString();
this.teamNameGuest = ((JSONObject) ((JSONObject) json.get("teams")).get("away")).get("name").toString();
this.round = ((JSONObject) json.get("league")).get("round").toString();
this.matchId = Integer.parseInt(json.get("fixture_id").toString());
// TODO
this.leagueId = Integer.parseInt(json.get("league_id").toString());
this.teamIdHome = Integer.parseInt(((JSONObject) json.get("homeTeam")).get("team_id").toString());
this.teamIdGuest = Integer.parseInt(((JSONObject) json.get("awayTeam")).get("team_id").toString());
this.teamNameHome = ((JSONObject) json.get("homeTeam")).get("team_name").toString();
this.teamNameGuest = ((JSONObject) json.get("awayTeam")).get("team_name").toString();
this.goalsHome = getNumberOrNull(json.get("goalsHomeTeam"));
this.goalsGuest = getNumberOrNull(json.get("goalsAwayTeam"));
this.round = json.get("round").toString();
try {
this.matchday = getMatchdayFromRoundString(season, this.round, this.leagueId);
} catch (Exception e) {
throw new Exception("Did not find matchday for league '" + this.leagueId + "': '" + json.get("round").toString() + "'");
}
this.matchDatetime = (String) ((JSONObject) json.get("fixture")).get("date");
this.status = parseStatus(((JSONObject) ((JSONObject) json.get("fixture")).get("status")).get("short").toString());
this.matchDatetime = (String) json.get("event_date");
this.status = parseStatus(json.get("statusShort").toString());
this.parseResult(json);
}
@@ -35,15 +40,15 @@ public class APIFootballMatch extends BaseMatch {
public static int getMatchdayFromRoundString(int season, String round, int leagueId) {
round = round.replace(" ", "_");
Integer matchday = -1;
Integer matchday = null;
if (round.startsWith("Regular_Season_-_")) {
matchday = Integer.valueOf(round.replace("Regular_Season_-_", ""));
matchday = Integer.parseInt(round.replace("Regular_Season_-_", ""));
} else {
APIFootballConnector con = APIFootballConnector.getAPIFootballConnectorInstance(season);
JSONObject roundsObject = con.getMatchdays(leagueId);
JSONArray roundsArray = (JSONArray)(roundsObject.get("response"));
JSONArray roundsArray = (JSONArray)(((JSONObject) roundsObject.get("api")).get("fixtures"));
for (int i = 0; i < roundsArray.size(); i++) {
if(roundsArray.get(i).toString().replace("_", " ").equals(round.replace("_", " "))) {
if(roundsArray.get(i).toString().equals(round)) {
matchday = i + 1;
break;
}
@@ -53,32 +58,60 @@ public class APIFootballMatch extends BaseMatch {
}
private Integer getNumberOrNull(Object object) {
return object != null ? Integer.valueOf(object.toString()) : null;
return object != null ? Integer.parseInt(object.toString()) : null;
}
public String getTeamNameHome() {
return this.teamNameHome;
}
public String getTeamNameGuest() {
return this.teamNameGuest;
}
public String getRound() {
return this.round;
}
public void setShowTable(boolean showTable) {
this.showTable = showTable;
}
public Boolean getShowTable() {
return this.showTable;
}
private int parseStatus(String statusShort) {
return switch (statusShort) {
case "TBD", "NS" -> 0;
case "FT", "AET", "PEN" -> 3;
default -> 1;
};
switch (statusShort) {
case "TBD":
case "NS": return 0;
case "FT":
case "AET":
case "PEN": return 3;
default: return 1;
}
}
private void parseResult(JSONObject json) {
Object resultFulltime = ((JSONObject) json.get("score")).get("fulltime");
this.goalsHome = getNumberOrNull(((JSONObject) resultFulltime).get("home"));
this.goalsGuest = getNumberOrNull(((JSONObject) resultFulltime).get("away"));
if(resultFulltime != null) {
String[] result = resultFulltime.toString().split("-");
this.goalsHome = Integer.parseInt(result[0]);
this.goalsGuest = Integer.parseInt(result[1]);
}
Object resultExtratime = ((JSONObject) json.get("score")).get("extratime");
this.goalsOvertimeHome = getNumberOrNull(((JSONObject) resultExtratime).get("home"));
this.goalsOvertimeGuest = getNumberOrNull(((JSONObject) resultExtratime).get("away"));
if(resultExtratime != null) {
String[] result = resultExtratime.toString().split("-");
this.goalsOvertimeHome = this.goalsHome + Integer.parseInt(result[0]);
this.goalsOvertimeGuest = this.goalsGuest + Integer.parseInt(result[1]);
}
Object resultPenalty = ((JSONObject) json.get("score")).get("penalty");
this.goalsPenaltyHome = getNumberOrNull(((JSONObject) resultPenalty).get("home"));
this.goalsPenaltyGuest = getNumberOrNull(((JSONObject) resultPenalty).get("away"));
if(resultPenalty != null) {
String[] result = resultPenalty.toString().split("-");
this.goalsPenaltyHome = this.goalsOvertimeHome + Integer.parseInt(result[0]);
this.goalsPenaltyGuest = this.goalsOvertimeGuest + Integer.parseInt(result[1]);
}
}
}
@@ -9,18 +9,12 @@ public class APIFootballMatchesProvider {
APIFootballConnector conn;
public APIFootballMatchesProvider(int season) {
this.conn = APIFootballConnector.getAPIFootballConnectorInstance(season);
this.conn = APIFootballConnector.getAPIFootballConnectorInstance(season - 1);
}
public ArrayList<APIFootballMatch> getAPIFootballMatchesFromConfig(JSONObject matchdayConfig) {
boolean ko = false;
try {
ko = (boolean) matchdayConfig.get("ko");
} catch (Exception e) {
// Nothing to do here
}
public ArrayList<APIFootballMatch> getAPIFootballMatchesFromConfig(JSONArray config) {
ArrayList<APIFootballMatch> apiFootballMatches = new ArrayList<>();
for (Object singleConfigObject : (JSONArray) matchdayConfig.get("matchesConfig")) {
for (Object singleConfigObject : config) {
JSONObject singleConfig = (JSONObject) singleConfigObject;
String type = (String) singleConfig.get("type");
boolean showTable = false;
@@ -35,11 +29,7 @@ public class APIFootballMatchesProvider {
e.printStackTrace();
}
boolean finalShowTable = showTable;
boolean finalKo = ko;
matches.forEach(apiFootballMatch -> {
apiFootballMatch.setShowTable(finalShowTable);
apiFootballMatch.setKoMatch(finalKo);
});
matches.forEach(apiFootballMatch -> apiFootballMatch.setShowTable(finalShowTable));
apiFootballMatches.addAll(matches);
break;
case "SingleMatch":
@@ -48,7 +38,6 @@ public class APIFootballMatchesProvider {
APIFootballMatch match = conn.getMatchDataByLeagueAndMatchID(matchLeague, matchId);
showTable = (boolean) singleConfig.get("showTable");
match.setShowTable(showTable);
match.setKoMatch(ko);
apiFootballMatches.add(match);
break;
}
@@ -1,43 +1,40 @@
package de.jeyp91.apifootball;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashSet;
import de.jeyp91.ResourceProvider;
import de.jeyp91.S3Provider;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.jeyp91.ResourceProvider;
import de.jeyp91.S3Provider;
import java.io.*;
import java.util.HashSet;
public class APIFootballUpdater {
private static final Logger logger = LoggerFactory.getLogger(APIFootballUpdater.class);
private static final String BASE_URL = "https://v3.football.api-sports.io/";
private static final Logger logger = LogManager.getLogger(APIFootballUpdater.class);
public APIFootballUpdater() {
}
public void updateFixtures(int season, int league) {
String requestPath = "fixtures";
public void updateFixtures(int league) {
String apiFootballUrl = "https://v2.api-football.com/fixtures/league/" + league + "?timezone=Europe/Berlin";
S3Provider prov = new S3Provider();
try {
String content = getRawData(requestPath, season, league);
prov.writeFixturesToS3(season, league, content);
String content = getRawData(apiFootballUrl);
prov.writeFixturesToS3(league, content);
} catch (Exception e) {
if(e.getMessage().toLowerCase().contains("rate limit'")) {
try {
Thread.sleep(1000 * 60);
String content = getRawData(requestPath, season, league);
prov.writeFixturesToS3(season, league, content);
String content = getRawData(apiFootballUrl);
prov.writeFixturesToS3(league, content);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
} catch (Exception exception) {
@@ -50,9 +47,9 @@ public class APIFootballUpdater {
}
public void updateAllFixtures(int season) {
HashSet<Integer> leagues = getLeagues();
HashSet<Integer> leagues = getLeagues(season);
for (Integer league : leagues) {
updateFixtures(season, league);
updateFixtures(league);
try {
Thread.sleep(1000*6);
} catch (InterruptedException e) {
@@ -62,9 +59,9 @@ public class APIFootballUpdater {
}
public void updateAllRounds(int season) {
HashSet<Integer> leagues = getLeagues();
HashSet<Integer> leagues = getLeagues(season);
for (Integer league : leagues) {
updateRounds(season, league);
updateRounds(league);
try {
Thread.sleep(1000*6);
} catch (InterruptedException e) {
@@ -73,18 +70,18 @@ public class APIFootballUpdater {
}
}
public void updateRounds(int season, int league) {
String requestPath = "fixtures/rounds";
public void updateRounds(int league) {
String apiFootballUrl = "https://v2.api-football.com/fixtures/rounds/" + league;
S3Provider prov = new S3Provider();
try {
String content = getRawData(requestPath, season, league);
prov.writeRoundsToS3(season, league, content);
String content = getRawData(apiFootballUrl);
prov.writeRoundsToS3(league, content);
} catch (Exception e) {
if(e.getMessage().toLowerCase().contains("rate limit'")) {
try {
Thread.sleep(1000 * 60);
String content = getRawData(requestPath, season, league);
prov.writeRoundsToS3(season, league, content);
String content = getRawData(apiFootballUrl);
prov.writeRoundsToS3(league, content);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
} catch (Exception exception) {
@@ -96,37 +93,54 @@ public class APIFootballUpdater {
}
}
public String getRawData(String requestPath, int season, int league) throws Exception {
if(league != 1 && league != 4) {
/**
* Season usually is one higher in Tippliga than in API-Football.
* e.g. 2023/24 is 2024 in Tippliga and 2023 in API-Football.
* Because Liga Cup in Tippliga is at the end of a season, season does match World Cup (1) and Euro Championship (4)
*/
season--;
}
public String getRawData(String requestUrl) throws Exception {
HttpClient client = HttpClientBuilder.create().build();
String requestUrl = BASE_URL + requestPath + "?season=" + (season) + "&league=" + league + "&timezone=Europe/Berlin";
HttpGet request = new HttpGet(requestUrl);
// add request header
request.addHeader("x-rapidapi-host", "v3.football.api-sports.io");
request.addHeader("x-rapidapi-key", "a607e6a7437d9d52f3ac73e0b2704d0b");
request.addHeader("X-RapidAPI-Key", "a607e6a7437d9d52f3ac73e0b2704d0b");
HttpResponse response = null;
try {
response = client.execute(request);
} catch (IOException e) {
/* TODO */
e.printStackTrace();
}
BufferedReader rd = null;
try {
assert response != null;
rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent())
);
} catch (IOException e) {
/* TODO */
e.printStackTrace();
}
HttpResponse response = client.execute(request);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuilder result = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
String line = "";
while (true) {
try {
line = rd.readLine();
} catch (Exception e) {
/* TODO */
e.printStackTrace();
}
// Stop reading if last line was found.
if (line == null) break;
result.append(line);
}
checkErrors(requestUrl, result.toString());
return result.toString();
}
public HashSet<Integer> getLeagues() {
JSONArray leaguesArray = ResourceProvider.getLigenConfig();
public HashSet<Integer> getLeagues(int season) {
JSONArray leaguesArray = ResourceProvider.getLigenConfig(season);
HashSet<Integer> leagues = new HashSet<>();
for (Object leagueObject : leaguesArray) {
JSONObject leagueJSONObject = (JSONObject) leagueObject;
@@ -138,15 +152,15 @@ public class APIFootballUpdater {
public void checkErrors(String requestUrl, String result) throws Exception {
JSONObject resultObject = stringToJSONObject(result);
boolean containsError = !((JSONArray) resultObject.get("errors")).isEmpty();
// int results = Integer.parseInt(resultObject.get("results").toString());
boolean containsError = ((JSONObject) resultObject.get("api")).containsKey("error");
int results = Integer.parseInt(((JSONObject) resultObject.get("api")).get("results").toString());
if(containsError) {
String errorMessage = resultObject.get("errors").toString();
String errorMessage = ((JSONObject) resultObject.get("api")).get("error").toString();
throw new Exception(requestUrl + " returned error: '" + errorMessage + "'");
} else if (results == 0) {
String statusMessage = ((JSONObject) resultObject.get("api")).get("status").toString();
throw new Exception(requestUrl + " did not have any results with status: '" + statusMessage + "'");
}
// else if (results == 0) {
// throw new Exception(requestUrl + " did not have any results.");
// }
}
private JSONObject stringToJSONObject(String rawData) {
@@ -1,14 +1,45 @@
package de.jeyp91.googlecalendar;
import com.google.common.io.Resources;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
public class CalendarConfigProvider {
private static String GOOGLE_CALENDAR_ID = "825f79shtm9n3uknj99iuu2qho";
private static JSONObject googleCalendarConfig = null;
private static JSONObject getGoogleCalendarConfig() {
if(googleCalendarConfig == null) {
//JSON parser object to parse read file
JSONParser jsonParser = new JSONParser();
URL url = Resources.getResource("Google_Calendar_Config.json");
String jsonConfig = null;
try {
jsonConfig = Resources.toString(url, StandardCharsets.UTF_8);
//Read JSON file
googleCalendarConfig = (JSONObject) jsonParser.parse(jsonConfig);
} catch (IOException | ParseException e) {
e.printStackTrace();
}
}
return googleCalendarConfig;
}
public static String getCalendarUrl() {
return GOOGLE_CALENDAR_ID + "@group.calendar.google.com";
JSONObject leagueConfig = (JSONObject) getGoogleCalendarConfig().get(String.valueOf(1));
return (String) leagueConfig.get("url");
}
public static String getCalendarId() {
return GOOGLE_CALENDAR_ID;
JSONObject leagueConfig = (JSONObject) getGoogleCalendarConfig().get(String.valueOf(1));
return (String) leagueConfig.get("id");
}
}
@@ -8,69 +8,34 @@ import com.google.api.services.calendar.Calendar;
import com.google.api.services.calendar.CalendarScopes;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.auth.oauth2.ServiceAccountCredentials;
import java.io.IOException;
import java.net.URI;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.io.*;
import java.util.Collections;
import java.util.List;
public class GoogleCalendarConnector {
private static final String APPLICATION_NAME = "Google Calendar API Java Quickstart";
private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
private static final String PROJECT_ID = "tippliga";
private static final String CLIENT_MAIL = "tlw-707@tippliga.iam.gserviceaccount.com";
private static final String CLIENT_ID = "101590566618120833710";
private static final String TOKEN_URI = "https://oauth2.googleapis.com/token";
/**
* Global instance of the scopes required by this quickstart.
* If modifying these scopes, delete your previously saved tokens/ folder.
*/
private static final String SERVICE_CREDENTIALS_FILE_PATH = "/tippliga-4e0def9ef447.json";
/**
* Creates an authorized Credential object.
* @return An authorized Credential object.
* @throws IOException If the Google_Credentials.json file cannot be found.
*/
private static GoogleCredentials getGoogleCredentials() throws IOException {
String privateKeyId = getEnv("GOOGLE_CALENDAR_TIPPLIGA_SERVICE_ACCOUNT_PRIVATE_KEY_ID");
String privateKeyPem = getEnv("GOOGLE_CALENDAR_TIPPLIGA_SERVICE_ACCOUNT_PRIVATE_KEY");
GoogleCredentials credentials = ServiceAccountCredentials.newBuilder()
.setClientEmail(CLIENT_MAIL)
.setClientId(CLIENT_ID)
.setPrivateKey(parsePrivateKey(privateKeyPem))
.setPrivateKeyId(privateKeyId)
.setProjectId(PROJECT_ID)
.setTokenServerUri(URI.create(TOKEN_URI))
.build()
InputStream in = GoogleCalendarConnector.class.getResourceAsStream(SERVICE_CREDENTIALS_FILE_PATH);
GoogleCredentials credentials = GoogleCredentials.fromStream(in)
.createScoped(Collections.singleton(CalendarScopes.CALENDAR));
credentials.refreshIfExpired();
return credentials;
}
private static PrivateKey parsePrivateKey(String pemData) throws IOException {
String normalized = pemData.replace("\\n", "\n");
String stripped = normalized
.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replaceAll("\\s", "");
byte[] encoded = Base64.getDecoder().decode(stripped);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
try {
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(keySpec);
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
throw new IOException("Failed to parse private key", e);
}
}
private static String getEnv(String name) throws IOException {
String value = System.getenv(name);
if (value == null || value.isEmpty()) {
throw new IOException("Environment variable " + name + " is not set");
}
return value;
}
public static com.google.api.services.calendar.Calendar getSerivce() {
Calendar service = null;
@@ -4,18 +4,19 @@ import com.google.api.client.util.DateTime;
import com.google.api.services.calendar.Calendar;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.EventDateTime;
import com.google.api.services.calendar.model.EventReminder;
import com.google.api.services.calendar.model.Events;
import de.jeyp91.tippliga.TLWLeague;
import de.jeyp91.tippliga.TLWMatchday;
import de.jeyp91.tippligaforum.TippligaSQLConnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Arrays;
import java.util.List;
import static de.jeyp91.googlecalendar.GoogleCalendarConnector.getSerivce;
@@ -23,9 +24,7 @@ import static de.jeyp91.googlecalendar.GoogleCalendarConnector.getSerivce;
public class TippligaGoogleEventManager {
private static List<Event> allEvents = null;
private static final Logger logger = LoggerFactory.getLogger(TippligaGoogleEventManager.class);
private static final HashMap<String, String> allLeagueNames = new HashMap<>();
private static final Logger logger = LogManager.getLogger(TippligaGoogleEventManager.class);
public static List<Event> getAllEvents(Integer season) {
if(allEvents == null) {
@@ -61,9 +60,6 @@ public class TippligaGoogleEventManager {
public static Event findEvent(List<Event> allEvents, Integer season, Integer league, Integer matchday, Integer deliveryDateNumber) {
String description = getDescription(season, league, matchday, deliveryDateNumber);
String descriptionHtml = getDescriptionHTML(season, league, matchday, deliveryDateNumber);
if(matchday == 34) {
String debug = "";
}
for (Event event : allEvents) {
String eventDescription = event.getDescription();
if (
@@ -90,10 +86,8 @@ public class TippligaGoogleEventManager {
}
else {
String googleEventStart = event.getStart().getDateTime().toString();
String googleEventEnd = event.getEnd().getDateTime().toString();
String googleEventStartBeautified = googleEventStart.substring(0, 19).replace("T", " ");
if(!googleEventStartBeautified.equals(deliveryDateString)
|| !googleEventEnd.equals(googleEventStart)) {
if(!googleEventStartBeautified.equals(deliveryDateString)) {
updateEvent(event, matchday, deliveryDateString, deliverDateNumber);
}
}
@@ -150,7 +144,7 @@ public class TippligaGoogleEventManager {
private static Event getEvent(TLWMatchday matchday, String deliveryDateString, Integer deliverDateNumber) {
String matchdayName = matchday.getMatchdayName().equals("") ? matchday.getMatchday().toString() + ". Spieltag" : matchday.getMatchdayName();
String summary = getLeagueNameCalendar(matchday.getSeason(), matchday.getLeague()) + " " + matchdayName + " tippen!";
String summary = TLWLeague.getLeagueNameCalendar(matchday.getLeague()) + " " + matchdayName + " tippen!";
if(deliverDateNumber > 1) summary += " " + deliverDateNumber + ". Chance \uD83D\uDE43";
String description = getDescription(matchday.getSeason(), matchday.getLeague(), matchday.getMatchday(), deliverDateNumber);
String location = "https://tippliga-wuerzburg.de/app.php/football/bet";
@@ -162,7 +156,7 @@ public class TippligaGoogleEventManager {
.setDateTime(deliveryDateTime)
.setTimeZone("Europe/Berlin");
// Set reminder to 12 remainingHours before
// Set reminder to 12 hours before
Event.Reminders reminders = new Event.Reminders();
reminders.setUseDefault(true);
@@ -201,13 +195,4 @@ public class TippligaGoogleEventManager {
}
});
}
private static String getLeagueNameCalendar(Integer season, Integer league) {
String seasonLeagueId = season.toString() + league.toString();
if(!allLeagueNames.containsKey(seasonLeagueId)) {
allLeagueNames.put(seasonLeagueId, TippligaSQLConnector.getInstance().getLeague(season.toString(), league.toString()).getLeagueNameCalendar());
}
return allLeagueNames.get(seasonLeagueId);
}
}
@@ -0,0 +1,142 @@
package de.jeyp91.openligadb;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
/**
*
*/
public class OpenLigaDBConnector {
private final String OPENLIGADB_API_URL = "http://www.openligadb.de/api/";
public OpenLigaDBConnector() {}
public OpenLigaDBMatch getMatchDataOfSingleMatch(int id) {
String url = OPENLIGADB_API_URL + "getmatchdata/" + id;
JSONObject matchAsJson = getDataAsJSONObject(url);
return new OpenLigaDBMatch(matchAsJson);
}
public ArrayList<OpenLigaDBMatch> getMatchDataOfMatchday(int season, String league, int matchday) {
String url = OPENLIGADB_API_URL + "getmatchdata/" + league + "/" + (season - 1) + "/" + matchday;
JSONArray matches = getDataAsJSONArray(url);
ArrayList<OpenLigaDBMatch> matchesList = new ArrayList<>();
for(Object match: matches) {
matchesList.add(new OpenLigaDBMatch((JSONObject) match));
}
return matchesList;
}
public ArrayList<OpenLigaDBMatch> getMatchDataOfCurrentMatchday(String league) {
String url = OPENLIGADB_API_URL + "getmatchdata/" + league;
JSONArray matches = getDataAsJSONArray(url);
ArrayList<OpenLigaDBMatch> matchesList = new ArrayList<>();
for(Object match: matches) {
matchesList.add(new OpenLigaDBMatch((JSONObject) match));
}
return matchesList;
}
public OpenLigaDBMatch getMatchDataByMatchId(int id) {
String url = OPENLIGADB_API_URL + "getmatchdata/" + id;
JSONObject match = getDataAsJSONObject(url);
return new OpenLigaDBMatch(match);
}
private JSONArray getDataAsJSONArray(String requestUrl) {
String rawData = getRawData(requestUrl);
JSONParser parser = new JSONParser();
JSONArray data = null;
try {
data = (JSONArray) parser.parse(rawData);
} catch (ParseException e) {
/* TODO */
e.printStackTrace();
}
return data;
}
private JSONObject getDataAsJSONObject(String requestUrl) {
String rawData = getRawData(requestUrl);
JSONParser parser = new JSONParser();
JSONObject data = null;
try {
data = (JSONObject) parser.parse(rawData);
} catch (ParseException e) {
/* TODO */
e.printStackTrace();
}
return data;
}
private String getRawData(String requestUrl) {
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(requestUrl);
// add request header
request.addHeader("Content-Type", "application/json");
HttpResponse response = null;
try {
response = client.execute(request);
} catch (ClientProtocolException e) {
/* TODO */
e.printStackTrace();
} catch (IOException e) {
/* TODO */
e.printStackTrace();
}
BufferedReader rd = null;
try {
rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent())
);
} catch (IOException e) {
/* TODO */
e.printStackTrace();
}
StringBuilder result = new StringBuilder();
String line = "";
while (true) {
try {
line = rd.readLine();
} catch (IOException e) {
/* TODO */
e.printStackTrace();
}
// Stop reading if last line was found.
if (line == null) break;
result.append(line);
}
return result.toString();
}
}
@@ -0,0 +1,88 @@
package de.jeyp91.openligadb;
import de.jeyp91.BaseMatch;
import de.jeyp91.tippliga.TLWMatch;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import java.util.regex.*;
/**
*
*/
public class OpenLigaDBMatch extends BaseMatch {
private final int RESULT_TYPE_ENDRESULT = 2;
private Integer season = null;
private int matchId;
private int leagueId;
private boolean matchIsFinished;
public OpenLigaDBMatch(JSONObject json) {
this.matchId = Integer.parseInt(json.get("MatchID").toString());
this.season = getSeasonFromLeageName(json.get("LeagueName").toString());
this.leagueId = Integer.parseInt(json.get("LeagueId").toString());
this.teamIdHome = Integer.parseInt(((JSONObject) json.get("Team1")).get("TeamId").toString());
this.teamIdGuest = Integer.parseInt(((JSONObject) json.get("Team2")).get("TeamId").toString());
for(int i = 0; i < ((JSONArray) json.get("MatchResults")).size(); i++) {
if(Integer.parseInt((((JSONObject) ((JSONArray) json.get("MatchResults")).get(i)).get("ResultTypeID")).toString()) == RESULT_TYPE_ENDRESULT) {
this.goalsHome = Integer.parseInt(((JSONObject) ((JSONArray) json.get("MatchResults")).get(i)).get("PointsTeam1").toString());
this.goalsGuest = Integer.parseInt(((JSONObject) ((JSONArray) json.get("MatchResults")).get(i)).get("PointsTeam2").toString());
}
}
this.matchday = Integer.parseInt(((JSONObject) json.get("Group")).get("GroupOrderID").toString());
this.matchIsFinished = (Boolean) json.get("MatchIsFinished");
this.matchDatetime = (String) json.get("MatchDateTime");
}
private int getSeasonFromLeageName(String leagueName) {
Pattern p = Pattern.compile("\\d*/\\d*");
Matcher m = p.matcher(leagueName);
m.find();
String seasonString = m.group();
p = Pattern.compile("\\d+");
m = p.matcher(seasonString);
Integer season = null;
while(m.find()) {
season = Integer.parseInt(m.group());
}
return season < 100 ? season + 2000 : season;
}
public boolean isSameMatch(TLWMatch compareMatch) {
if(this.getSeason()!= compareMatch.getSeason()) {
return false;
}
if(this.getMatchday() != compareMatch.getMatchday()) {
return false;
}
if(this.getTeamIdHome() != compareMatch.getTeamIdHome()) {
return false;
}
if(this.getTeamIdGuest() != compareMatch.getTeamIdGuest()) {
return false;
}
String thisDateTime = this.getMatchDateTime().replace("T", " ");
String tempDateTime = compareMatch.getMatchDateTime().replace("T", " ");
if(!tempDateTime.equals(thisDateTime)) {
return false;
}
if(this.goalsHome != compareMatch.getGoalsHome() ||
this.goalsGuest != compareMatch.getGoalsGuest()) {
return false;
}
return true;
}
public Integer getSeason() {
return this.season;
}
public Integer getMatchId() {
return this.matchId;
}
public boolean getMatchIsFinished() {
return this.matchIsFinished;
}
}
@@ -4,15 +4,14 @@ import com.google.common.collect.HashBiMap;
import de.jeyp91.ResourceProvider;
import de.jeyp91.StatusHolder;
import de.jeyp91.apifootball.APIFootballMatch;
import org.apache.logging.log4j.*;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TeamIDMatcher {
private static HashBiMap<Integer, Integer> ids = null;
private static final Logger logger = LoggerFactory.getLogger(TeamIDMatcher.class);
private static final Logger logger = LogManager.getLogger(TeamIDMatcher.class);
private static JSONArray teams;
private static boolean init = false;
public static final int HOME = 0;
@@ -10,7 +10,7 @@ public class TeamIDMatcherTemplateCreator {
public TeamIDMatcherTemplateCreator(int season, int league) throws Exception {
this.con = APIFootballConnector.getAPIFootballConnectorInstance(season);
JSONObject apiObject = con.getTeamsForLeague(season, league);
JSONObject apiObject = con.getTeamsForLeague(league);
JSONObject teamsObject = (JSONObject) apiObject.get("api");
this.teams = (JSONArray) teamsObject.get("teams");
}
+64 -39
View File
@@ -1,50 +1,75 @@
package de.jeyp91.tippliga;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TLWLeague {
private Integer season = null;
private Integer league = null;
private String leagueName = null;
private String leagueNameShort = null;
public TLWLeague(ResultSet rset) {
final int SEASON = 1;
final int LEAGUE = 2;
final int LEAGUE_NAME = 3;
final int LEAGUE_NAME_SHORT = 4;
try {
this.season = Integer.parseInt(rset.getString(SEASON));
this.league = Integer.parseInt(rset.getString(LEAGUE));
this.leagueName = rset.getString(LEAGUE_NAME);
this.leagueNameShort = rset.getString(LEAGUE_NAME_SHORT);
} catch (SQLException e) {
e.printStackTrace();
public static String getLeagueName(int id) {
String leagueName = "";
switch (id) {
case 1:
leagueName = "Tippliga";
break;
case 46:
leagueName = "Elfmeter";
break;
case 47:
leagueName = "Relegation";
break;
case 48:
leagueName = "WTL-Pokal";
break;
case 49:
leagueName = "Liga-Cup";
break;
default: break;
}
return leagueName;
}
public Integer getSeason() {
return this.season;
public static String getLeagueNameShort(int id) {
String leagueName = "";
switch (id) {
case 1:
leagueName = "1. TLW";
break;
case 2:
leagueName = "2. TLW";
break;
case 46:
leagueName = "ELF";
break;
case 47:
leagueName = "REL";
break;
case 48:
leagueName = "WTL";
break;
case 49:
leagueName = "LC";
break;
default: break;
}
return leagueName;
}
public Integer getLeague() {
return this.league;
}
public String getLeagueName() {
return this.leagueName;
}
public String getLeagueNameShort() {
return this.leagueNameShort;
}
public String getLeagueNameCalendar() {
String leagueName = this.leagueName;
if (leagueName.equals("1. Tippliga Würzburg") || leagueName.equals("2. Tippliga Würzburg")) {
leagueName = "Tippliga";
public static String getLeagueNameCalendar(int id) {
String leagueName = "";
switch (id) {
case 1:
case 2:
leagueName = "Tippliga";
break;
case 46:
leagueName = "Elfmeter";
break;
case 47:
leagueName = "Relegation";
break;
case 48:
leagueName = "WTL-Pokal";
break;
case 49:
leagueName = "Liga Cup";
break;
default: break;
}
return leagueName;
}
+37 -56
View File
@@ -2,20 +2,17 @@ package de.jeyp91.tippliga;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.jeyp91.BaseMatch;
import de.jeyp91.apifootball.APIFootballMatch;
import de.jeyp91.teamidmatcher.TeamIDMatcher;
import de.jeyp91.apifootball.APIFootballMatch;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
*
*/
public class TLWMatch extends BaseMatch{
private static final Logger logger = LoggerFactory.getLogger(TLWMatch.class);
private Integer season = null;
private Integer league = null;
@@ -23,6 +20,8 @@ public class TLWMatch extends BaseMatch{
private String groupId = null;
private String formulaHome = null;
private String formulaGuest = null;
private Integer koMatch = 0;
private Integer showTable = null;
private String trend = null;
private Float odd1 = null;
private Float oddX = null;
@@ -117,18 +116,6 @@ public class TLWMatch extends BaseMatch{
this.matchDatetime = matchDatetime;
}
public TLWMatch(int season, int league, int matchday, int matchNo, int status, int koMatch, String formulaHome, String formulaGuest, String matchDatetime) {
this.season = season;
this.matchday = matchday;
this.league = league;
this.matchNo = matchNo;
this.status = status;
this.koMatch = koMatch;
this.formulaHome = formulaHome;
this.formulaGuest = formulaGuest;
this.matchDatetime = matchDatetime;
}
public TLWMatch(int season, int league, int matchday, int matchNo, int teamIdHome, int teamIdGuest, String matchDatetime, int koMatch) {
this.season = season;
this.matchday = matchday;
@@ -166,14 +153,6 @@ public class TLWMatch extends BaseMatch{
this.rating = referenceMatch.rating;
}
public TLWMatch(String formulaHome, String formulaGuest, String matchDateTime) {
this.teamIdHome = 0;
this.teamIdGuest = 0;
this.formulaHome = formulaHome;
this.formulaGuest = formulaGuest;
this.matchDatetime = matchDateTime;
}
public Integer getSeason() {
return this.season;
}
@@ -186,16 +165,38 @@ public class TLWMatch extends BaseMatch{
return this.matchNo;
}
public Integer getKoMatch() {
return this.koMatch;
}
public String getGroupId() {
return this.groupId;
}
public Integer getShowTable() {
return this.showTable;
}
public String getFormulaHome() {
return this.formulaHome != null ? this.formulaHome : "D";
String formula = "'D'";
if(this.teamIdHome != null) {
return "''";
}
else if (this.formulaHome != null) {
formula = this.formulaHome;
}
return formula;
}
public String getFormulaGuest() {
return this.formulaGuest != null ? this.formulaGuest : "D";
String formula = "'D'";
if(this.teamIdGuest != null) {
return "''";
}
else if (this.formulaGuest != null) {
formula = this.formulaGuest;
}
return formula;
}
public String getSQLQueryInsert() {
@@ -214,16 +215,16 @@ public class TLWMatch extends BaseMatch{
return this.season + ", " +
this.league + ", " +
this.matchNo + ", " +
nullToSqlNullString(this.teamIdHome) + ", " +
nullToSqlNullString(this.teamIdGuest) + ", " +
nullToSqlEmptyString(this.teamIdHome) + ", " +
nullToSqlEmptyString(this.teamIdGuest) + ", " +
nullToSqlEmptyString(this.goalsHome) + ", " +
nullToSqlEmptyString(this.goalsGuest) + ", " +
this.matchday + ", " +
this.status + ", " +
nullToSqlEmptyString(this.matchDatetime) + ", " +
nullToSqlEmptyString(this.groupId) + ", " +
"'" + getFormulaHome() + "'" + ", " +
"'" + getFormulaGuest() + "'" + ", " +
getFormulaHome() + ", " +
getFormulaGuest() + ", " +
nullToSqlEmptyString(this.koMatch) + ", " +
nullToSqlEmptyString(this.goalsOvertimeHome) + ", " +
nullToSqlEmptyString(this.goalsOvertimeGuest) + ", " +
@@ -235,10 +236,6 @@ public class TLWMatch extends BaseMatch{
return number != null ? number.toString() : "''";
}
private String nullToSqlNullString(Integer number) {
return number != null ? number.toString() : "0";
}
private String nullToSqlEmptyString(String string) {
return string != null ? "'"+string+"'" : "''";
}
@@ -263,6 +260,10 @@ public class TLWMatch extends BaseMatch{
this.matchDatetime = matchDateTime;
}
public void setShowTable(Boolean showTable) {
this.showTable = showTable ? 0 : 1;
}
public void updateMatch(APIFootballMatch apiFootballMatch) {
this.teamIdHome = TeamIDMatcher.getTippligaIdFromApiFootballId(apiFootballMatch, TeamIDMatcher.HOME);
this.teamIdGuest = TeamIDMatcher.getTippligaIdFromApiFootballId(apiFootballMatch, TeamIDMatcher.GUEST);
@@ -280,24 +281,4 @@ public class TLWMatch extends BaseMatch{
return "";
}
}
public static boolean isSameMatchPlaceholder (TLWMatch tlwMatch, TLWMatch placeholderConfigMatch) {
String placeholderConfigMatchDateTime = placeholderConfigMatch.getMatchDateTime();
String tlwMatchDateTime = tlwMatch.getMatchDateTime();
String placeholderConfigMatchFormulaHome = placeholderConfigMatch.getFormulaHome();
String tlwMatchFormulaHome = tlwMatch.getFormulaHome();
String placeholderConfigMatchFormulaGuest = placeholderConfigMatch.getFormulaGuest();
String tlwMatchFormulaGuest = tlwMatch.getFormulaGuest();
if(Objects.equals(tlwMatchDateTime, placeholderConfigMatchDateTime) &&
Objects.equals(tlwMatchFormulaHome, placeholderConfigMatchFormulaHome) &&
Objects.equals(tlwMatchFormulaGuest, placeholderConfigMatchFormulaGuest)) {
return true;
}
if(Objects.equals(tlwMatchDateTime, placeholderConfigMatchDateTime) &&
Objects.equals(tlwMatch.getTeamIdHome(), null) &&
Objects.equals(tlwMatch.getTeamIdGuest(), null)) {
return true;
}
return false;
}
}
@@ -6,6 +6,11 @@ import java.sql.SQLException;
public class TLWMatchday {
final Integer STATUS_NOTSTARTED = 0;
final Integer STATUS_STARTED = 1;
final Integer STATUS_PROVISIONAL_RESULT_AVAILABLE = 2;
final Integer STATUS_FINISHED = 3;
private Integer season = null;
private Integer league = null;
private Integer matchday = null;
@@ -29,15 +34,15 @@ public class TLWMatchday {
final int MATCHES = 9;
try {
this.season = Integer.valueOf(rset.getString(SEASON));
this.league = Integer.valueOf(rset.getString(LEAGUE));
this.matchday = Integer.valueOf(rset.getString(MATCHDAY));
this.status = Integer.valueOf(rset.getString(STATUS));
this.season = Integer.parseInt(rset.getString(SEASON));
this.league = Integer.parseInt(rset.getString(LEAGUE));
this.matchday = Integer.parseInt(rset.getString(MATCHDAY));
this.status = Integer.parseInt(rset.getString(STATUS));
this.deliveryDate = rset.getString(DELIVERY_DATE);
this.deliveryDate2 = rset.getString(DELIVERY_DATE_2);
this.deliveryDate3 = rset.getString(DELIVERY_DATE_3);
this.matchdayName = rset.getString(MATCHDAY_NAME);
this.matches = Integer.valueOf(rset.getString(MATCHES));
this.matches = Integer.parseInt(rset.getString(MATCHES));
} catch (SQLException e) {
/* TODO */
e.printStackTrace();
@@ -22,7 +22,7 @@ public class TLWMatchdaysCreator {
this.season = season;
this.league = league;
TLWMatchesCreatorFootball matchesCreator = new TLWMatchesCreatorFootball(season, league, configPath);
TLWMatchesCreatorFootball matchesCreator = new TLWMatchesCreatorFootball(season, 1, configPath);
this.matches = matchesCreator.getMatches();
TippligaConfigProvider prov = new TippligaConfigProvider(season);
@@ -1,8 +1,8 @@
package de.jeyp91.tippliga;
import de.jeyp91.tippligaforum.TippligaSQLConnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@@ -13,7 +13,7 @@ import static de.jeyp91.googlecalendar.TippligaGoogleEventManager.*;
public class TLWMatchdaysUpdater {
private final Logger logger = LoggerFactory.getLogger(TLWMatch.class);
private final Logger logger = LogManager.getLogger(TLWMatch.class);
int season;
int league;
@@ -29,7 +29,8 @@ public class TLWMatchdaysUpdater {
this.matchdaysOriginal = conn.getMatchdays(String.valueOf(season), String.valueOf(league));
this.matchdaysOriginal.sort(Comparator.comparing(TLWMatchday::getMatchday));
this.matchdaysUpdated = conn.getUpdatedMatchdaysBasedOnMatches(String.valueOf(season), String.valueOf(league));
TLWMatchdaysCreator creator = new TLWMatchdaysCreator(season, league, configPath);
this.matchdaysUpdated = creator.getMatchdays();
this.matchdaysUpdated.sort(Comparator.comparing(TLWMatchday::getMatchday));
}
@@ -26,7 +26,7 @@ public class TLWMatchesCreatorFootball extends TLWMatchesCreatorBase {
this.season = season;
this.league = league;
this.conn = APIFootballConnector.getAPIFootballConnectorInstance(season);
this.conn = APIFootballConnector.getAPIFootballConnectorInstance(season - 1);
TippligaConfigProvider prov = new TippligaConfigProvider(season);
this.config = prov.getTippligaConfig(configFileName);
@@ -69,20 +69,6 @@ public class TLWMatchesCreatorFootball extends TLWMatchesCreatorBase {
}
}
// Add PlaceholderSingleMatch matches
for (Object matchesConfigObject : matchesConfig) {
JSONObject singleMatchConfig = (JSONObject) matchesConfigObject;
if(singleMatchConfig.get("type").equals("PlaceholderSingleMatch")) {
String formulaHome = (String) singleMatchConfig.get("formulaHome");
String formulaGuest = (String) singleMatchConfig.get("formulaGuest");
String matchDatetime = (String) singleMatchConfig.get("placeholderDatetime");
int matchNo = this.nextMatchNo;
this.nextMatchNo++;
this.TLWMatches.add(new TLWMatch(this.season, this.league, TLWMatchday, matchNo, 0, this.ko, formulaHome, formulaGuest, matchDatetime));
matchdayMatchCounter++;
}
}
// Add empty missing matches
int matchesPerMatchdayTemp = 0;
if(this.matchesPerMatchday != 0) {
@@ -3,8 +3,8 @@ package de.jeyp91.tippliga;
import de.jeyp91.ResourceProvider;
import de.jeyp91.StatusHolder;
import de.jeyp91.tippligaforum.TippligaConfigProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
@@ -12,7 +12,7 @@ import java.util.ArrayList;
public class TLWMatchesCreatorTipperLeague extends TLWMatchesCreatorBase {
private final Logger logger = LoggerFactory.getLogger(TLWMatchesCreatorTipperLeague.class);
private final Logger logger = LogManager.getLogger(TLWMatchesCreatorTipperLeague.class);
int season;
int league;
@@ -2,8 +2,8 @@ package de.jeyp91.tippliga;
import de.jeyp91.ResourceProvider;
import de.jeyp91.tippligaforum.TippligaConfigProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
@@ -11,7 +11,7 @@ import java.util.ArrayList;
public class TLWMatchesCreatorTipperPokal extends TLWMatchesCreatorBase{
Logger logger = LoggerFactory.getLogger(TLWMatchesCreatorTipperPokal.class);
Logger logger = LogManager.getLogger(TLWMatchesCreatorTipperPokal.class);
int season;
int league;
@@ -16,7 +16,7 @@ public class TLWMatchesManagerBase {
protected int season;
protected int league;
protected int numberOfMatchdays;
protected Integer matchesPerMatchday = null;
protected int matchesPerMatchday;
protected int ko;
protected int betKOType;
@@ -27,7 +27,6 @@ public class TLWMatchesManagerBase {
TippligaConfigProvider prov = new TippligaConfigProvider(this.season);
JSONObject config = prov.getTippligaConfig(configFileName);
this.numberOfMatchdays = ((Long) config.get("numberOfMatchdays")).intValue();
try { this.matchesPerMatchday = ((Long) config.get("matchesPerMatchday")).intValue(); } catch (Exception ignored) {}
this.matchdayConfig = (JSONArray) config.get("matchdayConfig");
this.ko = ((Long) config.get("ko")).intValue();
Long parsedBetKOType = (Long) config.get("betKOType");
@@ -106,7 +105,8 @@ public class TLWMatchesManagerBase {
return (int) date1.until(date2, ChronoUnit.DAYS);
}
protected TLWMatch getMatchingMatch(APIFootballMatch apiFootballMatch, ArrayList<TLWMatch> tlwMatches) {
protected TLWMatch getMatchingMatch(APIFootballMatch apiFootballMatch, ArrayList<TLWMatch> tlwMatches) throws NullPointerException{
int foundMatches = 0;
TLWMatch matchingMatch = null;
for(TLWMatch match : tlwMatches) {
Integer apiTeamIdHome = TeamIDMatcher.getTippligaIdFromApiFootballId(apiFootballMatch, TeamIDMatcher.HOME);
@@ -122,6 +122,7 @@ public class TLWMatchesManagerBase {
apiTeamIdHome.equals(tlwTeamIdHome)
&& apiTeamIdGuest.equals(tlwTeamIdGuest)
) {
foundMatches++;
matchingMatch = match;
}
}
@@ -1,21 +1,21 @@
package de.jeyp91.tippliga;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Objects;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.jeyp91.apifootball.APIFootballMatch;
import de.jeyp91.apifootball.APIFootballMatchesProvider;
import de.jeyp91.teamidmatcher.TeamIDMatcher;
import de.jeyp91.tippligaforum.TippligaSQLConnector;
import de.jeyp91.tippligaforum.TippligaWebsiteConnector;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Objects;
public class TLWMatchesResultsUpdater extends TLWMatchesManagerBase {
private static final Logger logger = LoggerFactory.getLogger(TLWMatchesResultsUpdater.class);
private static final Logger logger = LogManager.getLogger(TLWMatchesResultsUpdater.class);
ArrayList<ArrayList<TLWMatch>> tlwMatchesUpdated = new ArrayList<>();
@@ -37,8 +37,9 @@ public class TLWMatchesResultsUpdater extends TLWMatchesManagerBase {
TippligaSQLConnector tippligaSQLConnector = TippligaSQLConnector.getInstance();
for (Object singleMatchdayConfig : this.matchdayConfig) {
int tlwMatchday = ((Long) ((JSONObject) singleMatchdayConfig).get("TLWMatchday")).intValue();
JSONArray matchesConfig = (JSONArray) ((JSONObject) singleMatchdayConfig).get("matchesConfig");
ArrayList<APIFootballMatch> apiFootballMatches = apiFootballMatchesProvider.getAPIFootballMatchesFromConfig((JSONObject) singleMatchdayConfig);
ArrayList<APIFootballMatch> apiFootballMatches = apiFootballMatchesProvider.getAPIFootballMatchesFromConfig(matchesConfig);
ArrayList<TLWMatch> tlwMatchesOriginalMatchday = tippligaSQLConnector.getMatches(String.valueOf(this.season), String.valueOf(this.league), String.valueOf(tlwMatchday));
ArrayList<TLWMatch> tlwMatchesUpdatedMatchday = new ArrayList<>();
@@ -50,13 +51,13 @@ public class TLWMatchesResultsUpdater extends TLWMatchesManagerBase {
logger.error("Not matching config!");
}
if(!apiFootballMatches.isEmpty()) {
if(apiFootballMatches.size() > 0) {
updateResults(tlwMatchesUpdatedMatchday, apiFootballMatches);
}
updateBeautifulInfo(tlwMatchesOriginalMatchday, tlwMatchesUpdatedMatchday);
tlwMatchesUpdatedMatchday.removeIf(tlwMatch -> tlwMatch.getUpdateStatus() != TLWMatch.COMPARISON.DIFFERENT_RESULT);
if(!tlwMatchesUpdatedMatchday.isEmpty()) this.tlwMatchesUpdated.add(tlwMatchesUpdatedMatchday);
if(tlwMatchesUpdatedMatchday.size() > 0) this.tlwMatchesUpdated.add(tlwMatchesUpdatedMatchday);
}
}
@@ -89,7 +90,7 @@ public class TLWMatchesResultsUpdater extends TLWMatchesManagerBase {
tlwMatch.setGoalsGuest(apiFootballMatch.getGoalsGuest());
tlwMatch.setUpdateStatus(TLWMatch.COMPARISON.DIFFERENT_RESULT);
}
if(tlwMatch.getKoMatch() &&
if(tlwMatch.getKoMatch() == 1 &&
this.betKOType == 2 &&
(!Objects.equals(tlwMatch.getGoalsOvertimeHome(), apiFootballMatch.getGoalsOvertimeHome())
|| !Objects.equals(tlwMatch.getGoalsOvertimeGuest(), apiFootballMatch.getGoalsOvertimeGuest()))
@@ -98,7 +99,7 @@ public class TLWMatchesResultsUpdater extends TLWMatchesManagerBase {
tlwMatch.setGoalsOvertimeGuest(apiFootballMatch.getGoalsOvertimeGuest());
tlwMatch.setUpdateStatus(TLWMatch.COMPARISON.DIFFERENT_RESULT);
}
if(tlwMatch.getKoMatch() &&
if(tlwMatch.getKoMatch() == 1 &&
(this.betKOType == 1 || this.betKOType == 3) &&
(apiFootballMatch.getGoalsPenaltyHome() != null) &&
(!Objects.equals(tlwMatch.getGoalsOvertimeHome(), apiFootballMatch.getGoalsPenaltyHome())
@@ -108,7 +109,7 @@ public class TLWMatchesResultsUpdater extends TLWMatchesManagerBase {
tlwMatch.setGoalsOvertimeGuest(apiFootballMatch.getGoalsPenaltyGuest());
tlwMatch.setUpdateStatus(TLWMatch.COMPARISON.DIFFERENT_RESULT);
}
if(tlwMatch.getKoMatch() &&
if(tlwMatch.getKoMatch() == 1 &&
(this.betKOType == 1 || this.betKOType == 3) &&
(apiFootballMatch.getGoalsPenaltyHome() == null) &&
(!Objects.equals(tlwMatch.getGoalsOvertimeHome(), apiFootballMatch.getGoalsOvertimeHome())
@@ -130,9 +131,6 @@ public class TLWMatchesResultsUpdater extends TLWMatchesManagerBase {
private void updateBeautifulInfo(ArrayList<TLWMatch> matchesOriginal, ArrayList<TLWMatch> matchesUpdated) {
for (int i = 0; i < matchesOriginal.size(); i++) {
if(matchesUpdated.get(i).getUpdateStatus() != TLWMatch.COMPARISON.DIFFERENT_RESULT) {
continue;
}
updateBeautifulInfo(matchesOriginal.get(i), matchesUpdated.get(i));
}
}
@@ -150,7 +148,7 @@ public class TLWMatchesResultsUpdater extends TLWMatchesManagerBase {
"Ergebnis zu '" + matchUpdated.getGoalsHome() + ":" + matchUpdated.getGoalsGuest() + "'.\n";
}
if(matchOriginal.getKoMatch() && (!Objects.equals(matchOriginal.getGoalsOvertimeHome(), matchUpdated.getGoalsOvertimeHome())
if(matchOriginal.getKoMatch() == 1 && (!Objects.equals(matchOriginal.getGoalsOvertimeHome(), matchUpdated.getGoalsOvertimeHome())
|| !Objects.equals(matchOriginal.getGoalsOvertimeGuest(), matchUpdated.getGoalsOvertimeGuest()))) {
this.beautifulInfo += beautifulInfoStart +
"Ergebnis Nachspielzeit zu '" + matchUpdated.getGoalsOvertimeHome() + ":" + matchUpdated.getGoalsOvertimeGuest() + "'.\n";
@@ -159,8 +157,8 @@ public class TLWMatchesResultsUpdater extends TLWMatchesManagerBase {
if(matchOriginal.getStatus().equals(TLWMatch.STATUS_PROVISIONAL_RESULT_AVAILABLE)
&& Objects.equals(matchOriginal.getGoalsHome(), matchUpdated.getGoalsHome())
&& Objects.equals(matchOriginal.getGoalsGuest(), matchUpdated.getGoalsGuest())
&& (!matchOriginal.getKoMatch() || (
matchOriginal.getKoMatch()
&& (matchOriginal.getKoMatch() == 0 || (
matchOriginal.getKoMatch() == 1
&& Objects.equals(matchOriginal.getGoalsOvertimeHome(), matchUpdated.getGoalsOvertimeHome())
&& Objects.equals(matchOriginal.getGoalsOvertimeGuest(), matchUpdated.getGoalsOvertimeGuest())
))
@@ -1,23 +1,20 @@
package de.jeyp91.tippliga;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Objects;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.jeyp91.StatusHolder;
import de.jeyp91.teamidmatcher.TeamIDMatcher;
import de.jeyp91.apifootball.APIFootballMatch;
import de.jeyp91.apifootball.APIFootballMatchesProvider;
import de.jeyp91.teamidmatcher.TeamIDMatcher;
import de.jeyp91.tippligaforum.TippligaSQLConnector;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import java.time.*;
import java.util.ArrayList;
public class TLWMatchesUpdaterFootball extends TLWMatchesManagerBase {
private static final Logger logger = LoggerFactory.getLogger(TLWMatchesUpdaterFootball.class);
private static final Logger logger = LogManager.getLogger(TLWMatchesUpdaterFootball.class);
ArrayList<TLWMatch> tlwMatchesOriginal;
ArrayList<TLWMatch> tlwMatchesUpdated;
@@ -41,12 +38,9 @@ public class TLWMatchesUpdaterFootball extends TLWMatchesManagerBase {
TippligaSQLConnector tippligaSQLConnector = TippligaSQLConnector.getInstance();
for (Object singleMatchdayConfig : this.matchdayConfig) {
int tlwMatchday = ((Long) ((JSONObject) singleMatchdayConfig).get("TLWMatchday")).intValue();
JSONArray matchesConfig = (JSONArray) ((JSONObject) singleMatchdayConfig).get("matchesConfig");
ArrayList<APIFootballMatch> apiFootballMatches = apiFootballMatchesProvider.getAPIFootballMatchesFromConfig((JSONObject) singleMatchdayConfig);
if(apiFootballMatches.isEmpty()) {
continue;
}
ArrayList<APIFootballMatch> apiFootballMatches = apiFootballMatchesProvider.getAPIFootballMatchesFromConfig(matchesConfig);
ArrayList<TLWMatch> tlwMatchesOriginalMatchday = tippligaSQLConnector.getMatches(String.valueOf(this.season), String.valueOf(this.league), String.valueOf(tlwMatchday));
ArrayList<TLWMatch> tlwMatchesUpdatedMatchday = new ArrayList<>();
@@ -62,16 +56,14 @@ public class TLWMatchesUpdaterFootball extends TLWMatchesManagerBase {
LocalDateTime firstMatchOriginal = TLWMatchesManagerBase.getFirstMatchtimeTLW(tlwMatchesOriginalMatchday);
LocalDateTime firstMatchUpdated = TLWMatchesManagerBase.getFirstMatchtimeAPIFootball(apiFootballMatches);
if(now.isBefore(firstMatchOriginal) && now.isBefore(firstMatchUpdated)) {
if(apiFootballMatches.size() > 0
&& now.isBefore(firstMatchOriginal)
&& now.isBefore(firstMatchUpdated)) {
addMissingMatches(tlwMatchesUpdatedMatchday, apiFootballMatches);
updateMatchDateTimes(tlwMatchesUpdatedMatchday, apiFootballMatches);
updateShowTable(tlwMatchesUpdatedMatchday, apiFootballMatches);
updateStatus(tlwMatchesUpdatedMatchday);
}
if(now.isBefore(firstMatchOriginal)) {
updateStatus(tlwMatchesUpdatedMatchday);
addPlaceholderMatches(tlwMatchesUpdatedMatchday, (JSONObject) singleMatchdayConfig);
}
this.tlwMatchesOriginal.addAll(tlwMatchesOriginalMatchday);
this.tlwMatchesUpdated.addAll(tlwMatchesUpdatedMatchday);
@@ -143,14 +135,6 @@ public class TLWMatchesUpdaterFootball extends TLWMatchesManagerBase {
"Spiel in Tabelle einberechnen zu '" + (matchUpdated.getShowTable() == 1 ? "falsch" : "wahr") + "'.\n";
}
if (!matchOriginal.getKoMatch().equals(matchUpdated.getKoMatch())) {
updateString += updateStart +
"ko_match = '" + (matchUpdated.getKoMatch() ? "1" : "0") + "' " +
condition;
this.beautifulInfo += beautifulInfoStart +
"KO zu '" + (matchUpdated.getKoMatch() ? "wahr" : "falsch") + "'.\n";
}
return updateString;
}
@@ -159,104 +143,32 @@ public class TLWMatchesUpdaterFootball extends TLWMatchesManagerBase {
ArrayList<APIFootballMatch> apiFootballMatches) {
ArrayList<APIFootballMatch> missingMatches = new ArrayList<>();
if(!validateApiFootballTeamIds(apiFootballMatches)) {
return;
}
for(APIFootballMatch apiFootballMatch : apiFootballMatches) {
if(getMatchingMatch(apiFootballMatch, tlwMatches) == null) {
missingMatches.add(apiFootballMatch);
try {
if(getMatchingMatch(apiFootballMatch, tlwMatches) == null) {
missingMatches.add(apiFootballMatch);
}
} catch (NullPointerException ignored) {
}
}
for (APIFootballMatch missingMatch : missingMatches) {
Integer missingTeamIdHome = TeamIDMatcher.getTippligaIdFromApiFootballId(missingMatch, TeamIDMatcher.HOME);
Integer missingTeamIdGuest = TeamIDMatcher.getTippligaIdFromApiFootballId(missingMatch, TeamIDMatcher.GUEST);
boolean done = false;
// update placeholder match based on matching match datetime
for (TLWMatch tlwMatch : tlwMatches) {
Boolean homeMatches = tlwMatch.getTeamIdHome() == 0 || tlwMatch.getTeamIdHome().equals(missingTeamIdHome);
Boolean guestMatches =tlwMatch.getTeamIdGuest() == 0 || tlwMatch.getTeamIdGuest().equals(missingTeamIdGuest);
Boolean timeMatches = Objects.equals(tlwMatch.getMatchDateTime(), missingMatch.getMatchDateTime().replace("T", " ").substring(0, 19));
Boolean formulaHomeMatches = !Objects.equals(tlwMatch.getFormulaHome(), "");
Boolean formulaGuestMatches = !Objects.equals(tlwMatch.getFormulaGuest(), "");
if (
homeMatches
&& guestMatches
&& timeMatches
&& formulaHomeMatches
&& formulaGuestMatches
) {
for(TLWMatch tlwMatch : tlwMatches) {
if(tlwMatch.getTeamIdHome() == 0 && tlwMatch.getTeamIdGuest() == 0) {
tlwMatch.updateMatch(missingMatch);
done = true;
break;
}
}
// update empty match
if(!done) {
for (TLWMatch tlwMatch : tlwMatches) {
Integer teamIdHome = tlwMatch.getTeamIdHome();
Integer teamIdGuest = tlwMatch.getTeamIdGuest();
String formulaHome = tlwMatch.getFormulaHome();
String formulaGuest = tlwMatch.getFormulaGuest();
if (
(Objects.equals(teamIdHome, 0) || Objects.equals(teamIdHome, null))
&& (Objects.equals(teamIdGuest, 0) || Objects.equals(teamIdGuest, null))
&& (Objects.equals(formulaHome, "") || Objects.equals(formulaHome, "D"))
&& (Objects.equals(formulaGuest, "") || Objects.equals(formulaGuest, "D"))
) {
tlwMatch.updateMatch(missingMatch);
done = true;
break;
}
}
}
if(!done) {
logger.error("Could not add missing match: " + this.season + ", " + this.league + ", " + tlwMatches.get(0).getMatchday() + ", " + missingMatch.getTeamNameHome() + " - " + missingMatch.getTeamNameGuest());
}
}
}
private void addPlaceholderMatches(ArrayList<TLWMatch> tlwMatches,
JSONObject matchdayConfig) {
Integer numberOfMatches = this.matchesPerMatchday;
try { numberOfMatches = ((Long) matchdayConfig.get("numberOfMatches")).intValue();} catch (Exception ignored) {}
ArrayList<TLWMatch> placeholderMatches = new ArrayList<>();
ArrayList<TLWMatch> tlwMatchesCopy = new ArrayList<>(tlwMatches);
JSONArray matchesConfig = (JSONArray) matchdayConfig.get("matchesConfig");
for (Object singleMatchConfig : matchesConfig) {
// check if type placeholderSingleMatch
if(((JSONObject) singleMatchConfig).get("type").equals("PlaceholderSingleMatch")) {
String formulaHome = (String) ((JSONObject) singleMatchConfig).get("formulaHome");
String formulaGuest = (String) ((JSONObject) singleMatchConfig).get("formulaGuest");
String matchDateTime = (String) ((JSONObject) singleMatchConfig).get("placeholderDatetime");
TLWMatch placeholderMatch = new TLWMatch(formulaHome, formulaGuest, matchDateTime);
placeholderMatches.add(placeholderMatch);
}
}
// filter placeholderMatches by checking if they are already in tlwMatches
Iterator<TLWMatch> placeholderIterator = placeholderMatches.iterator();
while (placeholderIterator.hasNext()) {
TLWMatch placeholderMatch = placeholderIterator.next();
Iterator<TLWMatch> tlwMatchIterator = tlwMatchesCopy.iterator();
while (tlwMatchIterator.hasNext()) {
TLWMatch tlwMatch = tlwMatchIterator.next();
if (TLWMatch.isSameMatchPlaceholder(tlwMatch, placeholderMatch)) {
tlwMatchIterator.remove();
placeholderIterator.remove();
break;
}
}
}
// check if total number of matches is not too high
if(tlwMatches.size() + placeholderMatches.size() > (numberOfMatches)) {
logger.error("Too many matches in config: " + this.season + ", " + this.league + ", " + tlwMatches.get(0).getMatchday());
} else {
// add placeholderMatches to tlwMatches
tlwMatches.addAll(placeholderMatches);
}
}
private void updateMatchDateTimes(
ArrayList<TLWMatch> tlwMatches,
ArrayList<APIFootballMatch> apiFootballMatches)
@@ -283,13 +195,10 @@ public class TLWMatchesUpdaterFootball extends TLWMatchesManagerBase {
if(earliestDate.isAfter(now)) {
for(TLWMatch match : matches) {
LocalDateTime date = TLWMatchesManagerBase.getDate(match);
int daysDifference = TLWMatchesManagerBase.getDaysDifference(earliestDate, date);
if (daysDifference == 0) {
if (getDaysDifference(earliestDate, date) == 0) {
match.setStatus(0);
} else if (daysDifference > 0 && daysDifference < 7) {
match.setStatus(-1);
} else {
match.setStatus(-2);
match.setStatus(-1);
}
}
}
@@ -303,27 +212,8 @@ public class TLWMatchesUpdaterFootball extends TLWMatchesManagerBase {
for(APIFootballMatch apiFootballMatch : apiFootballMatches) {
try {
TLWMatch tlwMatch = getMatchingMatch(apiFootballMatch, tlwMatchesCopy);
if(tlwMatch.getTeamIdHome() == 4) {
int debug = 1;
}
tlwMatchesCopy.remove(tlwMatch);
tlwMatch.setShowTable(apiFootballMatch.getShowTable() == 0);
} catch (NullPointerException ignored) {
}
}
}
private void updateKo(
ArrayList<TLWMatch> tlwMatches,
ArrayList<APIFootballMatch> apiFootballMatches)
{
ArrayList<TLWMatch> tlwMatchesCopy = new ArrayList<>(tlwMatches);
for(APIFootballMatch apiFootballMatch : apiFootballMatches) {
try {
TLWMatch tlwMatch = getMatchingMatch(apiFootballMatch, tlwMatchesCopy);
tlwMatchesCopy.remove(tlwMatch);
tlwMatch.setKoMatch(apiFootballMatch.getKoMatch());
tlwMatch.setShowTable(apiFootballMatch.getShowTable());
} catch (NullPointerException ignored) {
}
@@ -337,20 +227,4 @@ public class TLWMatchesUpdaterFootball extends TLWMatchesManagerBase {
public String getBeautifulInfo() {
return this.beautifulInfo;
}
private boolean validateApiFootballTeamIds(ArrayList<APIFootballMatch> apiFootballMatches) {
int missing = 0;
for(APIFootballMatch apiFootballMatch : apiFootballMatches) {
if(TeamIDMatcher.getTippligaIdFromApiFootballId(apiFootballMatch, TeamIDMatcher.HOME) == null) {
missing++;
}
if(TeamIDMatcher.getTippligaIdFromApiFootballId(apiFootballMatch, TeamIDMatcher.GUEST) == null) {
missing++;
}
}
return missing == 0;
}
}
@@ -1,8 +1,8 @@
package de.jeyp91.tippliga;
import de.jeyp91.tippligaforum.TippligaSQLConnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.ArrayList;
import java.util.LinkedHashSet;
@@ -10,7 +10,7 @@ import java.util.Set;
public class TLWTeamsCreator {
private static final Logger logger = LoggerFactory.getLogger(TLWTeamsCreator.class);
private static final Logger logger = LogManager.getLogger(TLWTeamsCreator.class);
int season;
int league;
ArrayList<TLWMatch> matches;
@@ -1,35 +1,22 @@
package de.jeyp91.tippligaforum;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.*;
import de.jeyp91.S3Provider;
import de.jeyp91.apifootball.APIFootballMatch;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
public class MatchesListCreator {
private final JSONObject mainObject = new JSONObject();
private String country;
private String leagueName;
private final int season;
private final String country;
private final String leagueName;
public MatchesListCreator(int season, int league) {
this.season = season;
public MatchesListCreator(int league) {
S3Provider prov = new S3Provider();
JSONObject leagueConfig = prov.getFixturesJSONFromS3(season, league);
if (leagueConfig == null) {
return;
}
JSONArray matchesAPIFootball = (JSONArray) leagueConfig.get("response");
if(matchesAPIFootball.isEmpty()) {
return;
}
JSONObject leagueConfig = prov.getFixturesJSONFromS3(league);
JSONObject api = (JSONObject) leagueConfig.get("api");
JSONArray matchesAPIFootball = (JSONArray) api.get("fixtures");
JSONObject firstMatchAPIFootball = (JSONObject) matchesAPIFootball.get(0);
JSONObject leagueObject = (JSONObject) firstMatchAPIFootball.get("league");
@@ -53,20 +40,16 @@ public class MatchesListCreator {
JSONObject matchAPIFootball = (JSONObject) matchAPIFootballObject;
JSONObject match = new JSONObject();
JSONObject leagueObject = (JSONObject) matchAPIFootball.get("league");
Long leagueId = (Long) leagueObject.get("id");
String matchdayString = leagueObject.get("round").toString();
int matchday = APIFootballMatch.getMatchdayFromRoundString(this.season, matchdayString, leagueId.intValue());
Long leagueId = (Long) matchAPIFootball.get("league_id");
String matchdayString = matchAPIFootball.get("round").toString();
int matchday = APIFootballMatch.getMatchdayFromRoundString(2021, matchdayString, leagueId.intValue());
String matchtime = matchAPIFootball.get("event_date").toString().replace("T", " ").substring(0, 16);
Long fixtureId = (Long) matchAPIFootball.get("fixture_id");
JSONObject fixtureObject = (JSONObject) matchAPIFootball.get("fixture");
String matchtime = fixtureObject.get("date").toString().replace("T", " ").substring(0, 16);
Long fixtureId = (Long) fixtureObject.get("id");
JSONObject teamsObject = (JSONObject) matchAPIFootball.get("teams");
JSONObject teamHome = (JSONObject) teamsObject.get("home");
String teamNameHome = teamHome.get("name").toString();
JSONObject teamGuest = (JSONObject) teamsObject.get("away");
String teamNameGuest = teamGuest.get("name").toString();
JSONObject teamHome = (JSONObject) matchAPIFootball.get("homeTeam");
String teamNameHome = teamHome.get("team_name").toString();
JSONObject teamGuest = (JSONObject) matchAPIFootball.get("awayTeam");
String teamNameGuest = teamGuest.get("team_name").toString();
match.put("match", teamNameHome + " - " + teamNameGuest);
match.put("matchday", matchday);
@@ -1,20 +1,20 @@
package de.jeyp91.tippligaforum;
import de.jeyp91.App;
import de.jeyp91.apifootball.APIFootballUpdater;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.jeyp91.apifootball.APIFootballUpdater;
public class MatchesListForumUpdater {
private HashSet<Integer> leagues;
private static final Logger logger = LoggerFactory.getLogger(MatchesListForumUpdater.class);
private static final Logger logger = LogManager.getLogger(MatchesListForumUpdater.class);
public MatchesListForumUpdater() {
this.leagues = new APIFootballUpdater().getLeagues();
public MatchesListForumUpdater(int season) {
this.leagues = new APIFootballUpdater().getLeagues(season);
}
public void updateAllLeagues(int season) {
@@ -24,10 +24,7 @@ public class MatchesListForumUpdater {
}
public void updateLeague(int season, int league) {
MatchesListCreator creator = new MatchesListCreator(season, league);
if(creator.getMatches().isEmpty()) {
return;
}
MatchesListCreator creator = new MatchesListCreator(league);
String content = creator.getMatchesBeautiful();
String contentWithCodeBBCode = "<r><CODE><s>[code]</s>" + content + "<e>[/code]</e></CODE></r>";
Integer postId = getPostId(season, creator.getCountry(), creator.getLeagueName());
@@ -1,137 +0,0 @@
package de.jeyp91.tippligaforum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SeasonForumPostsCreator {
private static final Logger logger = LoggerFactory.getLogger(SeasonForumPostsCreator.class);
private static final String EMPTY_POST_CONTENT = "[code][/code]";
private static final String[] CONFIG_POSTS = {
"Supercup Tipper",
"WTL-Pokal Tipper",
"2. Tippliga Tipper",
"1. Tippliga Tipper",
"Relegation",
"Supercup",
"WTL-Pokal",
"Tippliga"
};
private static final String[] MATCH_LIST_POSTS = {
"World UEFA Super Cup",
"World UEFA Europa Conference League",
"World UEFA Europa League",
"World UEFA Champions League",
"Austria Bundesliga",
"Portugal Primeira Liga",
"Netherlands Eredivisie",
"Turkey Süper Lig",
"France Ligue 1",
"Italy Serie A",
"Spain La Liga",
"England Premier League",
"Germany Super Cup",
"Germany Frauen Bundesliga",
"Germany U19 Bundesliga",
"Germany Regionalliga - SudWest",
"Germany Regionalliga - Bayern",
"Germany 3. Liga",
"Germany 2. Bundesliga",
"Germany Bundesliga",
"Germany DFB Pokal"
};
private final int season;
private final TippligaWebsiteConnector connector;
private final TippligaSQLConnector sqlConnector;
public SeasonForumPostsCreator(int season) {
this.season = season;
try {
this.connector = new TippligaWebsiteConnector();
} catch (IOException e) {
throw new RuntimeException(e);
}
this.sqlConnector = TippligaSQLConnector.getInstance();
}
public void createAllPosts() {
Integer adminForumId = sqlConnector.getForumId("Admin");
if (adminForumId == null) {
logger.error("Forum 'Admin' not found. Aborting.");
return;
}
Integer tippligaConfigForumId = sqlConnector.getForumId("Tippliga-Config", adminForumId);
if (tippligaConfigForumId == null) {
logger.error("Forum 'Tippliga-Config' not found. Aborting.");
return;
}
Integer seasonForumId = sqlConnector.getForumId(String.valueOf(season), tippligaConfigForumId);
if (seasonForumId == null) {
logger.error("Forum '" + season + "' not found under Tippliga-Config. Aborting.");
return;
}
Integer ligenForumId = sqlConnector.getForumId("Ligen", seasonForumId);
if (ligenForumId == null) {
logger.error("Forum 'Ligen' not found under " + season + ". Aborting.");
return;
}
createConfigPosts(seasonForumId);
createMatchListPosts(ligenForumId);
}
private void createConfigPosts(int seasonForumId) {
logger.info("Creating config posts in forum " + season + "...");
for (String subject : CONFIG_POSTS) {
if (postExists(seasonForumId, subject)) {
logger.info("Config post '" + subject + "' already exists. Skipping.");
continue;
}
boolean success = connector.createPost(seasonForumId, subject, EMPTY_POST_CONTENT);
if (success) {
logger.info("Created config post: " + subject);
} else {
logger.error("Failed to create config post: " + subject);
}
}
}
private void createMatchListPosts(int ligenForumId) {
logger.info("Creating match list posts in " + season + " > Ligen...");
for (String subject : MATCH_LIST_POSTS) {
if (postExists(ligenForumId, subject)) {
logger.info("Match list post '" + subject + "' already exists. Skipping.");
continue;
}
boolean success = connector.createPost(ligenForumId, subject, EMPTY_POST_CONTENT);
if (success) {
logger.info("Created match list post: " + subject);
} else {
logger.error("Failed to create match list post: " + subject);
}
}
}
private boolean postExists(int forumId, String subject) {
String query = "SELECT COUNT(*) FROM phpbb_posts WHERE forum_id = " + forumId + " AND post_subject = '" + subject + "'";
ResultSet rset = sqlConnector.executeQuery(query);
try {
if (rset != null && rset.next()) {
return rset.getInt(1) > 0;
}
} catch (SQLException e) {
logger.error("Error checking if post exists", e);
}
return false;
}
}
@@ -1,32 +1,28 @@
package de.jeyp91.tippligaforum;
import de.jeyp91.StatusHolder;
import de.jeyp91.tippliga.TLWMatch;
import de.jeyp91.tippliga.TLWMatchday;
import de.jeyp91.tippliga.TLWTeam;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.xml.bind.DatatypeConverter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.util.ArrayList;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.Instant;
import java.util.ArrayList;
import javax.xml.bind.DatatypeConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.jeyp91.StatusHolder;
import de.jeyp91.tippliga.TLWLeague;
import de.jeyp91.tippliga.TLWMatch;
import de.jeyp91.tippliga.TLWMatchday;
import de.jeyp91.tippliga.TLWTeam;
import de.jeyp91.whatsapp.WhatsAppReminder;
public class TippligaSQLConnector {
Connection con;
private static final Logger logger = LoggerFactory.getLogger(TippligaSQLConnector.class);
private static final Logger logger = LogManager.getLogger(TippligaSQLConnector.class);
private static TippligaSQLConnector tlwSqlCon = null;
static {
@@ -67,7 +63,7 @@ public class TippligaSQLConnector {
}
public static TippligaSQLConnector getInstance() {
if (tlwSqlCon == null) {
if(tlwSqlCon == null) {
tlwSqlCon = new TippligaSQLConnector();
}
return tlwSqlCon;
@@ -144,66 +140,6 @@ public class TippligaSQLConnector {
return matchdays;
}
public TLWLeague getLeague(String season, String league) {
String queryString = "SELECT * FROM `phpbb_footb_leagues` WHERE `season` = " + season + " AND `league` = " + league + ";";
ResultSet rset = executeQuery(queryString);
TLWLeague tlwLeague = null;
try {
while (rset.next()) {
tlwLeague = new TLWLeague(rset);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return tlwLeague;
}
public ArrayList<TLWMatchday> getUpdatedMatchdaysBasedOnMatches(String season, String league) {
String queryString = """
SELECT
d1.season,
d1.league,
d1.matchday,
d1.status,
d1.delivery_date,
min(STR_TO_DATE(d2.match_datetime, '%Y-%m-%d %H:%i:%s')) as delivery_date_2,
min(STR_TO_DATE(d3.match_datetime, '%Y-%m-%d %H:%i:%s')) as delivery_date_3,
d1.matchday_name,
d1.matches
FROM (
SELECT
md.season,
md.league,
md.matchday,
md.status,
min(STR_TO_DATE(ma.match_datetime, '%Y-%m-%d %H:%i:%s')) AS delivery_date,
md.matchday_name,
md.matches
FROM phpbb_footb_matchdays md
LEFT JOIN phpbb_footb_matches ma ON (md.season = ma.season AND md.league = ma.league AND md.matchday = ma.matchday)
WHERE md.season =""" + " " + season + " " + """
AND md.league =""" + " " + league + " " + """
GROUP BY md.season, md.league, md.matchday
) AS d1
LEFT JOIN phpbb_footb_matches d2 ON (d1.season = d2.season AND d1.league = d2.league AND d1.matchday = d2.matchday
AND DATEDIFF(DATE(STR_TO_DATE(d2.match_datetime, '%Y-%m-%d %H:%i:%s')), DATE(d1.delivery_date)) > 0)
LEFT JOIN phpbb_footb_matches d3 ON (d1.season = d3.season AND d1.league = d3.league AND d1.matchday = d3.matchday
AND DATEDIFF(DATE(STR_TO_DATE(d3.match_datetime, '%Y-%m-%d %H:%i:%s')), DATE(d1.delivery_date)) > 6)
GROUP BY d1.season, d1.league, d1.matchday;
""";
ArrayList<TLWMatchday> matchdays = new ArrayList<>();
ResultSet rset = executeQuery(queryString);
try {
while (rset.next()) {
matchdays.add(new TLWMatchday(rset));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return matchdays;
}
public Integer getForumId(String forumName, int parentId) {
String queryString = "SELECT forum_id FROM phpbb_forums WHERE forum_name = \"" + forumName + "\" AND parent_id = " + parentId + ";";
ResultSet rset = executeQuery(queryString);
@@ -246,19 +182,19 @@ public class TippligaSQLConnector {
return post;
}
public ResultSet executeQuery(String queryString) {
public ResultSet executeQuery (String queryString){
Statement stmt;
ResultSet rset = null;
try {
stmt = con.createStatement();
rset = stmt.executeQuery(queryString);
} catch (SQLException e) {
logger.error(e.getMessage());
logger.error(e.getStackTrace());
}
return rset;
}
public void executeUpdate(String queryString) {
public void executeUpdate (String queryString){
Statement stmt;
try {
stmt = con.createStatement();
@@ -270,7 +206,7 @@ public class TippligaSQLConnector {
public void updatePost(int postId, String postText) {
String postChecksum = getChecksum(postText);
final long postEditTime = Instant.now().getEpochSecond();
final long postEditTime = Instant.now().getEpochSecond();;
final String postEditReason = "Update by tool.";
int postEditUser = 2;
String query = getPostUpdateQuery(postId, postText, postChecksum, postEditTime, postEditReason, postEditUser);
@@ -324,156 +260,4 @@ public class TippligaSQLConnector {
post = post.replace("'", "&#039;");
return post;
}
public String getNextMailReminder(int hours) {
String query = """
WITH next_delivery_date AS (
SELECT
m.season,
m.league,
l.league_name,
l.bet_type,
m.matchday,
m.matchday_name,
delivery_date,
STR_TO_DATE(delivery_date, '%Y-%m-%d %H:%i:%s') as parsed_delivery_date
FROM phpbb_footb_matchdays m
LEFT JOIN phpbb_footb_leagues l ON (m.season = l.season AND m.league = l.league)
HAVING parsed_delivery_date > NOW() AND parsed_delivery_date < NOW() + INTERVAL {{remainingHours}} HOUR
)
""".replace("{{remainingHours}}", "" + hours);
ResultSet rset = executeQuery(query);
String reminder = null;
try {
if (rset.next()) {
reminder = "Reminder for user: " + rset.getString("username") + " for matchday: " + rset.getString("matchday");
}
} catch (SQLException e) {
e.printStackTrace();
}
return reminder;
}
public ArrayList<WhatsAppReminder> getNextWhatsAppReminders(int hours) {
final String remindersToSendQuery = """
WITH delivery_date_next_day AS (
SELECT
m.season,
m.league,
l.league_name,
l.bet_type,
m.matchday,
m.matchday_name,
delivery_date,
STR_TO_DATE(delivery_date, '%Y-%m-%d %H:%i:%s') as parsed_delivery_date
FROM phpbb_footb_matchdays m
LEFT JOIN phpbb_footb_leagues l ON (m.season = l.season AND m.league = l.league)
HAVING parsed_delivery_date > NOW() AND parsed_delivery_date < NOW() + INTERVAL {{remainingHours}} HOUR
)
SELECT
d.season,
d.league,
d.league_name,
d.matchday,
IF(d.matchday_name = '', CONCAT(d.matchday, '. Spieltag'), d.matchday_name) AS matchday_name,
d.delivery_date,
CASE
WHEN DATE (d.parsed_delivery_date) = CURDATE() THEN 'heute'
WHEN DATE (d.parsed_delivery_date) = CURDATE() + INTERVAL 1 DAY THEN 'morgen'
ELSE DATE (d.parsed_delivery_date)
END AS today_or_tomorrow,
TIME_FORMAT(TIME(d.parsed_delivery_date), '%H:%i') AS time,
'{{remainingHours}}' AS remaining_hours,
b.user_id,
u.username,
CASE
WHEN SUBSTR(pf.pf_handynummer, 1, 2) = '00' THEN pf.pf_handynummer
WHEN SUBSTR(pf.pf_handynummer, 1, 1) = '+' THEN CONCAT('00', SUBSTR(pf.pf_handynummer, 2))
WHEN SUBSTR(pf.pf_handynummer, 1, 2) = '01' THEN CONCAT('0049', SUBSTR(pf.pf_handynummer, 2))
ELSE ''
END AS pf_handynummer,
count(*) AS missing_bets
FROM delivery_date_next_day d
LEFT JOIN phpbb_footb_matches m
ON (d.season = m.season
AND d.league = m.league
AND d.matchday = m.matchday)
LEFT JOIN phpbb_footb_bets b
ON (m.season = b.season
AND m.league = b.league
AND m.match_no = b.match_no)
LEFT JOIN phpbb_footb_matches mb
ON (d.season = mb.season
AND d.league = mb.league - 50
AND d.matchday = mb.matchday
AND (b.user_id + 2000 = mb.team_id_home OR b.user_id + 2000 = mb.team_id_guest))
LEFT JOIN phpbb_footb_whatsapp_reminders r
ON (m.season = r.season
AND m.league = r.league
AND m.matchday = r.matchday
AND r.delivery_date = d.delivery_date
AND b.user_id = r.user_id
AND r.remaining_hours = {{remainingHours}})
LEFT JOIN phpbb_users u
ON (b.user_id = u.user_id)
LEFT JOIN phpbb_footb_whatsapp_reminder_users wu
ON (u.username = wu.username)
LEFT JOIN phpbb_profile_fields_data pf
ON (u.user_id = pf.user_id)
WHERE ((d.bet_type = 0 AND mb.match_no IS NOT NULL) OR d.bet_type = 1)
AND (b.goals_home = '' OR b.goals_guest = '')
AND r.timestamp IS NULL
AND m.status = 0
AND wu.username IS NOT NULL
AND pf.pf_handynummer != ''
GROUP BY d.league_name, d.matchday, u.username, pf.pf_handynummer;
""".replace("{{remainingHours}}", "" + hours);
final int SEASON = 1;
final int LEAGUE = 2;
final int LEAGUE_NAME = 3;
final int MATCHDAY = 4;
final int MATCHDAY_NAME = 5;
final int DELIVERY_DATE = 6;
final int TODAY_OR_TOMORROW = 7;
final int TIME = 8;
final int HOURS = 9;
final int USER_ID = 10;
final int USERNAME = 11;
final int PHONE_NUMBER = 12;
final int MISSING_BETS = 13;
try {
ResultSet rset = executeQuery(remindersToSendQuery);
ArrayList <WhatsAppReminder> reminders = new ArrayList<>();
while (rset.next()) {
reminders.add(
new WhatsAppReminder(
Integer.parseInt(rset.getString(SEASON)),
Integer.parseInt(rset.getString(LEAGUE)),
rset.getString(LEAGUE_NAME),
Integer.parseInt(rset.getString(MATCHDAY)),
rset.getString(MATCHDAY_NAME),
rset.getString(DELIVERY_DATE),
rset.getString(TODAY_OR_TOMORROW),
rset.getString(TIME),
Integer.parseInt(rset.getString(HOURS)),
Integer.parseInt(rset.getString(USER_ID)),
rset.getString(USERNAME),
rset.getString(PHONE_NUMBER),
Integer.parseInt(rset.getString(MISSING_BETS))
)
);
}
return reminders;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public void markWhatsAppReminderAsSent(WhatsAppReminder reminder) {
String query = """
INSERT INTO phpbb_footb_whatsapp_reminders
(season, league, matchday, delivery_date, user_id, remaining_hours)
VALUES
(""" + reminder.season() + ", " + reminder.league() + ", " + reminder.matchday() + ", '" + reminder.deliveryDate() + "', " + reminder.userId() + ", " + reminder.remainingHours() + ");";
executeUpdate(query);
}
}
@@ -1,8 +1,8 @@
package de.jeyp91.tippligaforum;
import de.jeyp91.tippliga.TLWMatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.net.*;
@@ -23,7 +23,7 @@ public class TippligaWebsiteConnector {
CookieManager cm = new CookieManager(null, CookiePolicy.ACCEPT_ALL);
CookieStore cookieStore = cm.getCookieStore();
private static final Logger logger = LoggerFactory.getLogger(TippligaWebsiteConnector.class);
private static final Logger logger = LogManager.getLogger(TippligaWebsiteConnector.class);
private final HttpClient client;
private final String username = System.getenv("FORUM_USERNAME");
private final String password = System.getenv("FORUM_PASSWORD");
@@ -218,69 +218,6 @@ public class TippligaWebsiteConnector {
this.lastFormToken = matcher.group(2);
}
public boolean createPost(int forumId, String subject, String message) {
String url = "https://tippliga-wuerzburg.de/posting.php?mode=post&f=" + forumId;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create(url))
.GET().build();
String reqBody = "";
try {
TimeUnit.SECONDS.sleep(1);
reqBody = client.send(req, HttpResponse.BodyHandlers.ofString()).body();
} catch (IOException | InterruptedException e) {
logger.error("Failed to fetch posting form", e);
return false;
}
Pattern pattern = Pattern.compile("^[\\s\\S]*<input type=\"hidden\" name=\"creation_time\" value=\"([\\d]{10})\" \\/>[\\s\\S]*<input type=\"hidden\" name=\"form_token\" value=\"([\\d\\w]{40})\" \\/>[\\s\\S]*$");
Matcher matcher = pattern.matcher(reqBody);
if (!matcher.find()) {
logger.error("Could not find CSRF tokens in posting form for forum " + forumId);
return false;
}
String creationTime = matcher.group(1);
String formToken = matcher.group(2);
Map<String, String> postParameters = new HashMap<>();
postParameters.put("subject", subject);
postParameters.put("message", message);
postParameters.put("creation_time", creationTime);
postParameters.put("form_token", formToken);
postParameters.put("post", "Absenden");
postParameters.put("attach_sig", "1");
postParameters.put("enable_bbcode", "1");
postParameters.put("enable_smilies", "1");
postParameters.put("enable_magic_url", "1");
String postForm = postParameters.entrySet()
.stream()
.map(e -> e.getKey() + "=" + URLEncoder.encode(e.getValue(), StandardCharsets.UTF_8))
.collect(Collectors.joining("&"));
HttpRequest postReq = HttpRequest.newBuilder()
.uri(URI.create(url))
.headers("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString(postForm))
.build();
try {
TimeUnit.SECONDS.sleep(1);
HttpResponse<String> response = client.send(postReq, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 302) {
logger.info("Created post '" + subject + "' in forum " + forumId);
return true;
}
logger.error("Failed to create post '" + subject + "' in forum " + forumId + ". Status: " + response.statusCode());
return false;
} catch (IOException | InterruptedException e) {
logger.error("Failed to create post", e);
return false;
}
}
private String getSidFromCookie() {
HttpCookie sidCookie = cookieStore.getCookies().get(2);
String sid = sidCookie.getValue();
@@ -1,81 +0,0 @@
package de.jeyp91.whatsapp;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.HashMap;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import static de.jeyp91.apifootball.APIFootballConnector.stringToJSONObject;
public class OpenAIConnector {
private final HttpClient client;
private final String OPENAI_TOKEN = System.getenv("OPENAI_TOKEN");
private final String OPENAPI_URL = "https://api.openai.com/v1/chat/completions";
private final String OPENAPI_MODEL = "gpt-5-nano-2025-08-07";
private final HashMap<String, String> generatedMessages = new HashMap<>();
public OpenAIConnector() {
client = HttpClient.newBuilder().build();
}
public String getReminderMessage(WhatsAppReminder reminder) {
String key = reminder.leagueName() + reminder.matchdayName() + reminder.todayTomorrow() + reminder.time();
String message;
if (generatedMessages.containsKey(key)) {
message = generatedMessages.get(key);
} else {
message = executeReminderPrompt(reminder.leagueName(), reminder.matchdayName(), reminder.todayTomorrow(), reminder.time(), reminder.remainingHours());
generatedMessages.put(key, message);
}
message = message.replace("Hey", "Hey " + reminder.username());
String end = "\nDu kannst deine Tipps wie immer unter https://tippliga-wuerzburg.de/app.php/football/bet abgeben.\nViele Grüße\nDie Tippliga Admins";
message += end;
return message;
}
private String executeReminderPrompt(String leagueName, String matchdayName, String deliveryDay, String time, int remainingHours) {
String systemPrompt = "Generiere eine Nachricht, die dem Zweck dient, jemanden daran zu erinnern, seine noch fehlenden Tipps für den kommenden Spieltag abzuschicken. Die Nachricht muss so klingen, als ob ein Freund sie in natürlicher Sprache abschickt. Sie muss auf Deutsch sein. Die Nachricht muss den richtigen Singular und Plural für die Anzahl der fehlenden Wetten verwenden. Halte dich genau an die Vorlage und ersetze die Teile gekennzeichnet durch \"{}\" durch passende Passagen. Die Antwort auf diesen Prompt soll ausschließlich die Nachricht sein.\n\n "
+"Dies ist die Vorlage:\n"
+"Hey,\n"
+ (remainingHours == 24 ? "{ein netter einleitender Satz der \"league_name\", \"matchday_name\" enthält}.\n" : "{ein einleitender Satz der \"league_name\", \"matchday_name\" enthält und klar macht, dass die Zeit abläuft und nur noch weniger als zwei Stunden Zeit für die Abgabe der Tipps bleibt}.\n")
+"Bitte gib die fehlenden Tipps bis {delivery_day} um {time} ab.";
JSONObject userInput = new JSONObject();
userInput.put("league_name", leagueName);
userInput.put("matchday_name", matchdayName);
userInput.put("delivery_day", deliveryDay);
userInput.put("time", time);
String user = userInput.toJSONString();
JSONObject jsonBody = new JSONObject();
jsonBody.put("model", OPENAPI_MODEL);
JSONArray messages = new JSONArray();
JSONObject system = new JSONObject();
system.put("role", "system");
system.put("content", systemPrompt);
messages.add(system);
JSONObject userMessage = new JSONObject();
userMessage.put("role", "user");
userMessage.put("content", user);
messages.add(userMessage);
jsonBody.put("messages", messages);
HttpRequest openAIRequest = HttpRequest.newBuilder()
.uri(URI.create(OPENAPI_URL))
.headers("Content-Type", "application/json")
.headers("Authorization", "Bearer " + OPENAI_TOKEN)
.POST(HttpRequest.BodyPublishers.ofString(jsonBody.toJSONString()))
.build();
JSONObject response = new JSONObject();
try {
response = stringToJSONObject(client.send(openAIRequest, HttpResponse.BodyHandlers.ofString()).body());
} catch (Exception e) {
e.printStackTrace();
}
JSONArray choices = (JSONArray) response.get("choices");
JSONObject choice = (JSONObject) choices.get(0);
JSONObject message = (JSONObject) choice.get("message");
return message.get("content").toString();
}
}
@@ -1,72 +0,0 @@
package de.jeyp91.whatsapp;
import de.jeyp91.tippligaforum.TippligaSQLConnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.json.simple.JSONObject;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.ArrayList;
public class WhatsAppNotifier {
private final String host = System.getenv("TLW_WHATSAPP_HOST");
private final String port = System.getenv("TLW_WHATSAPP_PORT");
private final String apiKey = System.getenv("TLW_WHATSAPP_API_KEY");
private static final Logger logger = LoggerFactory.getLogger(WhatsAppNotifier.class);
private final HttpClient client;
private final OpenAIConnector openAIConnector = new OpenAIConnector();
public WhatsAppNotifier() {
client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.build();
}
public void sendNotifications() {
ArrayList<WhatsAppReminder> reminders = TippligaSQLConnector.getInstance().getNextWhatsAppReminders(24);
reminders.addAll(TippligaSQLConnector.getInstance().getNextWhatsAppReminders(2));
reminders.forEach(reminder -> {
boolean success = sendMessage(reminder);
if (success) {
markReminderAsSent(reminder);
logger.info("WhatsApp Erinnerung an " + reminder.username() + " gesendet.");
} else {
logger.error("WhatsApp Nachricht senden an " + reminder.username() + " fehlgeschlagen.");
}
});
}
public boolean sendMessage(WhatsAppReminder reminder) {
String message = openAIConnector.getReminderMessage(reminder);
JSONObject body = new JSONObject();
body.put("number", reminder.phoneNumber().substring(2));
body.put("message", message);
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create(this.host + (this.port != null ? ":" + this.port : "") + "/send"))
.headers("Content-Type", "application/json")
.headers("x-api-key", apiKey)
.POST(HttpRequest.BodyPublishers.ofString(body.toJSONString()))
.build();
boolean success = false;
try {
int responseCode = client.send(req, HttpResponse.BodyHandlers.ofString()).statusCode();
if (responseCode != 200) {
logger.error("Failed to send WhatsApp message. Response code: " + responseCode);
} else {
success = true;
}
} catch (Exception e) {
logger.error("Failed to send WhatsApp message: " + e.getMessage());
}
return success;
}
public void markReminderAsSent(WhatsAppReminder reminder) {
TippligaSQLConnector.getInstance().markWhatsAppReminderAsSent(reminder);
}
}
@@ -1,16 +0,0 @@
package de.jeyp91.whatsapp;
public record WhatsAppReminder(int season,
int league,
String leagueName,
int matchday,
String matchdayName,
String deliveryDate,
String todayTomorrow,
String time,
int remainingHours,
int userId,
String username,
String phoneNumber,
int missingBets) {
}
+4
View File
@@ -0,0 +1,4 @@
{
"username": "tippligawuerzburg",
"password": "1154f448eae29212971cb82ca8850f54bff23629"
}
@@ -0,0 +1,6 @@
{
"1": {
"id": "825f79shtm9n3uknj99iuu2qho",
"url": "825f79shtm9n3uknj99iuu2qho@group.calendar.google.com"
}
}
@@ -0,0 +1,14 @@
{
"installed": {
"client_id": "267204101826-2ps9m6httllrc7mrsvml50rsfb661k87.apps.googleusercontent.com",
"project_id": "tippliga",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": "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",
"redirect_uris": [
"urn:ietf:wg:oauth:2.0:oob",
"http://localhost"
]
}
}
@@ -93,10 +93,5 @@
"country": "World",
"name": "UEFA Super Cup",
"league_id": 5235
},
{
"country": "World",
"name": "Euro Championship",
"league_id": 5858
}
]
@@ -1,97 +0,0 @@
[
{
"country": "Germany",
"name": "Bundesliga",
"league_id": 6375
},
{
"country": "Germany",
"name": "2. Bundesliga",
"league_id": 6387
},
{
"country": "Germany",
"name": "3. Liga",
"league_id": 6443
},
{
"country": "Germany",
"name": "Regionalliga - Bayern",
"league_id": 6472
},
{
"country": "Germany",
"name": "Regionalliga - SudWest",
"league_id": 6471
},
{
"country": "Germany",
"name": "U19 Bundesliga",
"league_id": 6572
},
{
"country": "Germany",
"name": "Frauen Bundesliga",
"league_id": 6510
},
{
"country": "Germany",
"name": "DFB Pokal",
"league_id": 6244
},
{
"country": "Germany",
"name": "Super Cup",
"league_id": 6247
},
{
"country": "England",
"name": "Premier League",
"league_id": 6280
},
{
"country": "Spain",
"name": "La Liga",
"league_id": 6284
},
{
"country": "Italy",
"name": "Serie A",
"league_id": 6374
},
{
"country": "France",
"name": "Ligue 1",
"league_id": 6315
},
{
"country": "Turkey",
"name": "Süper Lig",
"league_id": 6447
},
{
"country": "Netherlands",
"name": "Eredivisie",
"league_id": 6314
},
{
"country": "World",
"name": "UEFA Champions League",
"league_id": 6281
},
{
"country": "World",
"name": "UEFA Europa League",
"league_id": 6283
},
{
"country": "World",
"name": "UEFA Europa Conference League",
"league_id": 6282
},
{
"country": "World",
"name": "UEFA Super Cup",
"league_id": 6241
}
]
-117
View File
@@ -1,117 +0,0 @@
[
{
"country": "Germany",
"name": "Bundesliga",
"league_id": 78
},
{
"country": "Germany",
"name": "2. Bundesliga",
"league_id": 79
},
{
"country": "Germany",
"name": "3. Liga",
"league_id": 80
},
{
"country": "Germany",
"name": "Regionalliga - Bayern",
"league_id": 83
},
{
"country": "Germany",
"name": "Regionalliga - SudWest",
"league_id": 86
},
{
"country": "Germany",
"name": "U19 Bundesliga",
"league_id": 488
},
{
"country": "Germany",
"name": "Frauen Bundesliga",
"league_id": 82
},
{
"country": "Germany",
"name": "DFB Pokal",
"league_id": 81
},
{
"country": "Germany",
"name": "Super Cup",
"league_id": 529
},
{
"country": "England",
"name": "Premier League",
"league_id": 39
},
{
"country": "Spain",
"name": "La Liga",
"league_id": 140
},
{
"country": "Italy",
"name": "Serie A",
"league_id": 135
},
{
"country": "France",
"name": "Ligue 1",
"league_id": 61
},
{
"country": "Turkey",
"name": "Süper Lig",
"league_id": 203
},
{
"country": "Netherlands",
"name": "Eredivisie",
"league_id": 88
},
{
"country": "Austria",
"name": "Bundesliga",
"league_id": 218
},
{
"country": "Portugal",
"name": "Primeira Liga",
"league_id": 94
},
{
"country": "World",
"name": "UEFA Champions League",
"league_id": 2
},
{
"country": "World",
"name": "UEFA Europa League",
"league_id": 3
},
{
"country": "World",
"name": "UEFA Europa Conference League",
"league_id": 848
},
{
"country": "World",
"name": "UEFA Super Cup",
"league_id": 531
},
{
"country": "World",
"name": "World Cup",
"league_id": 1
},
{
"country": "World",
"name": "Euro Championship",
"league_id": 4
}
]
@@ -1188,390 +1188,5 @@
"teamname": "Girona",
"tippligaID": 648,
"apiFootballID": 547
},
{
"teamname": "PSV Eindhoven",
"tippligaID": 510,
"apiFootballID": 197
},
{
"teamname": "Viktoria Plzen",
"tippligaID": 598,
"apiFootballID": 567
},
{
"teamname": "PAOK Saloniki",
"tippligaID": 579,
"apiFootballID": 619
},
{
"teamname": "Club Brugge KV",
"tippligaID": 462,
"apiFootballID": 569
},
{
"teamname": "FC Toulouse",
"tippligaID": 427,
"apiFootballID": 96
},
{
"teamname": "Stade Brestois 29",
"tippligaID": 649,
"apiFootballID": 106
},
{
"teamname": "Albania",
"tippligaID": 702,
"apiFootballID": 778
},
{
"teamname": "Slovenia",
"tippligaID": 926,
"apiFootballID": 1091
},
{
"teamname": "Serbia",
"tippligaID": 924,
"apiFootballID": 14
},
{
"teamname": "Romania",
"tippligaID": 836,
"apiFootballID": 774
},
{
"teamname": "Georgia",
"tippligaID": 751,
"apiFootballID": 1104
},
{
"teamname": "TuS Koblenz",
"tippligaID": 32,
"apiFootballID": 1648
},
{
"teamname": "Phönix Lübeck",
"tippligaID": 650,
"apiFootballID": 12831
},
{
"teamname": "Alemannia Aachen",
"tippligaID": 7,
"apiFootballID": 4259
},
{
"teamname": "Borussia Hildesheim",
"tippligaID": 651,
"apiFootballID": 12742
},
{
"teamname": "AJ Auxerre",
"tippligaID": 652,
"apiFootballID": 108
},
{
"teamname": "FK Bodø/Glimt",
"tippligaID": 653,
"apiFootballID": 327
},
{
"teamname": "Jagiellonia",
"tippligaID": 654,
"apiFootballID": 336
},
{
"teamname": "Celje",
"tippligaID": 655,
"apiFootballID": 4360
},
{
"teamname": "Legia Warszawa",
"tippligaID": 656,
"apiFootballID": 339
},
{
"teamname": "Djurgardens IF",
"tippligaID": 657,
"apiFootballID": 364
},
{
"teamname": "Rapid Wien",
"tippligaID": 415,
"apiFootballID": 781
},
{
"teamname": "ZFC Meuselwitz",
"tippligaID": 102,
"apiFootballID": 9358
},
{
"teamname": "Bahlinger SC",
"tippligaID": 585,
"apiFootballID": 9359
},
{
"teamname": "SV Hemelingen",
"tippligaID": 658,
"apiFootballID": 12783
},
{
"teamname": "RSV Eintracht",
"tippligaID": 659,
"apiFootballID": 14754
},
{
"teamname": "Sturm Graz",
"tippligaID": 559,
"apiFootballID": 637
},
{
"teamname": "Go Ahead Eagles",
"tippligaID": 660,
"apiFootballID": 410
},
{
"teamname": "Espanyol",
"tippligaID": 572,
"apiFootballID": 540
},
{
"teamname": "Como",
"tippligaID": 661,
"apiFootballID": 895
},
{
"teamname": "Genk",
"tippligaID": 662,
"apiFootballID": 742
},
{
"teamname": "Sigma Olomouc",
"tippligaID": 663,
"apiFootballID": 2250
},
{
"teamname": "AZ Alkmaar",
"tippligaID": 454,
"apiFootballID": 201
},
{
"teamname": "AEK Athens",
"tippligaID": 404,
"apiFootballID": 575
},
{
"teamname": "Mexico",
"tippligaID": 916,
"apiFootballID": 16
},
{
"teamname": "South Africa",
"tippligaID": 928,
"apiFootballID": 1531
},
{
"teamname": "South Korea",
"tippligaID": 929,
"apiFootballID": 17
},
{
"teamname": "Canada",
"tippligaID": 664,
"apiFootballID": 5529
},
{
"teamname": "Bosnia & Herzegovina",
"tippligaID": 724,
"apiFootballID": 1113
},
{
"teamname": "USA",
"tippligaID": 931,
"apiFootballID": 2384
},
{
"teamname": "Paraguay",
"tippligaID": 921,
"apiFootballID": 2380
},
{
"teamname": "Qatar",
"tippligaID": 665,
"apiFootballID": 1569
},
{
"teamname": "Brazil",
"tippligaID": 903,
"apiFootballID": 6
},
{
"teamname": "Morocco",
"tippligaID": 707,
"apiFootballID": 31
},
{
"teamname": "Haiti",
"tippligaID": 666,
"apiFootballID": 2386
},
{
"teamname": "Australia",
"tippligaID": 902,
"apiFootballID": 20
},
{
"teamname": "New Zealand",
"tippligaID": 917,
"apiFootballID": 4673
},
{
"teamname": "Ghana",
"tippligaID": 910,
"apiFootballID": 1504
},
{
"teamname": "Panama",
"tippligaID": 705,
"apiFootballID": 11
},
{
"teamname": "Colombia",
"tippligaID": 938,
"apiFootballID": 8
},
{
"teamname": "Congo DR",
"tippligaID": 667,
"apiFootballID": 1508
},
{
"teamname": "Uzbekistan",
"tippligaID": 668,
"apiFootballID": 1568
},
{
"teamname": "Algeria",
"tippligaID": 900,
"apiFootballID": 1532
},
{
"teamname": "Jordan",
"tippligaID": 669,
"apiFootballID": 1548
},
{
"teamname": "Argentina",
"tippligaID": 901,
"apiFootballID": 26
},
{
"teamname": "Senegal",
"tippligaID": 708,
"apiFootballID": 13
},
{
"teamname": "Iraq",
"tippligaID": 670,
"apiFootballID": 1567
},
{
"teamname": "Norway",
"tippligaID": 823,
"apiFootballID": 1090
},
{
"teamname": "Uruguay",
"tippligaID": 930,
"apiFootballID": 7
},
{
"teamname": "Cape Verde Islands",
"tippligaID": 671,
"apiFootballID": 1533
},
{
"teamname": "Saudi Arabia",
"tippligaID": 703,
"apiFootballID": 23
},
{
"teamname": "Egypt",
"tippligaID": 706,
"apiFootballID": 32
},
{
"teamname": "Iran",
"tippligaID": 937,
"apiFootballID": 22
},
{
"teamname": "Ecuador",
"tippligaID": 934,
"apiFootballID": 2382
},
{
"teamname": "Curaçao",
"tippligaID": 672,
"apiFootballID": 5530
},
{
"teamname": "Ivory Coast",
"tippligaID": 907,
"apiFootballID": 1501
},
{
"teamname": "Japan",
"tippligaID": 914,
"apiFootballID": 12
},
{
"teamname": "Tunisia",
"tippligaID": 710,
"apiFootballID": 28
},
{
"teamname": "SC St. Tönis",
"tippligaID": 673,
"apiFootballID": 19466
},
{
"teamname": "Lüneburger SK Hansa",
"tippligaID": 76,
"apiFootballID": 1645
},
{
"teamname": "Eintracht Trier",
"tippligaID": 46,
"apiFootballID": 1627
},
{
"teamname": "SSV Jeddeloh",
"tippligaID": 124,
"apiFootballID": 1655
},
{
"teamname": "Krieschow",
"tippligaID": 675,
"apiFootballID": 14713
},
{
"teamname": "Westfalia Rhynern",
"tippligaID": 676,
"apiFootballID": 14826
},
{
"teamname": "HEBC",
"tippligaID": 677,
"apiFootballID": 16078
},
{
"teamname": "Fortuna Köln",
"tippligaID": 583,
"apiFootballID": 1326
},
{
"teamname": "NEXT TEAM",
"tippligaID": 674,
"apiFootballID": 9999999
}
]
]
@@ -31,7 +31,7 @@
},
{
"team_id": 2058,
"team_name": "Nicole",
"team_name": "Nicole (TG Rhön)",
"team_name_short": "Nicole"
},
{
@@ -278,20 +278,5 @@
"team_id": 2137,
"team_name": "Johannes",
"team_name_short": "Johannes"
},
{
"team_id": 2138,
"team_name": "TG ChatGPT",
"team_name_short": "ChatGPT"
},
{
"team_id": 2139,
"team_name": "Dustin",
"team_name_short": "Dustin"
},
{
"team_id": 2140,
"team_name": "Marcel W.",
"team_name_short": "Marcel W."
}
]
@@ -1,114 +0,0 @@
{
"numberOfMatchdays": 5,
"matchesPerMatchday": 0,
"pointMode": 4,
"pointsTendency": 1,
"pointsDifference": 2,
"pointsDirectHit": 3,
"ko": 1,
"matchdayConfig": [
{
"TLWMatchday": 1,
"matchdayName": "1. Runde",
"numberOfMatches": 32,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 5275,
"leagueMatchday": 1,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2022-07-29 20:45:00"
}
]
},
{
"TLWMatchday": 2,
"numberOfMatches": 12,
"matchdayName": "2. Spieltag",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 5275,
"leagueMatchday": 2,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2022-10-18 18:30:00"
}
]
},
{
"TLWMatchday": 3,
"numberOfMatches": 12,
"matchdayName": "3. Spieltag",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 5275,
"leagueMatchday": 3,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2023-01-31 18:30:00"
}
]
},
{
"TLWMatchday": 4,
"numberOfMatches": 8,
"matchdayName": "Achtelfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 5275,
"leagueMatchday": 4,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2023-04-04 18:30:00"
}
]
},
{
"TLWMatchday": 5,
"numberOfMatches": 4,
"matchdayName": "Viertelfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 5275,
"leagueMatchday": 5,
"showTable": true
},
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 5275,
"leagueMatchday": 5,
"showTable": true
},
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 5275,
"leagueMatchday": 6,
"showTable": true
},
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 5275,
"leagueMatchday": 6,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2023-05-02 20:45:00"
}
]
}
]
}
@@ -1,118 +0,0 @@
{
"numberOfMatchdays": 5,
"matchesPerMatchday": 0,
"pointMode": 4,
"pointsTendency": 1,
"pointsDifference": 2,
"pointsDirectHit": 3,
"ko": 1,
"matchdayConfig": [
{
"TLWMatchday": 1,
"matchdayName": "1. Runde",
"numberOfMatches": 32,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 5858,
"leagueMatchday": 1,
"showTable": true
}
]
},
{
"TLWMatchday": 2,
"numberOfMatches": 12,
"matchdayName": "2. Spieltag",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 5858,
"leagueMatchday": 2,
"showTable": true
}
]
},
{
"TLWMatchday": 3,
"numberOfMatches": 12,
"matchdayName": "3. Spieltag",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 5858,
"leagueMatchday": 3,
"showTable": true
}
]
},
{
"TLWMatchday": 4,
"numberOfMatches": 8,
"matchdayName": "Achtelfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 5858,
"leagueMatchday": 4,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2024-06-29 18:00:00"
}
]
},
{
"TLWMatchday": 5,
"numberOfMatches": 4,
"matchdayName": "Viertelfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 5858,
"leagueMatchday": 5,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2024-07-05 18:00:00"
}
]
},
{
"TLWMatchday": 6,
"numberOfMatches": 2,
"matchdayName": "Halbfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 5858,
"leagueMatchday": 6,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2024-07-09 21:00:00"
}
]
},
{
"TLWMatchday": 7,
"numberOfMatches": 1,
"matchdayName": "Finale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 5858,
"leagueMatchday": 7,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2024-07-14 21:00:00"
}
]
}
]
}
@@ -1,435 +0,0 @@
{
"numberOfMatchdays": 39,
"matchesPerMatchday": 12,
"pointMode": 4,
"pointsTendency": 1,
"pointsDifference": 2,
"pointsDirectHit": 3,
"ko": 0,
"matchdayConfig": [
{
"TLWMatchday": 1,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6387,
"leagueMatchday": 1,
"showTable": false
}
]
},
{
"TLWMatchday": 2,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6387,
"leagueMatchday": 2,
"showTable": false
}
]
},
{
"TLWMatchday": 3,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 1,
"showTable": true
}
]
},
{
"TLWMatchday": 4,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 2,
"showTable": true
}
]
},
{
"TLWMatchday": 5,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 3,
"showTable": true
}
]
},
{
"TLWMatchday": 6,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 4,
"showTable": true
}
]
},
{
"TLWMatchday": 7,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 5,
"showTable": true
}
]
},
{
"TLWMatchday": 8,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 6,
"showTable": true
}
]
},
{
"TLWMatchday": 9,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 7,
"showTable": true
}
]
},
{
"TLWMatchday": 10,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 8,
"showTable": true
}
]
},
{
"TLWMatchday": 11,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 9,
"showTable": true
}
]
},
{
"TLWMatchday": 12,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 10,
"showTable": true
}
]
},
{
"TLWMatchday": 13,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 11,
"showTable": true
}
]
},
{
"TLWMatchday": 14,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 12,
"showTable": true
}
]
},
{
"TLWMatchday": 15,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 13,
"showTable": true
}
]
},
{
"TLWMatchday": 16,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 14,
"showTable": true
}
]
},
{
"TLWMatchday": 17,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 15,
"showTable": true
}
]
},
{
"TLWMatchday": 18,
"matchesConfig": [
{
"type": "Placeholder",
"placeholderDatetime": "2024-12-26 18:00:00"
}
]
},
{
"TLWMatchday": 19,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 16,
"showTable": true
}
]
},
{
"TLWMatchday": 20,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 17,
"showTable": true
}
]
},
{
"TLWMatchday": 21,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 18,
"showTable": true
}
]
},
{
"TLWMatchday": 22,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 19,
"showTable": true
}
]
},
{
"TLWMatchday": 23,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 20,
"showTable": true
}
]
},
{
"TLWMatchday": 24,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 21,
"showTable": true
}
]
},
{
"TLWMatchday": 25,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 22,
"showTable": true
}
]
},
{
"TLWMatchday": 26,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 23,
"showTable": true
}
]
},
{
"TLWMatchday": 27,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 24,
"showTable": true
}
]
},
{
"TLWMatchday": 28,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 25,
"showTable": true
}
]
},
{
"TLWMatchday": 29,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 26,
"showTable": true
}
]
},
{
"TLWMatchday": 30,
"matchesConfig": [
{
"type": "Placeholder",
"placeholderDatetime": "2025-03-18 18:00:00"
}
]
},
{
"TLWMatchday": 31,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 27,
"showTable": true
}
]
},
{
"TLWMatchday": 32,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 28,
"showTable": true
}
]
},
{
"TLWMatchday": 33,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 29,
"showTable": true
}
]
},
{
"TLWMatchday": 34,
"matchesConfig": [
{
"type": "Placeholder",
"placeholderDatetime": "2025-04-15 18:00:00"
}
]
},
{
"TLWMatchday": 35,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 30,
"showTable": true
}
]
},
{
"TLWMatchday": 36,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 31,
"showTable": true
}
]
},
{
"TLWMatchday": 37,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 32,
"showTable": true
}
]
},
{
"TLWMatchday": 38,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 33,
"showTable": true
}
]
},
{
"TLWMatchday": 39,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6375,
"leagueMatchday": 34,
"showTable": true
}
]
}
]
}
File diff suppressed because it is too large Load Diff
@@ -1,152 +0,0 @@
{
"numberOfMatchdays": 5,
"matchesPerMatchday": 0,
"pointMode": 4,
"pointsTendency": 1,
"pointsDifference": 2,
"pointsDirectHit": 3,
"ko": 1,
"matchdayConfig": [
{
"TLWMatchday": 1,
"matchdayName": "1. Runde",
"numberOfMatches": 32,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6244,
"leagueMatchday": 1,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2024-08-16 18:00:00"
}
]
},
{
"TLWMatchday": 2,
"numberOfMatches": 16,
"matchdayName": "Achtelfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6244,
"leagueMatchday": 2,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2024-10-29 18:00:00"
}
]
},
{
"TLWMatchday": 3,
"numberOfMatches": 8,
"matchdayName": "Viertelfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6244,
"leagueMatchday": 3,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2024-12-03 18:30:00"
}
]
},
{
"TLWMatchday": 4,
"numberOfMatches": 4,
"matchdayName": "Halbfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6244,
"leagueMatchday": 4,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2025-02-04 18:30:00"
}
]
},
{
"TLWMatchday": 5,
"numberOfMatches": 6,
"matchdayName": "Finale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6244,
"leagueMatchday": 5,
"showTable": true
},
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6244,
"leagueMatchday": 5,
"showTable": true
},
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6244,
"leagueMatchday": 6,
"showTable": true
},
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 6244,
"leagueMatchday": 6,
"showTable": true
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2025-04-01 20:45:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2025-04-02 20:45:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2025-04-01 20:45:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2025-04-02 20:45:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2025-05-24 20:00:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2025-05-24 20:00:00",
"formulaHome": "D",
"formulaGuest": "D"
}
]
}
]
}
@@ -1,152 +0,0 @@
{
"numberOfMatchdays": 5,
"matchesPerMatchday": 0,
"pointMode": 4,
"pointsTendency": 1,
"pointsDifference": 2,
"pointsDirectHit": 3,
"ko": 1,
"matchdayConfig": [
{
"TLWMatchday": 1,
"matchdayName": "1. Runde",
"numberOfMatches": 32,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 1,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2024-08-16 18:00:00"
}
]
},
{
"TLWMatchday": 2,
"numberOfMatches": 16,
"matchdayName": "Achtelfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 2,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2024-10-29 18:00:00"
}
]
},
{
"TLWMatchday": 3,
"numberOfMatches": 8,
"matchdayName": "Viertelfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 3,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2024-12-03 18:30:00"
}
]
},
{
"TLWMatchday": 4,
"numberOfMatches": 4,
"matchdayName": "Halbfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 4,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2025-02-04 18:30:00"
}
]
},
{
"TLWMatchday": 5,
"numberOfMatches": 6,
"matchdayName": "Finale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 5,
"showTable": true
},
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 5,
"showTable": true
},
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 6,
"showTable": true
},
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 6,
"showTable": true
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2025-04-01 20:45:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2025-04-02 20:45:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2025-04-01 20:45:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2025-04-02 20:45:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2025-05-24 20:00:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2025-05-24 20:00:00",
"formulaHome": "D",
"formulaGuest": "D"
}
]
}
]
}
@@ -1,135 +0,0 @@
{
"numberOfMatchdays": 8,
"matchesPerMatchday": 0,
"pointMode": 4,
"pointsTendency": 1,
"pointsDifference": 2,
"pointsDirectHit": 3,
"ko": 1,
"matchdayConfig": [
{
"TLWMatchday": 1,
"numberOfMatches": 24,
"matchdayName": "1. Spieltag",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 1,
"leagueMatchday": 1,
"showTable": true
}
]
},
{
"TLWMatchday": 2,
"numberOfMatches": 24,
"matchdayName": "2. Spieltag",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 1,
"leagueMatchday": 2,
"showTable": true
}
]
},
{
"TLWMatchday": 3,
"numberOfMatches": 24,
"matchdayName": "3. Spieltag",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 1,
"leagueMatchday": 3,
"showTable": true
}
]
},
{
"TLWMatchday": 4,
"numberOfMatches": 16,
"matchdayName": "Sechzentelfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 1,
"leagueMatchday": 4,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2026-06-28 21:00:00"
}
]
},
{
"TLWMatchday": 5,
"numberOfMatches": 8,
"matchdayName": "Achtelfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 1,
"leagueMatchday": 5,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2026-07-04 19:00:00"
}
]
},
{
"TLWMatchday": 6,
"numberOfMatches": 4,
"matchdayName": "Viertelfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 1,
"leagueMatchday": 6,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2026-07-09 22:00:00"
}
]
},
{
"TLWMatchday": 7,
"numberOfMatches": 2,
"matchdayName": "Halbfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 1,
"leagueMatchday": 7,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2026-07-14 21:00:00"
}
]
},
{
"TLWMatchday": 8,
"numberOfMatches": 2,
"matchdayName": "Finale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 1,
"leagueMatchday": 8,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2026-07-18 23:00:00"
}
]
}
]
}
@@ -1,434 +0,0 @@
{
"numberOfMatchdays": 39,
"matchesPerMatchday": 12,
"pointMode": 4,
"pointsTendency": 1,
"pointsDifference": 2,
"pointsDirectHit": 3,
"ko": 0,
"matchdayConfig": [
{
"TLWMatchday": 1,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 79,
"leagueMatchday": 1,
"showTable": false
}
]
},
{
"TLWMatchday": 2,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 79,
"leagueMatchday": 2,
"showTable": false
}
]
},
{
"TLWMatchday": 3,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 1,
"showTable": true
}
]
},
{
"TLWMatchday": 4,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 2,
"showTable": true
}
]
},
{
"TLWMatchday": 5,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 3,
"showTable": true
}
]
},
{
"TLWMatchday": 6,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 4,
"showTable": true
}
]
},
{
"TLWMatchday": 7,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 5,
"showTable": true
}
]
},
{
"TLWMatchday": 8,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 6,
"showTable": true
}
]
},
{
"TLWMatchday": 9,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 7,
"showTable": true
}
]
},
{
"TLWMatchday": 10,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 8,
"showTable": true
}
]
},
{
"TLWMatchday": 11,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 9,
"showTable": true
}
]
},
{
"TLWMatchday": 12,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 10,
"showTable": true
}
]
},
{
"TLWMatchday": 13,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 11,
"showTable": true
}
]
},
{
"TLWMatchday": 14,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 12,
"showTable": true
}
]
},
{
"TLWMatchday": 15,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 13,
"showTable": true
}
]
},
{
"TLWMatchday": 16,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 14,
"showTable": true
}
]
},
{
"TLWMatchday": 17,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 15,
"showTable": true
}
]
},
{
"TLWMatchday": 18,
"matchesConfig": [
{
"type": "Placeholder",
"placeholderDatetime": "2025-12-26 18:00:00"
}
]
},
{
"TLWMatchday": 19,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 16,
"showTable": true
}
]
},
{
"TLWMatchday": 20,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 17,
"showTable": true
}
]
},
{
"TLWMatchday": 21,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 18,
"showTable": true
}
]
},
{
"TLWMatchday": 22,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 19,
"showTable": true
}
]
},
{
"TLWMatchday": 23,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 20,
"showTable": true
}
]
},
{
"TLWMatchday": 24,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 21,
"showTable": true
}
]
},
{
"TLWMatchday": 25,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 22,
"showTable": true
}
]
},
{
"TLWMatchday": 26,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 23,
"showTable": true
}
]
},
{
"TLWMatchday": 27,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 24,
"showTable": true
}
]
},
{
"TLWMatchday": 28,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 25,
"showTable": true
}
]
},
{
"TLWMatchday": 29,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 26,
"showTable": true
}
]
},
{
"TLWMatchday": 30,
"matchesConfig": [
{
"type": "Placeholder",
"placeholderDatetime": "2026-03-17 18:00:00"
}
]
},
{
"TLWMatchday": 31,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 27,
"showTable": true
}
]
},
{
"TLWMatchday": 32,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 28,
"showTable": true
}
]
},
{
"TLWMatchday": 33,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 29,
"showTable": true
}
]
},
{
"TLWMatchday": 34,
"matchesConfig": [
{
"type": "Placeholder",
"placeholderDatetime": "2026-04-14 18:00:00"
}
]
},
{
"TLWMatchday": 35,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 30,
"showTable": true
}
]
},
{
"TLWMatchday": 36,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 31,
"showTable": true
}
]
},
{
"TLWMatchday": 37,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 32,
"showTable": true
}
]
},
{
"TLWMatchday": 38,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 33,
"showTable": true
}
]
},
{
"TLWMatchday": 39,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 34,
"showTable": true
}
]
}
]
}
@@ -1,11 +0,0 @@
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2026, 1, '1. Tippliga Würzburg', '1TL', 1, 39, 12, '0', '0', '0', '0', 4, 3, 1, 2, 0, 0, 0, 0, 561, 0, 1, 0.00, 0);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2026, 2, '2. Tippliga Würzburg', '2TL', 1, 39, 12, '0', '0', '0', '0', 4, 3, 1, 2, 0, 0, 0, 0, 561, 0, 1, 0.00, 0);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2026, 45, 'Supercup', 'SC', 2, 1, 0, '0', '0', '0', '0', 4, 3, 1, 2, 0, 0, 0, 1, 561, 0, 1, 0.00, 0);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2026, 47, 'Relegation', 'REL', 2, 1, 0, '0', '0', '0', '0', 4, 3, 1, 2, 0, 0, 0, 1, 561, 0, 1, 0.00, 1);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2026, 48, 'WTL-Pokal', 'WTL', 2, 5, 0, '0', '0', '0', '0', 4, 3, 1, 2, 0, 0, 0, 0, 561, 0, 1, 0.00, 0);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2026, 49, 'WM-Tippspiel', 'EM', 2, 7, 0, '0', '0', '0', '0', 4, 3, 1, 2, 0, 0, 0, 0, 0, 0, 1, 0.00, 1);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2026, 51, '1. Tippliga Würzburg', '1TL', 1, 39, 7, '0', '0', '0', '0', 1, 0, 0, 0, 1, 0, 0, 0, 561, 0, 1, 0.00, 0);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2026, 52, '2. Tippliga Würzburg', '2TL', 1, 39, 7, '0', '0', '0', '0', 1, 0, 0, 0, 1, 0, 0, 0, 561, 0, 1, 0.00, 0);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2026, 95, 'Supercup', 'SC', 2, 2, 0, '0', '0', '0', '0', 1, 0, 0, 0, 1, 0, 0, 0, 561, 0, 1, 0.00, 0);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2026, 97, 'Relegation', 'REL', 2, 1, 0, '0', '0', '0', '0', 1, 0, 0, 0, 1, 0, 0, 0, 561, 0, 1, 0.00, 0);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2026, 98, 'WTL-Pokal', 'WTL', 2, 6, 0, '0', '0', '0', '0', 1, 0, 0, 0, 1, 0, 0, 0, 561, 0, 1, 0.00, 0);
@@ -1,152 +0,0 @@
{
"numberOfMatchdays": 5,
"matchesPerMatchday": 0,
"pointMode": 4,
"pointsTendency": 1,
"pointsDifference": 2,
"pointsDirectHit": 3,
"ko": 1,
"matchdayConfig": [
{
"TLWMatchday": 1,
"matchdayName": "1. Runde",
"numberOfMatches": 32,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 1,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2025-08-15 18:00:00"
}
]
},
{
"TLWMatchday": 2,
"numberOfMatches": 16,
"matchdayName": "Achtelfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 2,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2025-10-28 18:00:00"
}
]
},
{
"TLWMatchday": 3,
"numberOfMatches": 8,
"matchdayName": "Viertelfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 3,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2025-12-02 18:30:00"
}
]
},
{
"TLWMatchday": 4,
"numberOfMatches": 4,
"matchdayName": "Halbfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 4,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2026-02-03 18:30:00"
}
]
},
{
"TLWMatchday": 5,
"numberOfMatches": 6,
"matchdayName": "Finale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 5,
"showTable": true
},
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 5,
"showTable": true
},
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 6,
"showTable": true
},
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 6,
"showTable": true
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2026-04-21 20:45:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2026-04-21 20:45:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2026-04-22 20:45:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2026-04-22 20:45:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2026-05-23 20:00:00",
"formulaHome": "W 61",
"formulaGuest": "W 63"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2026-05-23 20:00:00",
"formulaHome": "W 62",
"formulaGuest": "W 64"
}
]
}
]
}
@@ -1,58 +0,0 @@
{
"numberOfMatchdays": 1,
"matchesPerMatchday": 4,
"pointMode": 4,
"pointsTendency": 1,
"pointsDifference": 2,
"pointsDirectHit": 3,
"ko": 1,
"matchdayConfig": [
{
"TLWMatchday": 1,
"matchdayName": "Relegation",
"numberOfMatches": 4,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 35,
"showTable": true
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2027-05-27 20:30:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2027-05-31 20:30:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 79,
"leagueMatchday": 35,
"showTable": true
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2027-05-28 20:30:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2027-06-01 20:30:00",
"formulaHome": "D",
"formulaGuest": "D"
}
]
}
]
}
@@ -1,54 +0,0 @@
{
"numberOfMatchdays": 2,
"matchesPerMatchday": 4,
"pointMode": 4,
"pointsTendency": 1,
"pointsDifference": 2,
"pointsDirectHit": 3,
"ko": 1,
"matchdayConfig": [
{
"TLWMatchday": 1,
"matchdayName": "Supercup",
"numberOfMatches": 4,
"matchesConfig": [
{
"matchday": 1,
"matchtime": "2026-08-22 20:30",
"match": "Borussia Dortmund - Bayern München",
"showTable": false,
"matchLeague": 529,
"type": "SingleMatch",
"matchId": 1582362
},
{
"matchday": 1,
"matchtime": "2026-08-22 20:30",
"match": "Borussia Dortmund - Bayern München",
"showTable": false,
"matchLeague": 529,
"type": "SingleMatch",
"matchId": 1582362
},
{
"matchday": 1,
"matchtime": "2026-08-12 21:00",
"match": "Paris Saint Germain - Aston Villa",
"showTable": false,
"matchLeague": 531,
"type": "SingleMatch",
"matchId": 1583664
},
{
"matchday": 1,
"matchtime": "2026-08-12 21:00",
"match": "Paris Saint Germain - Aston Villa",
"showTable": false,
"matchLeague": 531,
"type": "SingleMatch",
"matchId": 1583664
}
]
}
]
}
@@ -1,4 +0,0 @@
{
"1": "Sascha",
"2": "Stefan"
}
@@ -1,434 +0,0 @@
{
"numberOfMatchdays": 39,
"matchesPerMatchday": 12,
"pointMode": 4,
"pointsTendency": 1,
"pointsDifference": 2,
"pointsDirectHit": 3,
"ko": 0,
"matchdayConfig": [
{
"TLWMatchday": 1,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 79,
"leagueMatchday": 1,
"showTable": false
}
]
},
{
"TLWMatchday": 2,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 79,
"leagueMatchday": 2,
"showTable": false
}
]
},
{
"TLWMatchday": 3,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 1,
"showTable": true
}
]
},
{
"TLWMatchday": 4,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 2,
"showTable": true
}
]
},
{
"TLWMatchday": 5,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 3,
"showTable": true
}
]
},
{
"TLWMatchday": 6,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 4,
"showTable": true
}
]
},
{
"TLWMatchday": 7,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 5,
"showTable": true
}
]
},
{
"TLWMatchday": 8,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 6,
"showTable": true
}
]
},
{
"TLWMatchday": 9,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 7,
"showTable": true
}
]
},
{
"TLWMatchday": 10,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 8,
"showTable": true
}
]
},
{
"TLWMatchday": 11,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 9,
"showTable": true
}
]
},
{
"TLWMatchday": 12,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 10,
"showTable": true
}
]
},
{
"TLWMatchday": 13,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 11,
"showTable": true
}
]
},
{
"TLWMatchday": 14,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 12,
"showTable": true
}
]
},
{
"TLWMatchday": 15,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 13,
"showTable": true
}
]
},
{
"TLWMatchday": 16,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 14,
"showTable": true
}
]
},
{
"TLWMatchday": 17,
"matchesConfig": [
{
"type": "Placeholder",
"placeholderDatetime": "2026-12-26 18:00:00"
}
]
},
{
"TLWMatchday": 18,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 15,
"showTable": true
}
]
},
{
"TLWMatchday": 19,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 16,
"showTable": true
}
]
},
{
"TLWMatchday": 20,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 17,
"showTable": true
}
]
},
{
"TLWMatchday": 21,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 18,
"showTable": true
}
]
},
{
"TLWMatchday": 22,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 19,
"showTable": true
}
]
},
{
"TLWMatchday": 23,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 20,
"showTable": true
}
]
},
{
"TLWMatchday": 24,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 21,
"showTable": true
}
]
},
{
"TLWMatchday": 25,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 22,
"showTable": true
}
]
},
{
"TLWMatchday": 26,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 23,
"showTable": true
}
]
},
{
"TLWMatchday": 27,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 24,
"showTable": true
}
]
},
{
"TLWMatchday": 28,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 25,
"showTable": true
}
]
},
{
"TLWMatchday": 29,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 26,
"showTable": true
}
]
},
{
"TLWMatchday": 30,
"matchesConfig": [
{
"type": "Placeholder",
"placeholderDatetime": "2027-03-17 18:00:00"
}
]
},
{
"TLWMatchday": 31,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 27,
"showTable": true
}
]
},
{
"TLWMatchday": 32,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 28,
"showTable": true
}
]
},
{
"TLWMatchday": 33,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 29,
"showTable": true
}
]
},
{
"TLWMatchday": 34,
"matchesConfig": [
{
"type": "Placeholder",
"placeholderDatetime": "2027-04-14 18:00:00"
}
]
},
{
"TLWMatchday": 35,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 30,
"showTable": true
}
]
},
{
"TLWMatchday": 36,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 31,
"showTable": true
}
]
},
{
"TLWMatchday": 37,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 32,
"showTable": true
}
]
},
{
"TLWMatchday": 38,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 33,
"showTable": true
}
]
},
{
"TLWMatchday": 39,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 78,
"leagueMatchday": 34,
"showTable": true
}
]
}
]
}
@@ -1,16 +0,0 @@
{
"1": "Flo",
"2": "Michael",
"3": "Demian",
"4": "Sascha",
"5": "Maxi Z.",
"6": "Julian",
"7": "Dustin",
"8": "Kay",
"9": "Lukas",
"10": "Marcel U.",
"11": "TG Nürnberg",
"12": "Nicole",
"13": "Franz",
"14": "Tristan"
}
@@ -1,16 +0,0 @@
{
"1": "Philipp",
"2": "Marcel",
"3": "Matthias",
"4": "Max",
"5": "Marcel W.",
"6": "Friedrich",
"7": "Stefan",
"8": "Armin",
"9": "Barb",
"10": "Hilde",
"11": "Olli L.",
"12": "Jimmy",
"13": "Johannes",
"14": "Patrick"
}
@@ -1,10 +0,0 @@
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2027, 1, '1. Tippliga Würzburg', '1TL', 1, 39, 12, '0', '0', '0', '0', 4, 3, 1, 2, 0, 0, 0, 0, 561, 0, 1, 0.00, 0);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2027, 2, '2. Tippliga Würzburg', '2TL', 1, 39, 12, '0', '0', '0', '0', 4, 3, 1, 2, 0, 0, 0, 0, 561, 0, 1, 0.00, 0);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2027, 45, 'Supercup', 'SC', 2, 1, 0, '0', '0', '0', '0', 4, 3, 1, 2, 0, 0, 0, 1, 561, 0, 1, 0.00, 0);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2027, 47, 'Relegation', 'REL', 2, 1, 0, '0', '0', '0', '0', 4, 3, 1, 2, 0, 0, 0, 1, 561, 0, 1, 0.00, 1);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2027, 48, 'WTL-Pokal', 'WTL', 2, 5, 0, '0', '0', '0', '0', 4, 3, 1, 2, 0, 0, 0, 0, 561, 0, 1, 0.00, 0);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2027, 51, '1. Tippliga Würzburg', '1TL', 1, 39, 7, '0', '0', '0', '0', 1, 0, 0, 0, 1, 0, 0, 0, 561, 0, 1, 0.00, 0);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2027, 52, '2. Tippliga Würzburg', '2TL', 1, 39, 7, '0', '0', '0', '0', 1, 0, 0, 0, 1, 0, 0, 0, 561, 0, 1, 0.00, 0);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2027, 95, 'Supercup', 'SC', 2, 2, 0, '0', '0', '0', '0', 1, 0, 0, 0, 1, 0, 0, 0, 561, 0, 1, 0.00, 0);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2027, 97, 'Relegation', 'REL', 2, 1, 0, '0', '0', '0', '0', 1, 0, 0, 0, 1, 0, 0, 0, 561, 0, 1, 0.00, 0);
INSERT INTO `phpbb_footb_leagues` (`season`, `league`, `league_name`, `league_name_short`, `league_type`, `matchdays`, `matches_on_matchday`, `win_result`, `win_result_02`, `win_matchday`, `win_season`, `points_mode`, `points_result`, `points_tendency`, `points_diff`, `points_last`, `join_by_user`, `join_in_season`, `bet_in_time`, `rules_post_id`, `sort`, `bet_ko_type`, `bet_points`, `bet_type`) VALUES (2027, 98, 'WTL-Pokal', 'WTL', 2, 6, 0, '0', '0', '0', '0', 1, 0, 0, 0, 1, 0, 0, 0, 561, 0, 1, 0.00, 0);
@@ -1,152 +0,0 @@
{
"numberOfMatchdays": 5,
"matchesPerMatchday": 0,
"pointMode": 4,
"pointsTendency": 1,
"pointsDifference": 2,
"pointsDirectHit": 3,
"ko": 1,
"matchdayConfig": [
{
"TLWMatchday": 1,
"matchdayName": "1. Runde",
"numberOfMatches": 32,
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 1,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2026-08-21 18:00:00"
}
]
},
{
"TLWMatchday": 2,
"numberOfMatches": 16,
"matchdayName": "Achtelfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 2,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2026-10-27 18:00:00"
}
]
},
{
"TLWMatchday": 3,
"numberOfMatches": 8,
"matchdayName": "Viertelfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 3,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2026-12-01 18:30:00"
}
]
},
{
"TLWMatchday": 4,
"numberOfMatches": 4,
"matchdayName": "Halbfinale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 4,
"showTable": true
},
{
"type": "Placeholder",
"placeholderDatetime": "2027-02-02 18:30:00"
}
]
},
{
"TLWMatchday": 5,
"numberOfMatches": 6,
"matchdayName": "Finale",
"matchesConfig": [
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 5,
"showTable": true
},
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 5,
"showTable": true
},
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 6,
"showTable": true
},
{
"type": "AllMatchesOfMatchday",
"matchesLeague": 81,
"leagueMatchday": 6,
"showTable": true
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2027-04-20 20:45:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2027-04-20 20:45:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2027-04-21 20:45:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2027-04-21 20:45:00",
"formulaHome": "D",
"formulaGuest": "D"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2027-05-29 20:00:00",
"formulaHome": "W 61",
"formulaGuest": "W 63"
},
{
"type": "PlaceholderSingleMatch",
"koMatch": true,
"placeholderDatetime": "2027-05-29 20:00:00",
"formulaHome": "W 62",
"formulaGuest": "W 64"
}
]
}
]
}
@@ -1,26 +0,0 @@
{
"1": "Matthias",
"2": "Marcel U.",
"3": "Marcel",
"4": "Dustin",
"5": "Johannes",
"6": "Tristan",
"7": "Philipp",
"8": "Nicole",
"9": "Barb",
"10": "TG Nürnberg",
"11": "Marcel W.",
"12": "Maxi Z.",
"13": "Olli L.",
"14": "Lukas",
"15": "Jimmy",
"16": "Franz",
"17": "Armin",
"18": "Demian",
"19": "Hilde",
"20": "Kay",
"21": "Patrick",
"22": "Flo",
"23": "Stefan",
"24": "Max"
}
@@ -1,2 +0,0 @@
UPDATE phpbb_footb_matchdays SET status = 0 WHERE season = 2027 AND status > 0;
UPDATE phpbb_footb_matches SET status = 0 WHERE season = 2027 AND status > 0;
@@ -0,0 +1,12 @@
{
"type": "service_account",
"project_id": "tippliga",
"private_key_id": "4e0def9ef4474114744a1fcaffae9e75689a8909",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDaJeiT0eCLSq6l\nfjvNxE9EnHtFxvWdJOx2CsIXvBJKA7u1b95uHSNQmmunJPMstMLvTRYYYVpJWUm0\njqLd4VGUDqjXuWcNQpn62TFLSGQs8bTwIYoYsAnTWC+kuG5iSaKKzw9UiKFx0Mxv\nLAm5CjqYb87E2pz+7ihCYfaMkpppwPhz8bUbQ+iHdo85cQBcZeVpjuL+W4KT89yV\nZxsV4dGJNabLLEznA1WyhS+pGz+3N9edfANyREthrxm1cyytd3omQ/pfIl7KpGlU\nIq4eDMzlPftn+Nq9S7UfTXzxcv9Ez2cdlGMSSSbpjQBYXNEewnzXutFqfK9h2STD\nM0XaqGh9AgMBAAECggEAAzMrOWAmI8zsUmcPYANG6WMgp6NVhcV46zEP/iTroVRg\nwr+r8bJWOJj+IjCgq4hQ09a3KyYGtlXwRrrH5HPyQyTAnqLjZtZ/3lzblm2TYJmJ\nwzwcbO1+skJCAF2Dxmxh35jgTafQIQJNhxheqtrwBStVQhUIIbosPBQvkven+tUv\n4lRn494VXNxWZSGevL+3iJoNtJbjjQ8FVLafx6/vKP4mShB0UxKHqSBRtzZ5g4/n\nB8d4Vw4Ma0eEBUMDD9vOqreMdKCUoMnZIKuQwWeyiug77mBxgfmCRnsefOdyEKne\nRvalPBKEpD2PH/iud+qkuNNITFCr0I1iF6f4NElciQKBgQD/q68TvMOUE2tlgdU6\n6o6d7b+Sm4yp19f1euR0fe7+5as6Pz4KWy0zwSXAczVNDXLq44hQ4eeJMALwKvQ+\nXqCrtjc3NkVtiPXIjnqEQ/t56WBZtsrLxlNAE9yxHQPEmyRMKjGOJTRpoNZzGBsS\naEqTiKinO7AY5xOWzXz+HVLDRQKBgQDabdmrKLJaHhboPBa5B7HJ8WCL5P5+97P6\n4WuDT7vQvyJqb3KhltdRAgMszFXsfYwyeidncQ3fxUlmMWtWlHROfjhyWQZ0jIJg\nwpTAvNqQ3HuXM2fRvM7d6Z69xE2RxVpRaAbvGUHvNohAW7Vwmoi/GV9NR6irV/ny\n1suS6SIH2QKBgHnJXEJ4nmlAvt3BdML1zC2qfKDne5/D81k5yu06t8evu1qpmXHx\ncJzAmq0LtA4aI+2DqQFuOo580kl5DJNRHBPvXmnsbjH5FasNQ4sRnw65fm39xqg+\ntpVFYND1U0Ap7qZhSu29BzRxqvV0PCEOkMeqRzwyEHYsTIZ/J9UcPrpJAoGAcNQ/\nlN8vycczNAEeB7QGzXbG1VyTbYiMSrK4c5rzPHAO2gX5o6ikTm8IrtJaLA/qJITe\n59sJPKbPNF+gv5dtwMIIbGC6KegOzOaWKj0jdaK+oKroHPo3rX+pBQNqwjq8XcKr\nmkRkv6lelkgJIEJjEruLdALpCKEoNp1niNquPnkCgYAVAkaF/8xYQ4UaBuJEJPOW\nDNXAmRrvaazU8GTv70t03VHKjhcv7b83L+n8yU3VuaqaO3bgyGIELJ2VRzVn16EH\nkUwh1W2fB1ZAmMK6V5JB7b8LCPdpCJSbQvNZAOZj4aodoNtGKM0j36rTSZJi2Rdz\nqtOSw0pEvALI62ufuNRUzA==\n-----END PRIVATE KEY-----\n",
"client_email": "tlw-707@tippliga.iam.gserviceaccount.com",
"client_id": "101590566618120833710",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/tlw-707%40tippliga.iam.gserviceaccount.com"
}
@@ -0,0 +1,167 @@
{
"numberOfMatchdays": 39,
"matchesPerMatchday": 12,
"pointMode": 4,
"pointsTendency": 1,
"pointsDifference": 2,
"pointsDirectHit": 3,
"ko": 0,
"matchdayConfig": [
{
"TLWMatchday": 1,
"matchesConfig": []
},
{
"TLWMatchday": 2,
"matchesConfig": []
},
{
"TLWMatchday": 3,
"matchesConfig": []
},
{
"TLWMatchday": 4,
"matchesConfig": []
},
{
"TLWMatchday": 5,
"matchesConfig": []
},
{
"TLWMatchday": 6,
"matchesConfig": []
},
{
"TLWMatchday": 7,
"matchesConfig": []
},
{
"TLWMatchday": 8,
"matchesConfig": []
},
{
"TLWMatchday": 9,
"matchesConfig": []
},
{
"TLWMatchday": 10,
"matchesConfig": []
},
{
"TLWMatchday": 11,
"matchesConfig": []
},
{
"TLWMatchday": 12,
"matchesConfig": []
},
{
"TLWMatchday": 13,
"matchesConfig": []
},
{
"TLWMatchday": 14,
"matchesConfig": []
},
{
"TLWMatchday": 15,
"matchesConfig": []
},
{
"TLWMatchday": 16,
"matchesConfig": []
},
{
"TLWMatchday": 17,
"matchesConfig": []
},
{
"TLWMatchday": 18,
"matchesConfig": []
},
{
"TLWMatchday": 19,
"matchesConfig": []
},
{
"TLWMatchday": 20,
"matchesConfig": []
},
{
"TLWMatchday": 21,
"matchesConfig": []
},
{
"TLWMatchday": 22,
"matchesConfig": []
},
{
"TLWMatchday": 23,
"matchesConfig": []
},
{
"TLWMatchday": 24,
"matchesConfig": []
},
{
"TLWMatchday": 25,
"matchesConfig": []
},
{
"TLWMatchday": 26,
"matchesConfig": []
},
{
"TLWMatchday": 27,
"matchesConfig": []
},
{
"TLWMatchday": 28,
"matchesConfig": []
},
{
"TLWMatchday": 29,
"matchesConfig": []
},
{
"TLWMatchday": 30,
"matchesConfig": []
},
{
"TLWMatchday": 31,
"matchesConfig": []
},
{
"TLWMatchday": 32,
"matchesConfig": []
},
{
"TLWMatchday": 33,
"matchesConfig": []
},
{
"TLWMatchday": 34,
"matchesConfig": []
},
{
"TLWMatchday": 35,
"matchesConfig": []
},
{
"TLWMatchday": 36,
"matchesConfig": []
},
{
"TLWMatchday": 37,
"matchesConfig": []
},
{
"TLWMatchday": 38,
"matchesConfig": []
},
{
"TLWMatchday": 39,
"matchesConfig": []
}
]
}
+2 -3
View File
@@ -1,6 +1,5 @@
package de.jeyp91;
import org.json.simple.JSONObject;
import org.junit.Test;
public class S3ProviderTest {
@@ -8,7 +7,7 @@ public class S3ProviderTest {
@Test
public void getFixturesFromS3Test() {
S3Provider prov = new S3Provider();
JSONObject rounds = prov.getFixturesJSONFromS3(2026, 1240);
System.out.println(rounds.toJSONString());
String rounds = prov.getFixturesStringFromS3(1240);
System.out.println(rounds);
}
}
@@ -3,6 +3,7 @@ import de.jeyp91.apifootball.APIFootballMatch;
import de.jeyp91.teamidmatcher.TeamIDMatcher;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
@@ -10,7 +11,7 @@ import static org.junit.Assert.assertEquals;
public class TeamIDMatcherTest {
@Test
public void getAPIFootballIdFromTippligaIdTest() {
public void getOpenLigaDbIdFromTippligaIdTest() {
int apiFootballId;
apiFootballId = TeamIDMatcher.getApiFootballIdFromTippligaId(505);
@@ -22,7 +23,7 @@ public class TeamIDMatcherTest {
}
@Test
public void getTippligaIdFromAPIFootballIdTest() throws Exception {
public void getTippligaIdFromOpenLigaDbIdTest() throws Exception {
int tlwId;
String jsonMatch = "{" +
"\"fixture_id\":1," +
@@ -1,11 +1,12 @@
package de.jeyp91.apifootball;
import de.jeyp91.openligadb.OpenLigaDBConnector;
import org.junit.Test;
import java.util.ArrayList;
import org.junit.Test;
public class APIFootballConnectorTest {
/*
@Test
public void APITestGetMatchDataOfMatchdayBundesliga() {
APIFootballConnector apiFootballConnector = APIFootballConnector.getAPIFootballConnectorInstance(2020);
@@ -13,5 +14,4 @@ public class APIFootballConnectorTest {
assert matchesOfMatchday.get(0).getTeamIdHome() == 744;
assert matchesOfMatchday.get(0).getTeamIdGuest() == 159;
}
*/
}
@@ -6,7 +6,7 @@ import org.junit.Test;
import static de.jeyp91.apifootball.APIFootballConnector.stringToJSONObject;
public class APIFootballMatchTest {
/*
@Test
public void withExtratime() throws Exception {
String matchString = "{\"fixture_id\":958530,\"league_id\":4303,\"league\":{\"name\":\"DFB Pokal\",\"country\":\"Germany\",\"logo\":\"https:\\/\\/media-3.api-sports.io\\/football\\/leagues\\/81.png\",\"flag\":\"https:\\/\\/media-1.api-sports.io\\/flags\\/de.svg\"},\"event_date\":\"2022-10-19T18:00:00+02:00\",\"event_timestamp\":1666195200,\"firstHalfStart\":1666195200,\"secondHalfStart\":1666198800,\"round\":\"2nd Round\",\"status\":\"Match Finished\",\"statusShort\":\"PEN\",\"elapsed\":120,\"venue\":\"Home Deluxe Arena\",\"referee\":\"Frank Willenborg, Germany\",\"homeTeam\":{\"team_id\":185,\"team_name\":\"SC Paderborn 07\",\"logo\":\"https:\\/\\/media-2.api-sports.io\\/football\\/teams\\/185.png\"},\"awayTeam\":{\"team_id\":162,\"team_name\":\"Werder Bremen\",\"logo\":\"https:\\/\\/media-3.api-sports.io\\/football\\/teams\\/162.png\"},\"goalsHomeTeam\":2,\"goalsAwayTeam\":2,\"score\":{\"halftime\":\"2-0\",\"fulltime\":\"2-2\",\"extratime\":\"0-0\",\"penalty\":\"5-4\"}}";
@@ -20,5 +20,4 @@ public class APIFootballMatchTest {
JSONObject matchJson = stringToJSONObject(matchString);
APIFootballMatch match = new APIFootballMatch(matchJson, 2023);
}
*/
}
@@ -4,30 +4,28 @@ import org.junit.Test;
public class APIFootballUpdaterTest {
int season = 2027;
/*
@Test
public void checkErrorsTest() {
String rateLimitError = "{\"results\":0,\"errors\":{\"rateLimit\":\"Too many requests. Your rate limit is 10 requests per minute.\"}}";
String exceededLimitDayError = "{\"api\":{\"results\":0,\"error\":\"You have reached the request limit for the day\"}}";
APIFootballUpdater updater = new APIFootballUpdater();
try {
updater.checkErrors("https://test.url/api", rateLimitError);
updater.checkErrors("https://test.url/api", exceededLimitDayError);
} catch (Exception e) {
System.out.println(e.getMessage());
assert e.getMessage().equals("https://test.url/api returned error: '{\"rateLimit\":\"Too many requests. Your rate limit is 10 requests per minute.\"}'");
assert e.getMessage().equals("https://test.url/api returned error: 'You have reached the request limit for the day'");
}
}
@Test
public void updateFixturesTest() {
APIFootballUpdater updater = new APIFootballUpdater();
updater.updateFixtures(season, 218);
// updater.updateFixtures(1240);
}
@Test
public void updateAllFixturesTest() {
APIFootballUpdater updater = new APIFootballUpdater();
updater.updateAllFixtures(season);
// updater.updateAllFixtures();
}
@Test
@@ -39,7 +37,6 @@ public class APIFootballUpdaterTest {
@Test
public void updateAllRoundsTest() {
APIFootballUpdater updater = new APIFootballUpdater();
updater.updateAllRounds(season);
// updater.updateAllRounds();
}
*/
}
@@ -0,0 +1,77 @@
package de.jeyp91.openligadb;
import org.junit.Test;
import java.util.ArrayList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class OpenLigaDBConnectorTest {
@Test
public void APITestGetMatchDataOfMatchdayBundesliga() {
OpenLigaDBConnector openLigaDBConnector = new OpenLigaDBConnector();
ArrayList<OpenLigaDBMatch> matches = openLigaDBConnector.getMatchDataOfMatchday(2020, "bl1", 1);
assertEquals(9, matches.size());
OpenLigaDBMatch match;
match = matches.get(0);
assertEquals((Integer) 55277, match.getMatchId());
assertEquals((Integer) 40, match.getTeamIdHome());
assertEquals((Integer) 54, match.getTeamIdGuest());
assertEquals((Integer) 2020, match.getSeason());
assertEquals("2019-08-16T20:30:00", match.getMatchDateTime());
assertEquals((Integer) 1, match.getMatchday());
assertEquals((Integer) 2, match.getGoalsHome());
assertEquals((Integer) 2, match.getGoalsGuest());
assertTrue(match.getMatchIsFinished());
match = matches.get(1);
assertEquals((Integer) 55278, match.getMatchId());
assertEquals((Integer) 7, match.getTeamIdHome());
assertEquals((Integer) 95, match.getTeamIdGuest());
assertEquals((Integer) 2020, match.getSeason());
assertEquals("2019-08-17T15:30:00", match.getMatchDateTime());
assertEquals((Integer) 1, match.getMatchday());
assertEquals((Integer) 5, match.getGoalsHome());
assertEquals((Integer) 1, match.getGoalsGuest());
assertTrue(match.getMatchIsFinished());
}
@Test
public void APITestGetMatchDataOfMatchdayDFBPokal() {
OpenLigaDBConnector openLigaDBConnector = new OpenLigaDBConnector();
ArrayList<OpenLigaDBMatch> matches = openLigaDBConnector.getMatchDataOfMatchday(2020, "dfb2019", 1);
assert matches.size() == 32;
OpenLigaDBMatch match = matches.get(0);
assertEquals((Integer) 54926, match.getMatchId());
assertEquals((Integer) 563, match.getTeamIdHome());
assertEquals((Integer) 7, match.getTeamIdGuest());
assertEquals((Integer) 2020, match.getSeason());
assertEquals("2019-08-09T20:45:00", match.getMatchDateTime());
assertEquals((Integer) 1, match.getMatchday());
assertEquals((Integer) 0, match.getGoalsHome());
assertEquals((Integer) 2, match.getGoalsGuest());
assertTrue(match.getMatchIsFinished());
}
@Test
public void APITestGetMatchDataOfSingleMatch() {
OpenLigaDBConnector openLigaDBConnector = new OpenLigaDBConnector();
OpenLigaDBMatch match = openLigaDBConnector.getMatchDataOfSingleMatch(55583);
assertEquals((Integer) 55583, match.getMatchId());
assertEquals((Integer) 16, match.getTeamIdHome());
assertEquals((Integer) 55, match.getTeamIdGuest());
assertEquals((Integer) 2020, match.getSeason());
assertEquals("2019-07-26T20:30:00", match.getMatchDateTime());
assertEquals((Integer) 1, match.getMatchday());
assertEquals((Integer) 2, match.getGoalsHome());
assertEquals((Integer) 1, match.getGoalsGuest());
assertTrue(match.getMatchIsFinished());
}
}
@@ -1,13 +1,15 @@
package de.jeyp91.tippliga;
import org.junit.Test;
import java.text.ParseException;
import java.util.ArrayList;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class TLWMatchdaysCreatorTest {
int season = 2027;
int season = 2023;
@Test
public void getMatchdaysTippligaTest() {
@@ -90,19 +92,11 @@ public class TLWMatchdaysCreatorTest {
System.out.println(sql);
}
@Test
public void getMatchdaysRelegationSqlTest() {
TLWMatchdaysCreator matchdaysCreator = new TLWMatchdaysCreator(season, 47, "Relegation");
String sql = matchdaysCreator.getMatchdaysSQL();
System.out.println(sql);
}
@Test
public void getMatchdaysEMTippspielSqlTest() {
TLWMatchdaysCreator matchdaysCreator = new TLWMatchdaysCreator(2021, 49, "EM-Tippspiel");
String sql = matchdaysCreator.getMatchdaysSQL();
System.out.println(sql);
// System.out.println(sql);
}
}
@@ -1,13 +1,14 @@
package de.jeyp91.tippliga;
import org.junit.Test;
import java.util.ArrayList;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class TLWMatchesCreatorFootballTest {
int season = 2027;
int season = 2023;
@Test
public void getMatchesTest() {
@@ -48,9 +49,9 @@ public class TLWMatchesCreatorFootballTest {
}
@Test
public void getMatchesRelegationSqlTest() {
TLWMatchesCreatorFootball creator = new TLWMatchesCreatorFootball(season, 47, "Relegation");
public void getMatchesEMTippspielSqlTest() {
TLWMatchesCreatorFootball creator = new TLWMatchesCreatorFootball(2021, 49, "EM-Tippspiel");
String sql = creator.getSQLInsertString();
System.out.println(sql);
// System.out.println(sql);
}
}
@@ -4,7 +4,7 @@ import org.junit.Test;
public class TLWMatchesCreatorTipperPokalTest {
int season = 2027;
int season = 2024;
@Test
public void getMatchesWTLPokalTest() {
@@ -2,9 +2,13 @@ package de.jeyp91.tippliga;
import org.junit.Test;
import java.text.ParseException;
import static org.junit.Assert.assertEquals;
public class TLWMatchesCreatorTipperTest {
int season = 2027;
int season = 2024;
@Test
public void getMatchesTippliga1Test() {
@@ -4,15 +4,14 @@ import org.junit.Test;
public class TLWMatchesUpdaterFootballTest {
int season = 2027;
int season = 2024;
@Test
public void getUpdateSqlTest1() {
TLWMatchesUpdaterFootball updater = new TLWMatchesUpdaterFootball(season, 1, "Tippliga");
String sql = updater.getUpdateSQL();
String beatifulInfo = updater.getBeautifulInfo();
System.out.println(sql);
// System.out.println(beatifulInfo);
// System.out.println(updater.getBeautifulInfo());
}
@Test

Some files were not shown because too many files have changed in this diff Show More