From b1f9281e58f0f376feb1f5d08869db073557095b Mon Sep 17 00:00:00 2001
From: Vincenzo Garambone
Date: Sat, 30 Mar 2024 18:05:17 +0100
Subject: [PATCH 1/6] Add support for football-data.org results
---
.../garambo/retrosearch/http/HttpService.java | 7 +
.../retrosearch/http/HttpServiceImpl.java | 37 +-
.../client/FootballDataOrgClient.java | 34 +
.../football/model/FootballDataResponse.java | 8 +
.../sports/football/model/match/Area.java | 3 +
.../football/model/match/Competition.java | 3 +
.../football/model/match/HomeAwayScore.java | 3 +
.../sports/football/model/match/Match.java | 28 +
.../sports/football/model/match/Score.java | 3 +
.../sports/football/model/match/Team.java | 3 +
.../football/model/match/enums/Status.java | 23 +
.../repository/InMemorySportsRepository.java | 38 +
.../football/repository/SportsRepository.java | 14 +
.../resources/sports/sports/response.json | 2492 +++++++++++++++++
14 files changed, 2688 insertions(+), 8 deletions(-)
create mode 100644 src/main/java/it/garambo/retrosearch/sports/football/client/FootballDataOrgClient.java
create mode 100644 src/main/java/it/garambo/retrosearch/sports/football/model/FootballDataResponse.java
create mode 100644 src/main/java/it/garambo/retrosearch/sports/football/model/match/Area.java
create mode 100644 src/main/java/it/garambo/retrosearch/sports/football/model/match/Competition.java
create mode 100644 src/main/java/it/garambo/retrosearch/sports/football/model/match/HomeAwayScore.java
create mode 100644 src/main/java/it/garambo/retrosearch/sports/football/model/match/Match.java
create mode 100644 src/main/java/it/garambo/retrosearch/sports/football/model/match/Score.java
create mode 100644 src/main/java/it/garambo/retrosearch/sports/football/model/match/Team.java
create mode 100644 src/main/java/it/garambo/retrosearch/sports/football/model/match/enums/Status.java
create mode 100644 src/main/java/it/garambo/retrosearch/sports/football/repository/InMemorySportsRepository.java
create mode 100644 src/main/java/it/garambo/retrosearch/sports/football/repository/SportsRepository.java
create mode 100644 src/test/resources/sports/sports/response.json
diff --git a/src/main/java/it/garambo/retrosearch/http/HttpService.java b/src/main/java/it/garambo/retrosearch/http/HttpService.java
index 8aa4e17..1ba999c 100644
--- a/src/main/java/it/garambo/retrosearch/http/HttpService.java
+++ b/src/main/java/it/garambo/retrosearch/http/HttpService.java
@@ -3,7 +3,9 @@
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.List;
import java.util.Map;
+import org.apache.http.Header;
public interface HttpService {
@@ -11,6 +13,11 @@ public interface HttpService {
String get(URI uri, Map params) throws IOException, URISyntaxException;
+ String get(URI uri, List additionalHeaders) throws IOException, URISyntaxException;
+
+ String get(URI uri, Map params, List additionalHeaders)
+ throws IOException, URISyntaxException;
+
String post(URI uri, String body) throws IOException;
String post(URI uri, Map formData) throws IOException, URISyntaxException;
diff --git a/src/main/java/it/garambo/retrosearch/http/HttpServiceImpl.java b/src/main/java/it/garambo/retrosearch/http/HttpServiceImpl.java
index 81cc21c..87eed29 100644
--- a/src/main/java/it/garambo/retrosearch/http/HttpServiceImpl.java
+++ b/src/main/java/it/garambo/retrosearch/http/HttpServiceImpl.java
@@ -3,6 +3,7 @@
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -27,12 +28,12 @@ public class HttpServiceImpl implements HttpService {
private final ResponseHandler responseHandler;
- private final Header[] defaultClientHeaders = {
- new BasicHeader("charset", "UTF-8"),
- new BasicHeader(
- "User-Agent",
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36")
- };
+ private final List defaultClientHeaders =
+ List.of(
+ new BasicHeader("charset", "UTF-8"),
+ new BasicHeader(
+ "User-Agent",
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"));
public HttpServiceImpl(
@Autowired HttpClientFactory clientFactory,
@@ -48,10 +49,30 @@ public String get(URI uri) throws IOException, URISyntaxException {
@Override
public String get(URI uri, Map params) throws IOException, URISyntaxException {
+ return get(uri, params, Collections.emptyList());
+ }
+
+ @Override
+ public String get(URI uri, List additionalHeaders)
+ throws IOException, URISyntaxException {
+ return get(uri, Collections.emptyMap(), additionalHeaders);
+ }
+
+ @Override
+ public String get(URI uri, Map params, List additionalHeaders)
+ throws IOException, URISyntaxException {
URIBuilder newUri = new URIBuilder(uri).setParameters(mapToNameValuePair(params));
final HttpGet get = new HttpGet(newUri.build());
- get.setHeaders(defaultClientHeaders);
+ Header[] requestHeaders = defaultClientHeaders.toArray(new Header[0]);
+
+ if (!CollectionUtils.isEmpty(additionalHeaders)) {
+ List newHeaders = new ArrayList<>(defaultClientHeaders);
+ newHeaders.addAll(additionalHeaders);
+ requestHeaders = newHeaders.toArray(new Header[0]);
+ }
+
+ get.setHeaders(requestHeaders);
return clientFactory.createHttpClient().execute(get, responseHandler);
}
@@ -59,7 +80,7 @@ public String get(URI uri, Map params) throws IOException, URISy
public String post(URI uri, String body) throws IOException {
final HttpPost post = new HttpPost(uri);
post.setEntity(new StringEntity(body));
- post.setHeaders(defaultClientHeaders);
+ post.setHeaders(defaultClientHeaders.toArray(new Header[0]));
return clientFactory.createHttpClient().execute(post, responseHandler);
}
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/client/FootballDataOrgClient.java b/src/main/java/it/garambo/retrosearch/sports/football/client/FootballDataOrgClient.java
new file mode 100644
index 0000000..fbf08da
--- /dev/null
+++ b/src/main/java/it/garambo/retrosearch/sports/football/client/FootballDataOrgClient.java
@@ -0,0 +1,34 @@
+package it.garambo.retrosearch.sports.football.client;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import it.garambo.retrosearch.http.HttpService;
+import it.garambo.retrosearch.sports.football.model.FootballDataResponse;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+import org.apache.http.message.BasicHeader;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConditionalOnProperty(value = "retrosearch.sports.football.enable", havingValue = "true")
+public class FootballDataOrgClient {
+
+ private final String API_URL = "https://api.football-data.org/v4/matches/";
+
+ @Value("${retrosearch.sports.football.api.key:}")
+ private String apiKey;
+
+ @Autowired HttpService httpService;
+
+ public FootballDataResponse getFootballData() throws IOException, URISyntaxException {
+ URI apiUri = new URI(API_URL);
+ BasicHeader apiKeyHeader = new BasicHeader("X-Auth-Token", apiKey);
+
+ String response = httpService.get(apiUri, List.of(apiKeyHeader));
+ return new ObjectMapper().readValue(response, FootballDataResponse.class);
+ }
+}
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/model/FootballDataResponse.java b/src/main/java/it/garambo/retrosearch/sports/football/model/FootballDataResponse.java
new file mode 100644
index 0000000..b91c467
--- /dev/null
+++ b/src/main/java/it/garambo/retrosearch/sports/football/model/FootballDataResponse.java
@@ -0,0 +1,8 @@
+package it.garambo.retrosearch.sports.football.model;
+
+import it.garambo.retrosearch.sports.football.model.match.Match;
+import java.util.List;
+import java.util.Map;
+
+public record FootballDataResponse(
+ Map filters, Map resultSet, List matches) {}
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/model/match/Area.java b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Area.java
new file mode 100644
index 0000000..d5eafc5
--- /dev/null
+++ b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Area.java
@@ -0,0 +1,3 @@
+package it.garambo.retrosearch.sports.football.model.match;
+
+public record Area(int id, String name, String code) {}
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/model/match/Competition.java b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Competition.java
new file mode 100644
index 0000000..3af9755
--- /dev/null
+++ b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Competition.java
@@ -0,0 +1,3 @@
+package it.garambo.retrosearch.sports.football.model.match;
+
+public record Competition(int id, String name, String code) {}
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/model/match/HomeAwayScore.java b/src/main/java/it/garambo/retrosearch/sports/football/model/match/HomeAwayScore.java
new file mode 100644
index 0000000..cff02ef
--- /dev/null
+++ b/src/main/java/it/garambo/retrosearch/sports/football/model/match/HomeAwayScore.java
@@ -0,0 +1,3 @@
+package it.garambo.retrosearch.sports.football.model.match;
+
+public record HomeAwayScore(int home, int away) {}
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/model/match/Match.java b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Match.java
new file mode 100644
index 0000000..4053941
--- /dev/null
+++ b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Match.java
@@ -0,0 +1,28 @@
+package it.garambo.retrosearch.sports.football.model.match;
+
+import it.garambo.retrosearch.sports.football.model.match.enums.Status;
+import java.util.Date;
+import org.jetbrains.annotations.NotNull;
+
+public record Match(
+ int id,
+ Date utcDate,
+ Date lastUpdated,
+ Area area,
+ Status status,
+ Competition competition,
+ Score score)
+ implements Comparable {
+
+ @Override
+ public int compareTo(@NotNull Match o) {
+ return this.area.id()
+ - o.area.id()
+ + this.competition.id()
+ - o.competition.id()
+ + this.id
+ - o.id
+ + this.status.ordinal()
+ - this.status.ordinal();
+ }
+}
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/model/match/Score.java b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Score.java
new file mode 100644
index 0000000..cc68116
--- /dev/null
+++ b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Score.java
@@ -0,0 +1,3 @@
+package it.garambo.retrosearch.sports.football.model.match;
+
+public record Score(HomeAwayScore halfTime, HomeAwayScore fullTime) {}
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/model/match/Team.java b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Team.java
new file mode 100644
index 0000000..5b67378
--- /dev/null
+++ b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Team.java
@@ -0,0 +1,3 @@
+package it.garambo.retrosearch.sports.football.model.match;
+
+public record Team(int id, String name, String shortName) {}
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/model/match/enums/Status.java b/src/main/java/it/garambo/retrosearch/sports/football/model/match/enums/Status.java
new file mode 100644
index 0000000..1b8ebbd
--- /dev/null
+++ b/src/main/java/it/garambo/retrosearch/sports/football/model/match/enums/Status.java
@@ -0,0 +1,23 @@
+package it.garambo.retrosearch.sports.football.model.match.enums;
+
+public enum Status {
+ SCHEDULED("Scheduled"),
+ TIMED("Timed"),
+ IN_PLAY("In Play"),
+ PAUSED("Paused"),
+ FINISHED("Finished"),
+ SUSPENDED("Suspended"),
+ POSTPONED("Postponed"),
+ CANCELLED("Canceled"),
+ AWARDED("Awarded");
+
+ final String description;
+
+ private Status(String description) {
+ this.description = description;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/repository/InMemorySportsRepository.java b/src/main/java/it/garambo/retrosearch/sports/football/repository/InMemorySportsRepository.java
new file mode 100644
index 0000000..1f47834
--- /dev/null
+++ b/src/main/java/it/garambo/retrosearch/sports/football/repository/InMemorySportsRepository.java
@@ -0,0 +1,38 @@
+package it.garambo.retrosearch.sports.football.repository;
+
+import it.garambo.retrosearch.sports.football.model.match.Match;
+import java.util.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+@ConditionalOnProperty(value = "retrosearch.sports.football.enable", havingValue = "true")
+public class InMemorySportsRepository implements SportsRepository {
+
+ Map> matchByArea;
+ private Date updatedAt;
+
+ @Override
+ public Set getAllMatchesByArea(String areaName) {
+ return matchByArea.get(areaName);
+ }
+
+ @Override
+ public void updateAll(Set newMatches) {
+ matchByArea.clear();
+ newMatches.forEach(
+ match -> {
+ String areaName = match.area().name();
+ matchByArea.putIfAbsent(areaName, Set.of());
+ matchByArea.get(areaName).add(match);
+ });
+ log.info("Football Results updated");
+ }
+
+ @Override
+ public Date getUpdatedAt() {
+ return updatedAt;
+ }
+}
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/repository/SportsRepository.java b/src/main/java/it/garambo/retrosearch/sports/football/repository/SportsRepository.java
new file mode 100644
index 0000000..d07ab0b
--- /dev/null
+++ b/src/main/java/it/garambo/retrosearch/sports/football/repository/SportsRepository.java
@@ -0,0 +1,14 @@
+package it.garambo.retrosearch.sports.football.repository;
+
+import it.garambo.retrosearch.sports.football.model.match.Match;
+import java.util.Date;
+import java.util.Set;
+
+public interface SportsRepository {
+
+ Set getAllMatchesByArea(String areaName);
+
+ void updateAll(Set newMatches);
+
+ Date getUpdatedAt();
+}
diff --git a/src/test/resources/sports/sports/response.json b/src/test/resources/sports/sports/response.json
new file mode 100644
index 0000000..e34bcf2
--- /dev/null
+++ b/src/test/resources/sports/sports/response.json
@@ -0,0 +1,2492 @@
+
+{
+ "filters":
+ {
+ "dateFrom": "2024-03-30",
+ "dateTo": "2024-03-31",
+ "permission": "TIER_ONE"
+ },
+ "resultSet":
+ {
+ "count": 34,
+ "competitions": "SA,PL,PD,BL1,PPL,DED,FL1",
+ "first": "2024-03-30",
+ "last": "2024-03-30",
+ "played": 3
+ },
+ "matches":
+ [
+ {
+ "area":
+ {
+ "id": 2114,
+ "name": "Italy",
+ "code": "ITA",
+ "flag": "https://crests.football-data.org/784.svg"
+ },
+ "competition":
+ {
+ "id": 2019,
+ "name": "Serie A",
+ "code": "SA",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/SA.png"
+ },
+ "season":
+ {
+ "id": 1600,
+ "startDate": "2023-08-19",
+ "endDate": "2024-05-26",
+ "currentMatchday": 30,
+ "winner": null
+ },
+ "id": 444551,
+ "utcDate": "2024-03-30T11:30:00Z",
+ "status": "FINISHED",
+ "matchday": 30,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T14:23:59Z",
+ "homeTeam":
+ {
+ "id": 113,
+ "name": "SSC Napoli",
+ "shortName": "Napoli",
+ "tla": "NAP",
+ "crest": "https://crests.football-data.org/113.svg"
+ },
+ "awayTeam":
+ {
+ "id": 102,
+ "name": "Atalanta BC",
+ "shortName": "Atalanta",
+ "tla": "ATA",
+ "crest": "https://crests.football-data.org/102.svg"
+ },
+ "score":
+ {
+ "winner": "AWAY_TEAM",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 0,
+ "away": 3
+ },
+ "halfTime":
+ {
+ "home": 0,
+ "away": 2
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ [
+ {
+ "id": 11002,
+ "name": "Luca Pairetto",
+ "type": "REFEREE",
+ "nationality": "Italy"
+ }
+ ]
+ },
+ {
+ "area":
+ {
+ "id": 2072,
+ "name": "England",
+ "code": "ENG",
+ "flag": "https://crests.football-data.org/770.svg"
+ },
+ "competition":
+ {
+ "id": 2021,
+ "name": "Premier League",
+ "code": "PL",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/PL.png"
+ },
+ "season":
+ {
+ "id": 1564,
+ "startDate": "2023-08-11",
+ "endDate": "2024-05-19",
+ "currentMatchday": 30,
+ "winner": null
+ },
+ "id": 436239,
+ "utcDate": "2024-03-30T12:30:00Z",
+ "status": "FINISHED",
+ "matchday": 30,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T15:39:34Z",
+ "homeTeam":
+ {
+ "id": 67,
+ "name": "Newcastle United FC",
+ "shortName": "Newcastle",
+ "tla": "NEW",
+ "crest": "https://crests.football-data.org/67.png"
+ },
+ "awayTeam":
+ {
+ "id": 563,
+ "name": "West Ham United FC",
+ "shortName": "West Ham",
+ "tla": "WHU",
+ "crest": "https://crests.football-data.org/563.png"
+ },
+ "score":
+ {
+ "winner": "HOME_TEAM",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 4,
+ "away": 3
+ },
+ "halfTime":
+ {
+ "home": 1,
+ "away": 2
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ [
+ {
+ "id": 11446,
+ "name": "Robert Jones",
+ "type": "REFEREE",
+ "nationality": "England"
+ }
+ ]
+ },
+ {
+ "area":
+ {
+ "id": 2224,
+ "name": "Spain",
+ "code": "ESP",
+ "flag": "https://crests.football-data.org/760.svg"
+ },
+ "competition":
+ {
+ "id": 2014,
+ "name": "Primera Division",
+ "code": "PD",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/PD.png"
+ },
+ "season":
+ {
+ "id": 1577,
+ "startDate": "2023-08-13",
+ "endDate": "2024-05-26",
+ "currentMatchday": 30,
+ "winner": null
+ },
+ "id": 438768,
+ "utcDate": "2024-03-30T13:00:00Z",
+ "status": "FINISHED",
+ "matchday": 30,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T16:02:15Z",
+ "homeTeam":
+ {
+ "id": 82,
+ "name": "Getafe CF",
+ "shortName": "Getafe",
+ "tla": "GET",
+ "crest": "https://crests.football-data.org/82.png"
+ },
+ "awayTeam":
+ {
+ "id": 559,
+ "name": "Sevilla FC",
+ "shortName": "Sevilla FC",
+ "tla": "SEV",
+ "crest": "https://crests.football-data.org/559.svg"
+ },
+ "score":
+ {
+ "winner": "AWAY_TEAM",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 0,
+ "away": 1
+ },
+ "halfTime":
+ {
+ "home": 0,
+ "away": 1
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ [
+ {
+ "id": 215462,
+ "name": "Javier Iglesias Villanueva",
+ "type": "REFEREE",
+ "nationality": "Spain"
+ }
+ ]
+ },
+ {
+ "area":
+ {
+ "id": 2114,
+ "name": "Italy",
+ "code": "ITA",
+ "flag": "https://crests.football-data.org/784.svg"
+ },
+ "competition":
+ {
+ "id": 2019,
+ "name": "Serie A",
+ "code": "SA",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/SA.png"
+ },
+ "season":
+ {
+ "id": 1600,
+ "startDate": "2023-08-19",
+ "endDate": "2024-05-26",
+ "currentMatchday": 30,
+ "winner": null
+ },
+ "id": 444547,
+ "utcDate": "2024-03-30T14:00:00Z",
+ "status": "IN_PLAY",
+ "matchday": 30,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T16:49:11Z",
+ "homeTeam":
+ {
+ "id": 107,
+ "name": "Genoa CFC",
+ "shortName": "Genoa",
+ "tla": "GEN",
+ "crest": "https://crests.football-data.org/107.svg"
+ },
+ "awayTeam":
+ {
+ "id": 470,
+ "name": "Frosinone Calcio",
+ "shortName": "Frosinone",
+ "tla": "FRO",
+ "crest": "https://crests.football-data.org/470.png"
+ },
+ "score":
+ {
+ "winner": "DRAW",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 1,
+ "away": 1
+ },
+ "halfTime":
+ {
+ "home": 1,
+ "away": 1
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ [
+ {
+ "id": 206189,
+ "name": "Juan Luca Sacchi",
+ "type": "REFEREE",
+ "nationality": "Italy"
+ }
+ ]
+ },
+ {
+ "area":
+ {
+ "id": 2114,
+ "name": "Italy",
+ "code": "ITA",
+ "flag": "https://crests.football-data.org/784.svg"
+ },
+ "competition":
+ {
+ "id": 2019,
+ "name": "Serie A",
+ "code": "SA",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/SA.png"
+ },
+ "season":
+ {
+ "id": 1600,
+ "startDate": "2023-08-19",
+ "endDate": "2024-05-26",
+ "currentMatchday": 30,
+ "winner": null
+ },
+ "id": 444553,
+ "utcDate": "2024-03-30T14:00:00Z",
+ "status": "IN_PLAY",
+ "matchday": 30,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T16:49:12Z",
+ "homeTeam":
+ {
+ "id": 586,
+ "name": "Torino FC",
+ "shortName": "Torino",
+ "tla": "TOR",
+ "crest": "https://crests.football-data.org/586.svg"
+ },
+ "awayTeam":
+ {
+ "id": 5911,
+ "name": "AC Monza",
+ "shortName": "Monza",
+ "tla": "MON",
+ "crest": "https://crests.football-data.org/5911.png"
+ },
+ "score":
+ {
+ "winner": "HOME_TEAM",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 1,
+ "away": 0
+ },
+ "halfTime":
+ {
+ "home": 0,
+ "away": 0
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ [
+ {
+ "id": 11068,
+ "name": "Gianluca Aureliano",
+ "type": "REFEREE",
+ "nationality": "Italy"
+ }
+ ]
+ },
+ {
+ "area":
+ {
+ "id": 2088,
+ "name": "Germany",
+ "code": "DEU",
+ "flag": "https://crests.football-data.org/759.svg"
+ },
+ "competition":
+ {
+ "id": 2002,
+ "name": "Bundesliga",
+ "code": "BL1",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/BL1.png"
+ },
+ "season":
+ {
+ "id": 1592,
+ "startDate": "2023-08-18",
+ "endDate": "2024-05-18",
+ "currentMatchday": 27,
+ "winner": null
+ },
+ "id": 442027,
+ "utcDate": "2024-03-30T14:30:00Z",
+ "status": "IN_PLAY",
+ "matchday": 27,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T16:49:18Z",
+ "homeTeam":
+ {
+ "id": 721,
+ "name": "RB Leipzig",
+ "shortName": "RB Leipzig",
+ "tla": "RBL",
+ "crest": "https://crests.football-data.org/721.png"
+ },
+ "awayTeam":
+ {
+ "id": 15,
+ "name": "1. FSV Mainz 05",
+ "shortName": "Mainz",
+ "tla": "M05",
+ "crest": "https://crests.football-data.org/15.png"
+ },
+ "score":
+ {
+ "winner": "DRAW",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 0,
+ "away": 0
+ },
+ "halfTime":
+ {
+ "home": 0,
+ "away": 0
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ [
+ {
+ "id": 57532,
+ "name": "Frank Willenborg",
+ "type": "REFEREE",
+ "nationality": "Germany"
+ }
+ ]
+ },
+ {
+ "area":
+ {
+ "id": 2088,
+ "name": "Germany",
+ "code": "DEU",
+ "flag": "https://crests.football-data.org/759.svg"
+ },
+ "competition":
+ {
+ "id": 2002,
+ "name": "Bundesliga",
+ "code": "BL1",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/BL1.png"
+ },
+ "season":
+ {
+ "id": 1592,
+ "startDate": "2023-08-18",
+ "endDate": "2024-05-18",
+ "currentMatchday": 27,
+ "winner": null
+ },
+ "id": 442025,
+ "utcDate": "2024-03-30T14:30:00Z",
+ "status": "IN_PLAY",
+ "matchday": 27,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T16:49:16Z",
+ "homeTeam":
+ {
+ "id": 18,
+ "name": "Borussia Mönchengladbach",
+ "shortName": "M'gladbach",
+ "tla": "BMG",
+ "crest": "https://crests.football-data.org/18.png"
+ },
+ "awayTeam":
+ {
+ "id": 17,
+ "name": "SC Freiburg",
+ "shortName": "Freiburg",
+ "tla": "SCF",
+ "crest": "https://crests.football-data.org/17.svg"
+ },
+ "score":
+ {
+ "winner": "AWAY_TEAM",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 0,
+ "away": 3
+ },
+ "halfTime":
+ {
+ "home": 0,
+ "away": 1
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ [
+ {
+ "id": 57526,
+ "name": "Christian Dingert",
+ "type": "REFEREE",
+ "nationality": "Germany"
+ }
+ ]
+ },
+ {
+ "area":
+ {
+ "id": 2088,
+ "name": "Germany",
+ "code": "DEU",
+ "flag": "https://crests.football-data.org/759.svg"
+ },
+ "competition":
+ {
+ "id": 2002,
+ "name": "Bundesliga",
+ "code": "BL1",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/BL1.png"
+ },
+ "season":
+ {
+ "id": 1592,
+ "startDate": "2023-08-18",
+ "endDate": "2024-05-18",
+ "currentMatchday": 27,
+ "winner": null
+ },
+ "id": 442026,
+ "utcDate": "2024-03-30T14:30:00Z",
+ "status": "IN_PLAY",
+ "matchday": 27,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T16:49:17Z",
+ "homeTeam":
+ {
+ "id": 12,
+ "name": "SV Werder Bremen",
+ "shortName": "Bremen",
+ "tla": "SVW",
+ "crest": "https://crests.football-data.org/12.svg"
+ },
+ "awayTeam":
+ {
+ "id": 11,
+ "name": "VfL Wolfsburg",
+ "shortName": "Wolfsburg",
+ "tla": "WOB",
+ "crest": "https://crests.football-data.org/11.svg"
+ },
+ "score":
+ {
+ "winner": "AWAY_TEAM",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 0,
+ "away": 1
+ },
+ "halfTime":
+ {
+ "home": 0,
+ "away": 1
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ [
+ {
+ "id": 9567,
+ "name": "Sascha Stegemann",
+ "type": "REFEREE",
+ "nationality": "Germany"
+ }
+ ]
+ },
+ {
+ "area":
+ {
+ "id": 2088,
+ "name": "Germany",
+ "code": "DEU",
+ "flag": "https://crests.football-data.org/759.svg"
+ },
+ "competition":
+ {
+ "id": 2002,
+ "name": "Bundesliga",
+ "code": "BL1",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/BL1.png"
+ },
+ "season":
+ {
+ "id": 1592,
+ "startDate": "2023-08-18",
+ "endDate": "2024-05-18",
+ "currentMatchday": 27,
+ "winner": null
+ },
+ "id": 442029,
+ "utcDate": "2024-03-30T14:30:00Z",
+ "status": "IN_PLAY",
+ "matchday": 27,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T16:49:18Z",
+ "homeTeam":
+ {
+ "id": 3,
+ "name": "Bayer 04 Leverkusen",
+ "shortName": "Leverkusen",
+ "tla": "B04",
+ "crest": "https://crests.football-data.org/3.png"
+ },
+ "awayTeam":
+ {
+ "id": 2,
+ "name": "TSG 1899 Hoffenheim",
+ "shortName": "Hoffenheim",
+ "tla": "TSG",
+ "crest": "https://crests.football-data.org/2.png"
+ },
+ "score":
+ {
+ "winner": "AWAY_TEAM",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 0,
+ "away": 1
+ },
+ "halfTime":
+ {
+ "home": 0,
+ "away": 1
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ [
+ {
+ "id": 8825,
+ "name": "Deniz Aytekin",
+ "type": "REFEREE",
+ "nationality": "Germany"
+ }
+ ]
+ },
+ {
+ "area":
+ {
+ "id": 2088,
+ "name": "Germany",
+ "code": "DEU",
+ "flag": "https://crests.football-data.org/759.svg"
+ },
+ "competition":
+ {
+ "id": 2002,
+ "name": "Bundesliga",
+ "code": "BL1",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/BL1.png"
+ },
+ "season":
+ {
+ "id": 1592,
+ "startDate": "2023-08-18",
+ "endDate": "2024-05-18",
+ "currentMatchday": 27,
+ "winner": null
+ },
+ "id": 442024,
+ "utcDate": "2024-03-30T14:30:00Z",
+ "status": "IN_PLAY",
+ "matchday": 27,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T16:49:15Z",
+ "homeTeam":
+ {
+ "id": 19,
+ "name": "Eintracht Frankfurt",
+ "shortName": "Frankfurt",
+ "tla": "SGE",
+ "crest": "https://crests.football-data.org/19.svg"
+ },
+ "awayTeam":
+ {
+ "id": 28,
+ "name": "1. FC Union Berlin",
+ "shortName": "Union Berlin",
+ "tla": "UNB",
+ "crest": "https://crests.football-data.org/28.svg"
+ },
+ "score":
+ {
+ "winner": "DRAW",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 0,
+ "away": 0
+ },
+ "halfTime":
+ {
+ "home": 0,
+ "away": 0
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ [
+ {
+ "id": 15821,
+ "name": "Marco Fritz",
+ "type": "REFEREE",
+ "nationality": "Germany"
+ }
+ ]
+ },
+ {
+ "area":
+ {
+ "id": 2072,
+ "name": "England",
+ "code": "ENG",
+ "flag": "https://crests.football-data.org/770.svg"
+ },
+ "competition":
+ {
+ "id": 2021,
+ "name": "Premier League",
+ "code": "PL",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/PL.png"
+ },
+ "season":
+ {
+ "id": 1564,
+ "startDate": "2023-08-11",
+ "endDate": "2024-05-19",
+ "currentMatchday": 30,
+ "winner": null
+ },
+ "id": 436241,
+ "utcDate": "2024-03-30T15:00:00Z",
+ "status": "PAUSED",
+ "matchday": 30,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T16:49:22Z",
+ "homeTeam":
+ {
+ "id": 356,
+ "name": "Sheffield United FC",
+ "shortName": "Sheffield Utd",
+ "tla": "SHE",
+ "crest": "https://crests.football-data.org/356.svg"
+ },
+ "awayTeam":
+ {
+ "id": 63,
+ "name": "Fulham FC",
+ "shortName": "Fulham",
+ "tla": "FUL",
+ "crest": "https://crests.football-data.org/63.svg"
+ },
+ "score":
+ {
+ "winner": "DRAW",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 0,
+ "away": 0
+ },
+ "halfTime":
+ {
+ "home": 0,
+ "away": 0
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ [
+ {
+ "id": 11396,
+ "name": "Tim Robinson",
+ "type": "REFEREE",
+ "nationality": "England"
+ }
+ ]
+ },
+ {
+ "area":
+ {
+ "id": 2072,
+ "name": "England",
+ "code": "ENG",
+ "flag": "https://crests.football-data.org/770.svg"
+ },
+ "competition":
+ {
+ "id": 2021,
+ "name": "Premier League",
+ "code": "PL",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/PL.png"
+ },
+ "season":
+ {
+ "id": 1564,
+ "startDate": "2023-08-11",
+ "endDate": "2024-05-19",
+ "currentMatchday": 30,
+ "winner": null
+ },
+ "id": 436233,
+ "utcDate": "2024-03-30T15:00:00Z",
+ "status": "PAUSED",
+ "matchday": 30,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T16:49:20Z",
+ "homeTeam":
+ {
+ "id": 1044,
+ "name": "AFC Bournemouth",
+ "shortName": "Bournemouth",
+ "tla": "BOU",
+ "crest": "https://crests.football-data.org/1044.png"
+ },
+ "awayTeam":
+ {
+ "id": 62,
+ "name": "Everton FC",
+ "shortName": "Everton",
+ "tla": "EVE",
+ "crest": "https://crests.football-data.org/62.png"
+ },
+ "score":
+ {
+ "winner": "DRAW",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 0,
+ "away": 0
+ },
+ "halfTime":
+ {
+ "home": 0,
+ "away": 0
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ [
+ {
+ "id": 213813,
+ "name": "Sam Barrott",
+ "type": "REFEREE",
+ "nationality": "England"
+ }
+ ]
+ },
+ {
+ "area":
+ {
+ "id": 2072,
+ "name": "England",
+ "code": "ENG",
+ "flag": "https://crests.football-data.org/770.svg"
+ },
+ "competition":
+ {
+ "id": 2021,
+ "name": "Premier League",
+ "code": "PL",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/PL.png"
+ },
+ "season":
+ {
+ "id": 1564,
+ "startDate": "2023-08-11",
+ "endDate": "2024-05-19",
+ "currentMatchday": 30,
+ "winner": null
+ },
+ "id": 436242,
+ "utcDate": "2024-03-30T15:00:00Z",
+ "status": "PAUSED",
+ "matchday": 30,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T16:49:23Z",
+ "homeTeam":
+ {
+ "id": 73,
+ "name": "Tottenham Hotspur FC",
+ "shortName": "Tottenham",
+ "tla": "TOT",
+ "crest": "https://crests.football-data.org/73.svg"
+ },
+ "awayTeam":
+ {
+ "id": 389,
+ "name": "Luton Town FC",
+ "shortName": "Luton Town",
+ "tla": "LUT",
+ "crest": "https://crests.football-data.org/389.png"
+ },
+ "score":
+ {
+ "winner": "AWAY_TEAM",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 0,
+ "away": 1
+ },
+ "halfTime":
+ {
+ "home": 0,
+ "away": 1
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ [
+ {
+ "id": 23568,
+ "name": "Jarred Gillett",
+ "type": "REFEREE",
+ "nationality": "Australia"
+ }
+ ]
+ },
+ {
+ "area":
+ {
+ "id": 2072,
+ "name": "England",
+ "code": "ENG",
+ "flag": "https://crests.football-data.org/770.svg"
+ },
+ "competition":
+ {
+ "id": 2021,
+ "name": "Premier League",
+ "code": "PL",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/PL.png"
+ },
+ "season":
+ {
+ "id": 1564,
+ "startDate": "2023-08-11",
+ "endDate": "2024-05-19",
+ "currentMatchday": 30,
+ "winner": null
+ },
+ "id": 436240,
+ "utcDate": "2024-03-30T15:00:00Z",
+ "status": "IN_PLAY",
+ "matchday": 30,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T16:49:22Z",
+ "homeTeam":
+ {
+ "id": 351,
+ "name": "Nottingham Forest FC",
+ "shortName": "Nottingham",
+ "tla": "NOT",
+ "crest": "https://crests.football-data.org/351.png"
+ },
+ "awayTeam":
+ {
+ "id": 354,
+ "name": "Crystal Palace FC",
+ "shortName": "Crystal Palace",
+ "tla": "CRY",
+ "crest": "https://crests.football-data.org/354.png"
+ },
+ "score":
+ {
+ "winner": "AWAY_TEAM",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 0,
+ "away": 1
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ [
+ {
+ "id": 11443,
+ "name": "Chris Kavanagh",
+ "type": "REFEREE",
+ "nationality": "England"
+ }
+ ]
+ },
+ {
+ "area":
+ {
+ "id": 2072,
+ "name": "England",
+ "code": "ENG",
+ "flag": "https://crests.football-data.org/770.svg"
+ },
+ "competition":
+ {
+ "id": 2021,
+ "name": "Premier League",
+ "code": "PL",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/PL.png"
+ },
+ "season":
+ {
+ "id": 1564,
+ "startDate": "2023-08-11",
+ "endDate": "2024-05-19",
+ "currentMatchday": 30,
+ "winner": null
+ },
+ "id": 436236,
+ "utcDate": "2024-03-30T15:00:00Z",
+ "status": "IN_PLAY",
+ "matchday": 30,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T16:49:21Z",
+ "homeTeam":
+ {
+ "id": 61,
+ "name": "Chelsea FC",
+ "shortName": "Chelsea",
+ "tla": "CHE",
+ "crest": "https://crests.football-data.org/61.png"
+ },
+ "awayTeam":
+ {
+ "id": 328,
+ "name": "Burnley FC",
+ "shortName": "Burnley",
+ "tla": "BUR",
+ "crest": "https://crests.football-data.org/328.png"
+ },
+ "score":
+ {
+ "winner": "HOME_TEAM",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 1,
+ "away": 0
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ [
+ {
+ "id": 11469,
+ "name": "Darren England",
+ "type": "REFEREE",
+ "nationality": "England"
+ }
+ ]
+ },
+ {
+ "area":
+ {
+ "id": 2224,
+ "name": "Spain",
+ "code": "ESP",
+ "flag": "https://crests.football-data.org/760.svg"
+ },
+ "competition":
+ {
+ "id": 2014,
+ "name": "Primera Division",
+ "code": "PD",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/PD.png"
+ },
+ "season":
+ {
+ "id": 1577,
+ "startDate": "2023-08-13",
+ "endDate": "2024-05-26",
+ "currentMatchday": 30,
+ "winner": null
+ },
+ "id": 438773,
+ "utcDate": "2024-03-30T15:15:00Z",
+ "status": "IN_PLAY",
+ "matchday": 30,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T16:49:08Z",
+ "homeTeam":
+ {
+ "id": 267,
+ "name": "UD Almería",
+ "shortName": "Almería",
+ "tla": "ALM",
+ "crest": "https://crests.football-data.org/267.png"
+ },
+ "awayTeam":
+ {
+ "id": 79,
+ "name": "CA Osasuna",
+ "shortName": "Osasuna",
+ "tla": "OSA",
+ "crest": "https://crests.football-data.org/79.svg"
+ },
+ "score":
+ {
+ "winner": "AWAY_TEAM",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 0,
+ "away": 2
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ [
+ {
+ "id": 206206,
+ "name": "Pablo González Fuertes",
+ "type": "REFEREE",
+ "nationality": "Spain"
+ }
+ ]
+ },
+ {
+ "area":
+ {
+ "id": 2187,
+ "name": "Portugal",
+ "code": "POR",
+ "flag": "https://crests.football-data.org/765.svg"
+ },
+ "competition":
+ {
+ "id": 2017,
+ "name": "Primeira Liga",
+ "code": "PPL",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/PPL.png"
+ },
+ "season":
+ {
+ "id": 1603,
+ "startDate": "2023-08-13",
+ "endDate": "2024-05-19",
+ "currentMatchday": 27,
+ "winner": null
+ },
+ "id": 445644,
+ "utcDate": "2024-03-30T15:30:00Z",
+ "status": "IN_PLAY",
+ "matchday": 27,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T16:49:09Z",
+ "homeTeam":
+ {
+ "id": 5543,
+ "name": "Vitória SC",
+ "shortName": "Vitória SC",
+ "tla": "GUI",
+ "crest": "https://crests.football-data.org/5543.png"
+ },
+ "awayTeam":
+ {
+ "id": 583,
+ "name": "Moreirense FC",
+ "shortName": "Moreirense",
+ "tla": "MOR",
+ "crest": "https://crests.football-data.org/583.png"
+ },
+ "score":
+ {
+ "winner": "DRAW",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 0,
+ "away": 0
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ []
+ },
+ {
+ "area":
+ {
+ "id": 2187,
+ "name": "Portugal",
+ "code": "POR",
+ "flag": "https://crests.football-data.org/765.svg"
+ },
+ "competition":
+ {
+ "id": 2017,
+ "name": "Primeira Liga",
+ "code": "PPL",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/PPL.png"
+ },
+ "season":
+ {
+ "id": 1603,
+ "startDate": "2023-08-13",
+ "endDate": "2024-05-19",
+ "currentMatchday": 27,
+ "winner": null
+ },
+ "id": 445639,
+ "utcDate": "2024-03-30T15:30:00Z",
+ "status": "IN_PLAY",
+ "matchday": 27,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T16:49:08Z",
+ "homeTeam":
+ {
+ "id": 712,
+ "name": "FC Arouca",
+ "shortName": "Arouca",
+ "tla": "FCA",
+ "crest": "https://crests.football-data.org/712.png"
+ },
+ "awayTeam":
+ {
+ "id": 5602,
+ "name": "SC Farense",
+ "shortName": "Farense",
+ "tla": "FAR",
+ "crest": "https://crests.football-data.org/5602.png"
+ },
+ "score":
+ {
+ "winner": "DRAW",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 0,
+ "away": 0
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ []
+ },
+ {
+ "area":
+ {
+ "id": 2163,
+ "name": "Netherlands",
+ "code": "NLD",
+ "flag": "https://crests.football-data.org/8601.svg"
+ },
+ "competition":
+ {
+ "id": 2003,
+ "name": "Eredivisie",
+ "code": "DED",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/ED.png"
+ },
+ "season":
+ {
+ "id": 1590,
+ "startDate": "2023-08-11",
+ "endDate": "2024-05-19",
+ "currentMatchday": 27,
+ "winner": null
+ },
+ "id": 441722,
+ "utcDate": "2024-03-30T15:30:00Z",
+ "status": "IN_PLAY",
+ "matchday": 27,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T16:49:08Z",
+ "homeTeam":
+ {
+ "id": 1915,
+ "name": "NEC",
+ "shortName": "NEC",
+ "tla": "NEC",
+ "crest": "https://crests.football-data.org/1915.png"
+ },
+ "awayTeam":
+ {
+ "id": 674,
+ "name": "PSV",
+ "shortName": "PSV",
+ "tla": "PSV",
+ "crest": "https://crests.football-data.org/674.png"
+ },
+ "score":
+ {
+ "winner": "DRAW",
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": 0,
+ "away": 0
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ [
+ {
+ "id": 56905,
+ "name": "Bas Nijhuis",
+ "type": "REFEREE",
+ "nationality": "Netherlands"
+ }
+ ]
+ },
+ {
+ "area":
+ {
+ "id": 2081,
+ "name": "France",
+ "code": "FRA",
+ "flag": "https://crests.football-data.org/773.svg"
+ },
+ "competition":
+ {
+ "id": 2015,
+ "name": "Ligue 1",
+ "code": "FL1",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/FL1.png"
+ },
+ "season":
+ {
+ "id": 1595,
+ "startDate": "2023-08-13",
+ "endDate": "2024-05-18",
+ "currentMatchday": 27,
+ "winner": null
+ },
+ "id": 442944,
+ "utcDate": "2024-03-30T16:00:00Z",
+ "status": "TIMED",
+ "matchday": 27,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T16:40:18Z",
+ "homeTeam":
+ {
+ "id": 545,
+ "name": "FC Metz",
+ "shortName": "FC Metz",
+ "tla": "FCM",
+ "crest": "https://crests.football-data.org/545.svg"
+ },
+ "awayTeam":
+ {
+ "id": 548,
+ "name": "AS Monaco FC",
+ "shortName": "Monaco",
+ "tla": "ASM",
+ "crest": "https://crests.football-data.org/548.png"
+ },
+ "score":
+ {
+ "winner": null,
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": null,
+ "away": null
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ [
+ {
+ "id": 57092,
+ "name": "Eric Wattellier",
+ "type": "REFEREE",
+ "nationality": "France"
+ }
+ ]
+ },
+ {
+ "area":
+ {
+ "id": 2114,
+ "name": "Italy",
+ "code": "ITA",
+ "flag": "https://crests.football-data.org/784.svg"
+ },
+ "competition":
+ {
+ "id": 2019,
+ "name": "Serie A",
+ "code": "SA",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/SA.png"
+ },
+ "season":
+ {
+ "id": 1600,
+ "startDate": "2023-08-19",
+ "endDate": "2024-05-26",
+ "currentMatchday": 30,
+ "winner": null
+ },
+ "id": 444549,
+ "utcDate": "2024-03-30T17:00:00Z",
+ "status": "TIMED",
+ "matchday": 30,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T10:21:32Z",
+ "homeTeam":
+ {
+ "id": 110,
+ "name": "SS Lazio",
+ "shortName": "Lazio",
+ "tla": "LAZ",
+ "crest": "https://crests.football-data.org/110.svg"
+ },
+ "awayTeam":
+ {
+ "id": 109,
+ "name": "Juventus FC",
+ "shortName": "Juventus",
+ "tla": "JUV",
+ "crest": "https://crests.football-data.org/109.svg"
+ },
+ "score":
+ {
+ "winner": null,
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": null,
+ "away": null
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ []
+ },
+ {
+ "area":
+ {
+ "id": 2088,
+ "name": "Germany",
+ "code": "DEU",
+ "flag": "https://crests.football-data.org/759.svg"
+ },
+ "competition":
+ {
+ "id": 2002,
+ "name": "Bundesliga",
+ "code": "BL1",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/BL1.png"
+ },
+ "season":
+ {
+ "id": 1592,
+ "startDate": "2023-08-18",
+ "endDate": "2024-05-18",
+ "currentMatchday": 27,
+ "winner": null
+ },
+ "id": 442023,
+ "utcDate": "2024-03-30T17:30:00Z",
+ "status": "TIMED",
+ "matchday": 27,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-02-29T15:21:23Z",
+ "homeTeam":
+ {
+ "id": 5,
+ "name": "FC Bayern München",
+ "shortName": "Bayern",
+ "tla": "FCB",
+ "crest": "https://crests.football-data.org/5.svg"
+ },
+ "awayTeam":
+ {
+ "id": 4,
+ "name": "Borussia Dortmund",
+ "shortName": "Dortmund",
+ "tla": "BVB",
+ "crest": "https://crests.football-data.org/4.png"
+ },
+ "score":
+ {
+ "winner": null,
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": null,
+ "away": null
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ []
+ },
+ {
+ "area":
+ {
+ "id": 2072,
+ "name": "England",
+ "code": "ENG",
+ "flag": "https://crests.football-data.org/770.svg"
+ },
+ "competition":
+ {
+ "id": 2021,
+ "name": "Premier League",
+ "code": "PL",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/PL.png"
+ },
+ "season":
+ {
+ "id": 1564,
+ "startDate": "2023-08-11",
+ "endDate": "2024-05-19",
+ "currentMatchday": 30,
+ "winner": null
+ },
+ "id": 436234,
+ "utcDate": "2024-03-30T17:30:00Z",
+ "status": "TIMED",
+ "matchday": 30,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-30T10:21:32Z",
+ "homeTeam":
+ {
+ "id": 58,
+ "name": "Aston Villa FC",
+ "shortName": "Aston Villa",
+ "tla": "AVL",
+ "crest": "https://crests.football-data.org/58.png"
+ },
+ "awayTeam":
+ {
+ "id": 76,
+ "name": "Wolverhampton Wanderers FC",
+ "shortName": "Wolverhampton",
+ "tla": "WOL",
+ "crest": "https://crests.football-data.org/76.svg"
+ },
+ "score":
+ {
+ "winner": null,
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": null,
+ "away": null
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ []
+ },
+ {
+ "area":
+ {
+ "id": 2224,
+ "name": "Spain",
+ "code": "ESP",
+ "flag": "https://crests.football-data.org/760.svg"
+ },
+ "competition":
+ {
+ "id": 2014,
+ "name": "Primera Division",
+ "code": "PD",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/PD.png"
+ },
+ "season":
+ {
+ "id": 1577,
+ "startDate": "2023-08-13",
+ "endDate": "2024-05-26",
+ "currentMatchday": 30,
+ "winner": null
+ },
+ "id": 438770,
+ "utcDate": "2024-03-30T17:30:00Z",
+ "status": "TIMED",
+ "matchday": 30,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-02-27T10:21:25Z",
+ "homeTeam":
+ {
+ "id": 95,
+ "name": "Valencia CF",
+ "shortName": "Valencia",
+ "tla": "VAL",
+ "crest": "https://crests.football-data.org/95.svg"
+ },
+ "awayTeam":
+ {
+ "id": 89,
+ "name": "RCD Mallorca",
+ "shortName": "Mallorca",
+ "tla": "MAL",
+ "crest": "https://crests.football-data.org/89.png"
+ },
+ "score":
+ {
+ "winner": null,
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": null,
+ "away": null
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ []
+ },
+ {
+ "area":
+ {
+ "id": 2163,
+ "name": "Netherlands",
+ "code": "NLD",
+ "flag": "https://crests.football-data.org/8601.svg"
+ },
+ "competition":
+ {
+ "id": 2003,
+ "name": "Eredivisie",
+ "code": "DED",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/ED.png"
+ },
+ "season":
+ {
+ "id": 1590,
+ "startDate": "2023-08-11",
+ "endDate": "2024-05-19",
+ "currentMatchday": 27,
+ "winner": null
+ },
+ "id": 441724,
+ "utcDate": "2024-03-30T17:45:00Z",
+ "status": "TIMED",
+ "matchday": 27,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2023-12-22T20:20:54Z",
+ "homeTeam":
+ {
+ "id": 6806,
+ "name": "Sparta Rotterdam",
+ "shortName": "Sparta",
+ "tla": "SPA",
+ "crest": "https://crests.football-data.org/6806.png"
+ },
+ "awayTeam":
+ {
+ "id": 1920,
+ "name": "Fortuna Sittard",
+ "shortName": "Sittard",
+ "tla": "SIT",
+ "crest": "https://crests.football-data.org/1920.png"
+ },
+ "score":
+ {
+ "winner": null,
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": null,
+ "away": null
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ []
+ },
+ {
+ "area":
+ {
+ "id": 2187,
+ "name": "Portugal",
+ "code": "POR",
+ "flag": "https://crests.football-data.org/765.svg"
+ },
+ "competition":
+ {
+ "id": 2017,
+ "name": "Primeira Liga",
+ "code": "PPL",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/PPL.png"
+ },
+ "season":
+ {
+ "id": 1603,
+ "startDate": "2023-08-13",
+ "endDate": "2024-05-19",
+ "currentMatchday": 27,
+ "winner": null
+ },
+ "id": 445637,
+ "utcDate": "2024-03-30T18:00:00Z",
+ "status": "TIMED",
+ "matchday": 27,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-19T15:21:36Z",
+ "homeTeam":
+ {
+ "id": 810,
+ "name": "Boavista FC",
+ "shortName": "Boavista",
+ "tla": "BOA",
+ "crest": "https://crests.football-data.org/810.png"
+ },
+ "awayTeam":
+ {
+ "id": 496,
+ "name": "Rio Ave FC",
+ "shortName": "Rio Ave",
+ "tla": "RIO",
+ "crest": "https://crests.football-data.org/496.png"
+ },
+ "score":
+ {
+ "winner": null,
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": null,
+ "away": null
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ []
+ },
+ {
+ "area":
+ {
+ "id": 2163,
+ "name": "Netherlands",
+ "code": "NLD",
+ "flag": "https://crests.football-data.org/8601.svg"
+ },
+ "competition":
+ {
+ "id": 2003,
+ "name": "Eredivisie",
+ "code": "DED",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/ED.png"
+ },
+ "season":
+ {
+ "id": 1590,
+ "startDate": "2023-08-11",
+ "endDate": "2024-05-19",
+ "currentMatchday": 27,
+ "winner": null
+ },
+ "id": 441720,
+ "utcDate": "2024-03-30T19:00:00Z",
+ "status": "TIMED",
+ "matchday": 27,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2023-12-22T20:20:54Z",
+ "homeTeam":
+ {
+ "id": 683,
+ "name": "RKC Waalwijk",
+ "shortName": "RKC",
+ "tla": "RKC",
+ "crest": "https://crests.football-data.org/683.png"
+ },
+ "awayTeam":
+ {
+ "id": 673,
+ "name": "SC Heerenveen",
+ "shortName": "Heerenveen",
+ "tla": "HEE",
+ "crest": "https://crests.football-data.org/673.png"
+ },
+ "score":
+ {
+ "winner": null,
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": null,
+ "away": null
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ []
+ },
+ {
+ "area":
+ {
+ "id": 2163,
+ "name": "Netherlands",
+ "code": "NLD",
+ "flag": "https://crests.football-data.org/8601.svg"
+ },
+ "competition":
+ {
+ "id": 2003,
+ "name": "Eredivisie",
+ "code": "DED",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/ED.png"
+ },
+ "season":
+ {
+ "id": 1590,
+ "startDate": "2023-08-11",
+ "endDate": "2024-05-19",
+ "currentMatchday": 27,
+ "winner": null
+ },
+ "id": 441717,
+ "utcDate": "2024-03-30T19:00:00Z",
+ "status": "TIMED",
+ "matchday": 27,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2023-12-22T20:20:54Z",
+ "homeTeam":
+ {
+ "id": 718,
+ "name": "Go Ahead Eagles",
+ "shortName": "Go Ahead",
+ "tla": "GOA",
+ "crest": "https://crests.football-data.org/718.png"
+ },
+ "awayTeam":
+ {
+ "id": 670,
+ "name": "SBV Excelsior",
+ "shortName": "Excelsior",
+ "tla": "EXC",
+ "crest": "https://crests.football-data.org/670.png"
+ },
+ "score":
+ {
+ "winner": null,
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": null,
+ "away": null
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ []
+ },
+ {
+ "area":
+ {
+ "id": 2114,
+ "name": "Italy",
+ "code": "ITA",
+ "flag": "https://crests.football-data.org/784.svg"
+ },
+ "competition":
+ {
+ "id": 2019,
+ "name": "Serie A",
+ "code": "SA",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/SA.png"
+ },
+ "season":
+ {
+ "id": 1600,
+ "startDate": "2023-08-19",
+ "endDate": "2024-05-26",
+ "currentMatchday": 30,
+ "winner": null
+ },
+ "id": 444546,
+ "utcDate": "2024-03-30T19:45:00Z",
+ "status": "TIMED",
+ "matchday": 30,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-02-27T10:21:25Z",
+ "homeTeam":
+ {
+ "id": 99,
+ "name": "ACF Fiorentina",
+ "shortName": "Fiorentina",
+ "tla": "FIO",
+ "crest": "https://crests.football-data.org/99.svg"
+ },
+ "awayTeam":
+ {
+ "id": 98,
+ "name": "AC Milan",
+ "shortName": "Milan",
+ "tla": "MIL",
+ "crest": "https://crests.football-data.org/98.svg"
+ },
+ "score":
+ {
+ "winner": null,
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": null,
+ "away": null
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ []
+ },
+ {
+ "area":
+ {
+ "id": 2081,
+ "name": "France",
+ "code": "FRA",
+ "flag": "https://crests.football-data.org/773.svg"
+ },
+ "competition":
+ {
+ "id": 2015,
+ "name": "Ligue 1",
+ "code": "FL1",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/FL1.png"
+ },
+ "season":
+ {
+ "id": 1595,
+ "startDate": "2023-08-13",
+ "endDate": "2024-05-18",
+ "currentMatchday": 27,
+ "winner": null
+ },
+ "id": 442947,
+ "utcDate": "2024-03-30T20:00:00Z",
+ "status": "TIMED",
+ "matchday": 27,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-10T05:21:21Z",
+ "homeTeam":
+ {
+ "id": 523,
+ "name": "Olympique Lyonnais",
+ "shortName": "Olympique Lyon",
+ "tla": "LYO",
+ "crest": "https://crests.football-data.org/523.svg"
+ },
+ "awayTeam":
+ {
+ "id": 547,
+ "name": "Stade de Reims",
+ "shortName": "Stade de Reims",
+ "tla": "SDR",
+ "crest": "https://crests.football-data.org/547.png"
+ },
+ "score":
+ {
+ "winner": null,
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": null,
+ "away": null
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ []
+ },
+ {
+ "area":
+ {
+ "id": 2072,
+ "name": "England",
+ "code": "ENG",
+ "flag": "https://crests.football-data.org/770.svg"
+ },
+ "competition":
+ {
+ "id": 2021,
+ "name": "Premier League",
+ "code": "PL",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/PL.png"
+ },
+ "season":
+ {
+ "id": 1564,
+ "startDate": "2023-08-11",
+ "endDate": "2024-05-19",
+ "currentMatchday": 30,
+ "winner": null
+ },
+ "id": 436235,
+ "utcDate": "2024-03-30T20:00:00Z",
+ "status": "TIMED",
+ "matchday": 30,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-02-06T10:21:19Z",
+ "homeTeam":
+ {
+ "id": 402,
+ "name": "Brentford FC",
+ "shortName": "Brentford",
+ "tla": "BRE",
+ "crest": "https://crests.football-data.org/402.png"
+ },
+ "awayTeam":
+ {
+ "id": 66,
+ "name": "Manchester United FC",
+ "shortName": "Man United",
+ "tla": "MUN",
+ "crest": "https://crests.football-data.org/66.png"
+ },
+ "score":
+ {
+ "winner": null,
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": null,
+ "away": null
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ []
+ },
+ {
+ "area":
+ {
+ "id": 2224,
+ "name": "Spain",
+ "code": "ESP",
+ "flag": "https://crests.football-data.org/760.svg"
+ },
+ "competition":
+ {
+ "id": 2014,
+ "name": "Primera Division",
+ "code": "PD",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/PD.png"
+ },
+ "season":
+ {
+ "id": 1577,
+ "startDate": "2023-08-13",
+ "endDate": "2024-05-26",
+ "currentMatchday": 30,
+ "winner": null
+ },
+ "id": 438766,
+ "utcDate": "2024-03-30T20:00:00Z",
+ "status": "TIMED",
+ "matchday": 30,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-02-27T10:21:25Z",
+ "homeTeam":
+ {
+ "id": 81,
+ "name": "FC Barcelona",
+ "shortName": "Barça",
+ "tla": "FCB",
+ "crest": "https://crests.football-data.org/81.svg"
+ },
+ "awayTeam":
+ {
+ "id": 275,
+ "name": "UD Las Palmas",
+ "shortName": "Las Palmas",
+ "tla": "LPA",
+ "crest": "https://crests.football-data.org/275.png"
+ },
+ "score":
+ {
+ "winner": null,
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": null,
+ "away": null
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ []
+ },
+ {
+ "area":
+ {
+ "id": 2163,
+ "name": "Netherlands",
+ "code": "NLD",
+ "flag": "https://crests.football-data.org/8601.svg"
+ },
+ "competition":
+ {
+ "id": 2003,
+ "name": "Eredivisie",
+ "code": "DED",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/ED.png"
+ },
+ "season":
+ {
+ "id": 1590,
+ "startDate": "2023-08-11",
+ "endDate": "2024-05-19",
+ "currentMatchday": 27,
+ "winner": null
+ },
+ "id": 441719,
+ "utcDate": "2024-03-30T20:00:00Z",
+ "status": "TIMED",
+ "matchday": 27,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2023-12-22T20:20:54Z",
+ "homeTeam":
+ {
+ "id": 682,
+ "name": "AZ",
+ "shortName": "AZ",
+ "tla": "AZ",
+ "crest": "https://crests.football-data.org/682.png"
+ },
+ "awayTeam":
+ {
+ "id": 679,
+ "name": "SBV Vitesse",
+ "shortName": "Vitesse",
+ "tla": "VIT",
+ "crest": "https://crests.football-data.org/679.png"
+ },
+ "score":
+ {
+ "winner": null,
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": null,
+ "away": null
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ []
+ },
+ {
+ "area":
+ {
+ "id": 2187,
+ "name": "Portugal",
+ "code": "POR",
+ "flag": "https://crests.football-data.org/765.svg"
+ },
+ "competition":
+ {
+ "id": 2017,
+ "name": "Primeira Liga",
+ "code": "PPL",
+ "type": "LEAGUE",
+ "emblem": "https://crests.football-data.org/PPL.png"
+ },
+ "season":
+ {
+ "id": 1603,
+ "startDate": "2023-08-13",
+ "endDate": "2024-05-19",
+ "currentMatchday": 27,
+ "winner": null
+ },
+ "id": 445641,
+ "utcDate": "2024-03-30T20:30:00Z",
+ "status": "TIMED",
+ "matchday": 27,
+ "stage": "REGULAR_SEASON",
+ "group": null,
+ "lastUpdated": "2024-03-19T15:21:36Z",
+ "homeTeam":
+ {
+ "id": 582,
+ "name": "GD Estoril Praia",
+ "shortName": "Estoril Praia",
+ "tla": "EST",
+ "crest": "https://crests.football-data.org/582.png"
+ },
+ "awayTeam":
+ {
+ "id": 503,
+ "name": "FC Porto",
+ "shortName": "Porto",
+ "tla": "FCP",
+ "crest": "https://crests.football-data.org/503.png"
+ },
+ "score":
+ {
+ "winner": null,
+ "duration": "REGULAR",
+ "fullTime":
+ {
+ "home": null,
+ "away": null
+ },
+ "halfTime":
+ {
+ "home": null,
+ "away": null
+ }
+ },
+ "odds":
+ {
+ "msg": "Activate Odds-Package in User-Panel to retrieve odds."
+ },
+ "referees":
+ []
+ }
+ ]
+}
\ No newline at end of file
From 0f5501d5bef4ec33555938e147a923b213f58d9a Mon Sep 17 00:00:00 2001
From: Vincenzo Garambone
Date: Sat, 30 Mar 2024 18:49:15 +0100
Subject: [PATCH 2/6] refactor, add tests
---
.../client/FootballDataOrgClient.java | 2 +-
.../sports/football/model/match/Area.java | 3 ++
.../football/model/match/Competition.java | 3 ++
.../sports/football/model/match/Match.java | 2 +
.../sports/football/model/match/Score.java | 3 ++
.../sports/football/model/match/Team.java | 3 ++
...itory.java => FootballDataRepository.java} | 5 ++-
...va => InMemoryFootballDataRepository.java} | 14 ++++---
.../scheduled/FootballDataScheduledTask.java | 31 ++++++++++++++
.../retrosearch/PrimaryTestConfiguration.java | 17 ++++++++
.../InMemoryFootballDataRepositoryTest.java | 40 +++++++++++++++++++
.../sports/{sports => football}/response.json | 0
12 files changed, 114 insertions(+), 9 deletions(-)
rename src/main/java/it/garambo/retrosearch/sports/football/repository/{SportsRepository.java => FootballDataRepository.java} (70%)
rename src/main/java/it/garambo/retrosearch/sports/football/repository/{InMemorySportsRepository.java => InMemoryFootballDataRepository.java} (65%)
create mode 100644 src/main/java/it/garambo/retrosearch/sports/football/scheduled/FootballDataScheduledTask.java
create mode 100644 src/test/java/it/garambo/retrosearch/PrimaryTestConfiguration.java
create mode 100644 src/test/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballDataRepositoryTest.java
rename src/test/resources/sports/{sports => football}/response.json (100%)
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/client/FootballDataOrgClient.java b/src/main/java/it/garambo/retrosearch/sports/football/client/FootballDataOrgClient.java
index fbf08da..9100023 100644
--- a/src/main/java/it/garambo/retrosearch/sports/football/client/FootballDataOrgClient.java
+++ b/src/main/java/it/garambo/retrosearch/sports/football/client/FootballDataOrgClient.java
@@ -24,7 +24,7 @@ public class FootballDataOrgClient {
@Autowired HttpService httpService;
- public FootballDataResponse getFootballData() throws IOException, URISyntaxException {
+ public FootballDataResponse fetchFootballData() throws IOException, URISyntaxException {
URI apiUri = new URI(API_URL);
BasicHeader apiKeyHeader = new BasicHeader("X-Auth-Token", apiKey);
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/model/match/Area.java b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Area.java
index d5eafc5..56ceba9 100644
--- a/src/main/java/it/garambo/retrosearch/sports/football/model/match/Area.java
+++ b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Area.java
@@ -1,3 +1,6 @@
package it.garambo.retrosearch.sports.football.model.match;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
public record Area(int id, String name, String code) {}
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/model/match/Competition.java b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Competition.java
index 3af9755..3b3f77a 100644
--- a/src/main/java/it/garambo/retrosearch/sports/football/model/match/Competition.java
+++ b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Competition.java
@@ -1,3 +1,6 @@
package it.garambo.retrosearch.sports.football.model.match;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
public record Competition(int id, String name, String code) {}
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/model/match/Match.java b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Match.java
index 4053941..08b50e0 100644
--- a/src/main/java/it/garambo/retrosearch/sports/football/model/match/Match.java
+++ b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Match.java
@@ -1,9 +1,11 @@
package it.garambo.retrosearch.sports.football.model.match;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import it.garambo.retrosearch.sports.football.model.match.enums.Status;
import java.util.Date;
import org.jetbrains.annotations.NotNull;
+@JsonIgnoreProperties(ignoreUnknown = true)
public record Match(
int id,
Date utcDate,
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/model/match/Score.java b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Score.java
index cc68116..c8d2116 100644
--- a/src/main/java/it/garambo/retrosearch/sports/football/model/match/Score.java
+++ b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Score.java
@@ -1,3 +1,6 @@
package it.garambo.retrosearch.sports.football.model.match;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
public record Score(HomeAwayScore halfTime, HomeAwayScore fullTime) {}
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/model/match/Team.java b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Team.java
index 5b67378..15796ea 100644
--- a/src/main/java/it/garambo/retrosearch/sports/football/model/match/Team.java
+++ b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Team.java
@@ -1,3 +1,6 @@
package it.garambo.retrosearch.sports.football.model.match;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
public record Team(int id, String name, String shortName) {}
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/repository/SportsRepository.java b/src/main/java/it/garambo/retrosearch/sports/football/repository/FootballDataRepository.java
similarity index 70%
rename from src/main/java/it/garambo/retrosearch/sports/football/repository/SportsRepository.java
rename to src/main/java/it/garambo/retrosearch/sports/football/repository/FootballDataRepository.java
index d07ab0b..46da8d2 100644
--- a/src/main/java/it/garambo/retrosearch/sports/football/repository/SportsRepository.java
+++ b/src/main/java/it/garambo/retrosearch/sports/football/repository/FootballDataRepository.java
@@ -2,13 +2,14 @@
import it.garambo.retrosearch.sports.football.model.match.Match;
import java.util.Date;
+import java.util.List;
import java.util.Set;
-public interface SportsRepository {
+public interface FootballDataRepository {
Set getAllMatchesByArea(String areaName);
- void updateAll(Set newMatches);
+ void updateAll(List newMatches);
Date getUpdatedAt();
}
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/repository/InMemorySportsRepository.java b/src/main/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballDataRepository.java
similarity index 65%
rename from src/main/java/it/garambo/retrosearch/sports/football/repository/InMemorySportsRepository.java
rename to src/main/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballDataRepository.java
index 1f47834..e595d19 100644
--- a/src/main/java/it/garambo/retrosearch/sports/football/repository/InMemorySportsRepository.java
+++ b/src/main/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballDataRepository.java
@@ -9,9 +9,9 @@
@Slf4j
@Component
@ConditionalOnProperty(value = "retrosearch.sports.football.enable", havingValue = "true")
-public class InMemorySportsRepository implements SportsRepository {
+public class InMemoryFootballDataRepository implements FootballDataRepository {
- Map> matchByArea;
+ private Map> matchByArea;
private Date updatedAt;
@Override
@@ -20,15 +20,17 @@ public Set getAllMatchesByArea(String areaName) {
}
@Override
- public void updateAll(Set newMatches) {
- matchByArea.clear();
+ public void updateAll(List newMatches) {
+ Map> updatedMatches = new HashMap<>();
newMatches.forEach(
match -> {
String areaName = match.area().name();
- matchByArea.putIfAbsent(areaName, Set.of());
- matchByArea.get(areaName).add(match);
+ updatedMatches.putIfAbsent(areaName, new HashSet<>());
+ updatedMatches.get(areaName).add(match);
});
log.info("Football Results updated");
+ matchByArea = updatedMatches;
+ updatedAt = new Date();
}
@Override
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/scheduled/FootballDataScheduledTask.java b/src/main/java/it/garambo/retrosearch/sports/football/scheduled/FootballDataScheduledTask.java
new file mode 100644
index 0000000..7c856e7
--- /dev/null
+++ b/src/main/java/it/garambo/retrosearch/sports/football/scheduled/FootballDataScheduledTask.java
@@ -0,0 +1,31 @@
+package it.garambo.retrosearch.sports.football.scheduled;
+
+import it.garambo.retrosearch.sports.football.client.FootballDataOrgClient;
+import it.garambo.retrosearch.sports.football.model.FootballDataResponse;
+import it.garambo.retrosearch.sports.football.repository.FootballDataRepository;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+@ConditionalOnProperty(value = "retrosearch.news.enable", havingValue = "true")
+public class FootballDataScheduledTask {
+
+ @Autowired private FootballDataOrgClient apiClient;
+
+ @Autowired private FootballDataRepository repository;
+
+ @Scheduled(fixedRate = 30 * 60 * 1000)
+ private void updateFootballData() {
+ try {
+ log.info("Updating article lists...");
+ FootballDataResponse footballData = apiClient.fetchFootballData();
+ repository.updateAll(footballData.matches());
+ } catch (Exception e) {
+ log.error("Article list update failed:", e);
+ }
+ }
+}
diff --git a/src/test/java/it/garambo/retrosearch/PrimaryTestConfiguration.java b/src/test/java/it/garambo/retrosearch/PrimaryTestConfiguration.java
new file mode 100644
index 0000000..3687b1b
--- /dev/null
+++ b/src/test/java/it/garambo/retrosearch/PrimaryTestConfiguration.java
@@ -0,0 +1,17 @@
+package it.garambo.retrosearch;
+
+import it.garambo.retrosearch.sports.football.repository.FootballDataRepository;
+import it.garambo.retrosearch.sports.football.repository.InMemoryFootballDataRepository;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+
+@TestConfiguration
+public class PrimaryTestConfiguration {
+
+ @Bean
+ @Primary
+ public FootballDataRepository repository() {
+ return new InMemoryFootballDataRepository();
+ }
+}
diff --git a/src/test/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballDataRepositoryTest.java b/src/test/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballDataRepositoryTest.java
new file mode 100644
index 0000000..9440ef8
--- /dev/null
+++ b/src/test/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballDataRepositoryTest.java
@@ -0,0 +1,40 @@
+package it.garambo.retrosearch.sports.football.repository;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import it.garambo.retrosearch.PrimaryTestConfiguration;
+import it.garambo.retrosearch.sports.football.model.FootballDataResponse;
+import it.garambo.retrosearch.sports.football.model.match.Match;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Set;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.core.io.Resource;
+
+@SpringBootTest(classes = PrimaryTestConfiguration.class)
+@ExtendWith(MockitoExtension.class)
+class InMemoryFootballDataRepositoryTest {
+
+ @Autowired FootballDataRepository repository;
+
+ @Test
+ void testUpdate(@Value("classpath:sports/football/response.json") Resource responseJson)
+ throws IOException {
+ String content = responseJson.getContentAsString(StandardCharsets.UTF_8);
+ FootballDataResponse response =
+ new ObjectMapper().readValue(content, FootballDataResponse.class);
+ assertNotNull(response);
+ repository.updateAll(response.matches());
+ assertNotNull(repository.getUpdatedAt());
+
+ Set italianMatches = repository.getAllMatchesByArea("Italy");
+ assertEquals(5, italianMatches.size());
+ }
+}
diff --git a/src/test/resources/sports/sports/response.json b/src/test/resources/sports/football/response.json
similarity index 100%
rename from src/test/resources/sports/sports/response.json
rename to src/test/resources/sports/football/response.json
From 59eb4f070bb02c8b0c07e681e9ed295932b8d1f8 Mon Sep 17 00:00:00 2001
From: Vincenzo Garambone
Date: Sat, 30 Mar 2024 19:08:44 +0100
Subject: [PATCH 3/6] refactor, add template/controller
---
.../controller/FootballController.java | 22 ++++++++++++++
.../sports/football/model/match/Match.java | 2 ++
...epository.java => FootballRepository.java} | 5 +++-
...y.java => InMemoryFootballRepository.java} | 13 +++++---
...edTask.java => FootballScheduledTask.java} | 6 ++--
src/main/resources/templates/football.html | 30 +++++++++++++++++++
.../retrosearch/PrimaryTestConfiguration.java | 8 ++---
...va => InMemoryFootballRepositoryTest.java} | 12 +++++---
8 files changed, 82 insertions(+), 16 deletions(-)
create mode 100644 src/main/java/it/garambo/retrosearch/controller/FootballController.java
rename src/main/java/it/garambo/retrosearch/sports/football/repository/{FootballDataRepository.java => FootballRepository.java} (75%)
rename src/main/java/it/garambo/retrosearch/sports/football/repository/{InMemoryFootballDataRepository.java => InMemoryFootballRepository.java} (77%)
rename src/main/java/it/garambo/retrosearch/sports/football/scheduled/{FootballDataScheduledTask.java => FootballScheduledTask.java} (90%)
create mode 100644 src/main/resources/templates/football.html
rename src/test/java/it/garambo/retrosearch/sports/football/repository/{InMemoryFootballDataRepositoryTest.java => InMemoryFootballRepositoryTest.java} (81%)
diff --git a/src/main/java/it/garambo/retrosearch/controller/FootballController.java b/src/main/java/it/garambo/retrosearch/controller/FootballController.java
new file mode 100644
index 0000000..ee4648d
--- /dev/null
+++ b/src/main/java/it/garambo/retrosearch/controller/FootballController.java
@@ -0,0 +1,22 @@
+package it.garambo.retrosearch.controller;
+
+import it.garambo.retrosearch.sports.football.repository.FootballRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+
+@Controller
+@ConditionalOnBean(FootballRepository.class)
+public class FootballController {
+
+ @Autowired private FootballRepository footballRepository;
+
+ @GetMapping(path = {"/football", "/sports/football"})
+ public String football(Model model) {
+ model.addAttribute("updatedAt", footballRepository.getUpdatedAt());
+ model.addAttribute("results", footballRepository.getAllMatches());
+ return "football";
+ }
+}
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/model/match/Match.java b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Match.java
index 08b50e0..5773835 100644
--- a/src/main/java/it/garambo/retrosearch/sports/football/model/match/Match.java
+++ b/src/main/java/it/garambo/retrosearch/sports/football/model/match/Match.java
@@ -13,6 +13,8 @@ public record Match(
Area area,
Status status,
Competition competition,
+ Team homeTeam,
+ Team awayTeam,
Score score)
implements Comparable {
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/repository/FootballDataRepository.java b/src/main/java/it/garambo/retrosearch/sports/football/repository/FootballRepository.java
similarity index 75%
rename from src/main/java/it/garambo/retrosearch/sports/football/repository/FootballDataRepository.java
rename to src/main/java/it/garambo/retrosearch/sports/football/repository/FootballRepository.java
index 46da8d2..f59bbc7 100644
--- a/src/main/java/it/garambo/retrosearch/sports/football/repository/FootballDataRepository.java
+++ b/src/main/java/it/garambo/retrosearch/sports/football/repository/FootballRepository.java
@@ -3,9 +3,12 @@
import it.garambo.retrosearch.sports.football.model.match.Match;
import java.util.Date;
import java.util.List;
+import java.util.Map;
import java.util.Set;
-public interface FootballDataRepository {
+public interface FootballRepository {
+
+ Map> getAllMatches();
Set getAllMatchesByArea(String areaName);
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballDataRepository.java b/src/main/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballRepository.java
similarity index 77%
rename from src/main/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballDataRepository.java
rename to src/main/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballRepository.java
index e595d19..d259bcd 100644
--- a/src/main/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballDataRepository.java
+++ b/src/main/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballRepository.java
@@ -9,14 +9,19 @@
@Slf4j
@Component
@ConditionalOnProperty(value = "retrosearch.sports.football.enable", havingValue = "true")
-public class InMemoryFootballDataRepository implements FootballDataRepository {
+public class InMemoryFootballRepository implements FootballRepository {
- private Map> matchByArea;
+ private Map> matchesByArea;
private Date updatedAt;
+ @Override
+ public Map> getAllMatches() {
+ return matchesByArea;
+ }
+
@Override
public Set getAllMatchesByArea(String areaName) {
- return matchByArea.get(areaName);
+ return matchesByArea.get(areaName);
}
@Override
@@ -29,7 +34,7 @@ public void updateAll(List newMatches) {
updatedMatches.get(areaName).add(match);
});
log.info("Football Results updated");
- matchByArea = updatedMatches;
+ matchesByArea = updatedMatches;
updatedAt = new Date();
}
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/scheduled/FootballDataScheduledTask.java b/src/main/java/it/garambo/retrosearch/sports/football/scheduled/FootballScheduledTask.java
similarity index 90%
rename from src/main/java/it/garambo/retrosearch/sports/football/scheduled/FootballDataScheduledTask.java
rename to src/main/java/it/garambo/retrosearch/sports/football/scheduled/FootballScheduledTask.java
index 7c856e7..5dc7480 100644
--- a/src/main/java/it/garambo/retrosearch/sports/football/scheduled/FootballDataScheduledTask.java
+++ b/src/main/java/it/garambo/retrosearch/sports/football/scheduled/FootballScheduledTask.java
@@ -2,7 +2,7 @@
import it.garambo.retrosearch.sports.football.client.FootballDataOrgClient;
import it.garambo.retrosearch.sports.football.model.FootballDataResponse;
-import it.garambo.retrosearch.sports.football.repository.FootballDataRepository;
+import it.garambo.retrosearch.sports.football.repository.FootballRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -12,11 +12,11 @@
@Slf4j
@Component
@ConditionalOnProperty(value = "retrosearch.news.enable", havingValue = "true")
-public class FootballDataScheduledTask {
+public class FootballScheduledTask {
@Autowired private FootballDataOrgClient apiClient;
- @Autowired private FootballDataRepository repository;
+ @Autowired private FootballRepository repository;
@Scheduled(fixedRate = 30 * 60 * 1000)
private void updateFootballData() {
diff --git a/src/main/resources/templates/football.html b/src/main/resources/templates/football.html
new file mode 100644
index 0000000..bc4f303
--- /dev/null
+++ b/src/main/resources/templates/football.html
@@ -0,0 +1,30 @@
+
+
+
+ RetroSearch Sports - Football
+
+
+
+Latest Football Results
+Updated:
+
+
+Results from football-data.org
+
+
+
+
\ No newline at end of file
diff --git a/src/test/java/it/garambo/retrosearch/PrimaryTestConfiguration.java b/src/test/java/it/garambo/retrosearch/PrimaryTestConfiguration.java
index 3687b1b..a98e3f2 100644
--- a/src/test/java/it/garambo/retrosearch/PrimaryTestConfiguration.java
+++ b/src/test/java/it/garambo/retrosearch/PrimaryTestConfiguration.java
@@ -1,7 +1,7 @@
package it.garambo.retrosearch;
-import it.garambo.retrosearch.sports.football.repository.FootballDataRepository;
-import it.garambo.retrosearch.sports.football.repository.InMemoryFootballDataRepository;
+import it.garambo.retrosearch.sports.football.repository.FootballRepository;
+import it.garambo.retrosearch.sports.football.repository.InMemoryFootballRepository;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
@@ -11,7 +11,7 @@ public class PrimaryTestConfiguration {
@Bean
@Primary
- public FootballDataRepository repository() {
- return new InMemoryFootballDataRepository();
+ public FootballRepository repository() {
+ return new InMemoryFootballRepository();
}
}
diff --git a/src/test/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballDataRepositoryTest.java b/src/test/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballRepositoryTest.java
similarity index 81%
rename from src/test/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballDataRepositoryTest.java
rename to src/test/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballRepositoryTest.java
index 9440ef8..2fad000 100644
--- a/src/test/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballDataRepositoryTest.java
+++ b/src/test/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballRepositoryTest.java
@@ -1,7 +1,6 @@
package it.garambo.retrosearch.sports.football.repository;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import it.garambo.retrosearch.PrimaryTestConfiguration;
@@ -9,6 +8,7 @@
import it.garambo.retrosearch.sports.football.model.match.Match;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.util.Map;
import java.util.Set;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -20,9 +20,9 @@
@SpringBootTest(classes = PrimaryTestConfiguration.class)
@ExtendWith(MockitoExtension.class)
-class InMemoryFootballDataRepositoryTest {
+class InMemoryFootballRepositoryTest {
- @Autowired FootballDataRepository repository;
+ @Autowired FootballRepository repository;
@Test
void testUpdate(@Value("classpath:sports/football/response.json") Resource responseJson)
@@ -34,6 +34,10 @@ void testUpdate(@Value("classpath:sports/football/response.json") Resource respo
repository.updateAll(response.matches());
assertNotNull(repository.getUpdatedAt());
+ Map> matches = repository.getAllMatches();
+ assertEquals(7, matches.keySet().size());
+ assertTrue(matches.containsKey("Italy"));
+
Set italianMatches = repository.getAllMatchesByArea("Italy");
assertEquals(5, italianMatches.size());
}
From fe6d2d03bb630f0d1ebe3c4c8fff6f3d4bd4d6a0 Mon Sep 17 00:00:00 2001
From: Vincenzo Garambone
Date: Sat, 30 Mar 2024 19:17:17 +0100
Subject: [PATCH 4/6] add basic templating
---
...lScheduledTask.java => FootballDataScheduledTask.java} | 8 ++++----
src/main/resources/templates/error.html | 2 +-
src/main/resources/templates/football.html | 5 ++---
3 files changed, 7 insertions(+), 8 deletions(-)
rename src/main/java/it/garambo/retrosearch/sports/football/scheduled/{FootballScheduledTask.java => FootballDataScheduledTask.java} (79%)
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/scheduled/FootballScheduledTask.java b/src/main/java/it/garambo/retrosearch/sports/football/scheduled/FootballDataScheduledTask.java
similarity index 79%
rename from src/main/java/it/garambo/retrosearch/sports/football/scheduled/FootballScheduledTask.java
rename to src/main/java/it/garambo/retrosearch/sports/football/scheduled/FootballDataScheduledTask.java
index 5dc7480..f53899b 100644
--- a/src/main/java/it/garambo/retrosearch/sports/football/scheduled/FootballScheduledTask.java
+++ b/src/main/java/it/garambo/retrosearch/sports/football/scheduled/FootballDataScheduledTask.java
@@ -11,8 +11,8 @@
@Slf4j
@Component
-@ConditionalOnProperty(value = "retrosearch.news.enable", havingValue = "true")
-public class FootballScheduledTask {
+@ConditionalOnProperty(value = "retrosearch.sports.football.enable", havingValue = "true")
+public class FootballDataScheduledTask {
@Autowired private FootballDataOrgClient apiClient;
@@ -21,11 +21,11 @@ public class FootballScheduledTask {
@Scheduled(fixedRate = 30 * 60 * 1000)
private void updateFootballData() {
try {
- log.info("Updating article lists...");
+ log.info("Updating football result list...");
FootballDataResponse footballData = apiClient.fetchFootballData();
repository.updateAll(footballData.matches());
} catch (Exception e) {
- log.error("Article list update failed:", e);
+ log.error("Football result list update failed:", e);
}
}
}
diff --git a/src/main/resources/templates/error.html b/src/main/resources/templates/error.html
index 1eb7e4e..ec8285e 100644
--- a/src/main/resources/templates/error.html
+++ b/src/main/resources/templates/error.html
@@ -6,7 +6,7 @@
Error - RetroSearch
Sorry, something went wrong :(
-
+
Go Back
diff --git a/src/main/resources/templates/football.html b/src/main/resources/templates/football.html
index bc4f303..37bbbde 100644
--- a/src/main/resources/templates/football.html
+++ b/src/main/resources/templates/football.html
@@ -9,14 +9,13 @@ Latest Football Results
Updated:
-
-
+
From a44ea1505dad11ca70721de2c1b0ed29a3048144 Mon Sep 17 00:00:00 2001
From: Vincenzo Garambone
Date: Sun, 31 Mar 2024 11:17:04 +0200
Subject: [PATCH 5/6] Template updates
---
src/main/resources/templates/football.html | 21 ++++++++++++-------
.../resources/templates/fragments/footer.html | 1 +
.../resources/templates/fragments/header.html | 10 ++++-----
3 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/src/main/resources/templates/football.html b/src/main/resources/templates/football.html
index 37bbbde..2df701d 100644
--- a/src/main/resources/templates/football.html
+++ b/src/main/resources/templates/football.html
@@ -5,24 +5,31 @@
-
Latest Football Results
+Latest football results
Updated:
-
-
-
-
-
-
-
+
+ -
+
+
+
+
+
+ :
+
+
+
+
-Results from football-data.org
+Data from football-data.org
diff --git a/src/main/resources/templates/fragments/footer.html b/src/main/resources/templates/fragments/footer.html
index 8621d52..fa064f7 100644
--- a/src/main/resources/templates/fragments/footer.html
+++ b/src/main/resources/templates/fragments/footer.html
@@ -3,6 +3,7 @@
RetroSearch is an open source project built by @garambo
| Search results from DuckDuckGo
+Search and Browse the WWW like it's 1997
HTML:
diff --git a/src/main/resources/templates/fragments/header.html b/src/main/resources/templates/fragments/header.html
index 5b76f54..b0412a1 100644
--- a/src/main/resources/templates/fragments/header.html
+++ b/src/main/resources/templates/fragments/header.html
@@ -1,12 +1,10 @@
-Search and Browse the WWW like it's 1997
+
+
+
-
-
- Check out the latest News!
-
-
\ No newline at end of file
From 974c5197cf1333ef8cc0f9546c3a38c1cc4c15c4 Mon Sep 17 00:00:00 2001
From: Vincenzo Garambone
Date: Sun, 31 Mar 2024 11:23:17 +0200
Subject: [PATCH 6/6] Update Readme, Version, wording
---
README.md | 17 +++++++++++++++++
VERSION | 2 +-
.../repository/InMemoryFootballRepository.java | 2 +-
src/main/resources/templates/football.html | 2 +-
.../resources/templates/fragments/header.html | 2 +-
5 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 9c54897..f67ebdb 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,8 @@ RetroSearch is a Spring Web Application that presents very simple HTML pages whi
It provides the ability to search the Web using DuckDuckGo with a custom scraper that loads the first page of results and allows you to browse pages in plain text.
You can deploy it on your local network and access it from your old computer!
+## News and sports APIs support
+
### Enabling the News API
RetroSearch can fetch news articles by using the GNews API, to allow this, add the environment variables as follows when running the Docker image:
@@ -25,8 +27,23 @@ RetroSearch can fetch news articles by using the GNews API, to allow this, add t
docker run -e NEWS_ACTIVE=true -e NEWS_API_KEY={your GNews API Key} -d -p80:8080 garambo/retrosearch:{Retro Search Version} --restart unless-stopped
```
+### Enabling the football-data.org API
+
+RetroSearch can fetch the latest football scores using the football-data.org API, to allow this, add the environment variables as follows when running the Docker image:
+
+```
+docker run -e FOOTBALL_API_ACTIVE=true -e FOOTBALL_API_KEY={your football-data.org API Key} -d -p80:8080 garambo/retrosearch:{Retro Search Version} --restart unless-stopped
+```
+
+### Enabling both
+
+```
+docker run -e NEWS_ACTIVE=true -e NEWS_API_KEY={your GNews API Key} FOOTBALL_API_ACTIVE=true -e FOOTBALL_API_KEY={your football-data.org API Key} -d -p80:8080 garambo/retrosearch:{Retro Search Version} --restart unless-stopped
+```
+
If running locally, just replace the property values in `application.properties` or create a new Spring run configuration.
+
### WIP
Currently in progress:
- Improve the parsing abilities for the browsing functionality
diff --git a/VERSION b/VERSION
index 616de50..5a2a580 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.5.2-testing
+0.6
diff --git a/src/main/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballRepository.java b/src/main/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballRepository.java
index d259bcd..6134994 100644
--- a/src/main/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballRepository.java
+++ b/src/main/java/it/garambo/retrosearch/sports/football/repository/InMemoryFootballRepository.java
@@ -33,7 +33,7 @@ public void updateAll(List newMatches) {
updatedMatches.putIfAbsent(areaName, new HashSet<>());
updatedMatches.get(areaName).add(match);
});
- log.info("Football Results updated");
+ log.info("Football scores updated");
matchesByArea = updatedMatches;
updatedAt = new Date();
}
diff --git a/src/main/resources/templates/football.html b/src/main/resources/templates/football.html
index 2df701d..9d11f7d 100644
--- a/src/main/resources/templates/football.html
+++ b/src/main/resources/templates/football.html
@@ -5,7 +5,7 @@
-Latest football results
+Latest football scores
Updated:
-
diff --git a/src/main/resources/templates/fragments/header.html b/src/main/resources/templates/fragments/header.html
index b0412a1..be8bfd6 100644
--- a/src/main/resources/templates/fragments/header.html
+++ b/src/main/resources/templates/fragments/header.html
@@ -1,7 +1,7 @@
-
+