Skip to content

Commit

Permalink
Enable image generation on server
Browse files Browse the repository at this point in the history
  • Loading branch information
This-Is-Ko committed Oct 7, 2023
1 parent 0f12b68 commit 928353d
Show file tree
Hide file tree
Showing 12 changed files with 92 additions and 69 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,11 @@ Enable service
# Restart service after file changes
sudo systemctl daemon-reload
sudo systemctl restart football-updater

To set up fonts for image generation, add font files to

/usr/share/fonts/ChakraPetch-Bold.ttf
/usr/share/fonts/Nike_Ithaca.otf

Additional reference for fonts on Linux https://medium.com/source-words/how-to-manually-install-update-and-uninstall-fonts-on-linux-a8d09a3853b0

2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {
}

group = 'com.ko'
version = '0.0.4-SNAPSHOT'
version = '0.0.5-SNAPSHOT'

java {
sourceCompatibility = '20'
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,4 @@ public class PlayerController {
HttpStatus.BAD_REQUEST, "Updating player failed", ex);
}
}

@PostMapping(path="/data-source/update")
public @ResponseBody DataSource updatePlayerDataSource(@RequestBody DataSource dataSource) {
try {
return playerService.updatePlayerDataSource(dataSource);
} catch (Exception ex) {
throw new ResponseStatusException(
HttpStatus.CONFLICT, "Unable to add player", ex);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ public PlayerMatchPerformanceStats parsePlayerMatchData(Player player, Document
}

return new PlayerMatchPerformanceStats(
dataSourceSiteName,
new Match(latestMatchUrl, selectedMatchDate, homeTeam, awayTeam, relevantTeam),
parseIntegerOrNull(resultRow.select("td[data-stat=minutes]").text()),
parseIntegerOrNull(resultRow.select("td[data-stat=goals]").text()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ private PlayerMatchPerformanceStats checkPlayerAndParse(Player player, JsonNode
}

return new PlayerMatchPerformanceStats(
dataSourceSiteName,
match,
getStatIntegerOrDefault(topStats, "Minutes played", 0),
getStatIntegerOrDefault(topStats, "Goals", 0),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
@Getter
public class PlayerMatchPerformanceStats {

private DataSourceSiteName dataSourceSiteName;
private Match match;
private Integer minutesPlayed;
private Integer goals;
Expand Down Expand Up @@ -58,7 +59,8 @@ public class PlayerMatchPerformanceStats {
private Integer gkPenaltiesScoredAgainst;
private Integer gkPenaltiesSaved;

public PlayerMatchPerformanceStats(Match match, Integer minutesPlayed, Integer goals, Integer assists, Integer shots, Integer shotsBlocked, Integer fouls, Integer fouled, Integer offsides, String crossingAccuracyAll, Integer dispossessed, Integer touches, String tacklingSuccessAll, Integer defensiveActions, Integer recoveries, Integer duelsWon, Integer duelsLost, Integer groundDuelsWon, Integer aerialDuelsWon, Integer chancesCreatedAll, String passingAccuracyAll, Integer passesIntoFinalThird, String carriesSuccessAll) {
public PlayerMatchPerformanceStats(DataSourceSiteName dataSourceSiteName, Match match, Integer minutesPlayed, Integer goals, Integer assists, Integer shots, Integer shotsBlocked, Integer fouls, Integer fouled, Integer offsides, String crossingAccuracyAll, Integer dispossessed, Integer touches, String tacklingSuccessAll, Integer defensiveActions, Integer recoveries, Integer duelsWon, Integer duelsLost, Integer groundDuelsWon, Integer aerialDuelsWon, Integer chancesCreatedAll, String passingAccuracyAll, Integer passesIntoFinalThird, String carriesSuccessAll) {
this.dataSourceSiteName = dataSourceSiteName;
this.match = match;
this.minutesPlayed = minutesPlayed;
this.goals = goals;
Expand All @@ -85,7 +87,8 @@ public PlayerMatchPerformanceStats(Match match, Integer minutesPlayed, Integer g
}

// Used by FBREF
public PlayerMatchPerformanceStats(Match match, Integer minutesPlayed, Integer goals, Integer assists, Integer penaltiesScored, Integer penaltiesWon, Integer shots, Integer shotsOnTarget, Integer yellowCards, Integer redCards, Integer fouls, Integer fouled, Integer offsides, Integer crosses, Integer touches, Integer tackles, Integer tacklesWon, Integer interceptions, Integer blocks, Float xg, Float xg_assist, Integer shotCreatingActions, Integer goalCreatingActions, Integer passesCompleted, Integer passesAttempted, Float passesSuccessPercentage, Integer progressivePasses, Integer carries, Integer progressiveCarries, Integer takesOnsAttempted, Integer takesOnsCompleted, Integer gkShotsOnTargetAgainst, Integer gkGoalsAgainst, Integer gkSaves, Float gkSavePercentage, Integer gkPenaltiesAttemptedAgainst, Integer gkPenaltiesScoredAgainst, Integer gkPenaltiesSaved) {
public PlayerMatchPerformanceStats(DataSourceSiteName dataSourceSiteName, Match match, Integer minutesPlayed, Integer goals, Integer assists, Integer penaltiesScored, Integer penaltiesWon, Integer shots, Integer shotsOnTarget, Integer yellowCards, Integer redCards, Integer fouls, Integer fouled, Integer offsides, Integer crosses, Integer touches, Integer tackles, Integer tacklesWon, Integer interceptions, Integer blocks, Float xg, Float xg_assist, Integer shotCreatingActions, Integer goalCreatingActions, Integer passesCompleted, Integer passesAttempted, Float passesSuccessPercentage, Integer progressivePasses, Integer carries, Integer progressiveCarries, Integer takesOnsAttempted, Integer takesOnsCompleted, Integer gkShotsOnTargetAgainst, Integer gkGoalsAgainst, Integer gkSaves, Float gkSavePercentage, Integer gkPenaltiesAttemptedAgainst, Integer gkPenaltiesScoredAgainst, Integer gkPenaltiesSaved) {
this.dataSourceSiteName = dataSourceSiteName;
this.match = match;
this.minutesPlayed = minutesPlayed;
this.goals = goals;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.ko.footballupdater.runners;

import com.ko.footballupdater.configuration.ImageGeneratorProperies;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.io.File;

@Slf4j
@Component
public class FileAccessValidationRunner implements ApplicationRunner {

@Autowired
private ImageGeneratorProperies imageGeneratorProperies;

@Override
public void run(ApplicationArguments args) {
validateFileAccess();
}

public void validateFileAccess() {
File dir = new File(imageGeneratorProperies.getInputPath());
File[] directoryListing = dir.listFiles();
if (directoryListing != null) {
log.info(String.format("Found %d files in input directory", directoryListing.length));
for (File child : directoryListing) {
try {
if (child.exists() && child.canRead()) {
log.debug("File access is valid for " + child.getAbsolutePath());
}
} catch (Exception e) {
log.warn("File access is not valid for " + child.getAbsolutePath());
}
}
log.info("Completed input directory file access check");
} else {
log.warn("Input directory contains no files");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ public boolean sendEmailUpdate(List<InstagramPost> posts){
// Create email body
StringBuilder emailContent = new StringBuilder();
for (InstagramPost post : posts) {
emailContent.append("############").append(post.getPlayer().getName()).append(" - ").append(post.getPlayerMatchPerformanceStats().getMatch().getDateAsFormattedString()).append("############\n\n");
emailContent.append("############").append(post.getPlayer().getName()).append(" - ").append(post.getPlayerMatchPerformanceStats().getDataSourceSiteName().toString()).append(" - ").append(post.getPlayerMatchPerformanceStats().getMatch().getDateAsFormattedString()).append("############\n\n");
emailContent.append(PostHelper.generatePostCaption(instagramPostProperies.getVersion(), post)).append("\n\n");
emailContent.append("Stat image(s)\n").append(PostHelper.generateS3UrlList(post)).append("\n");
if (!post.getImagesS3Urls().isEmpty()) {
emailContent.append("Stat image(s)\n").append(PostHelper.generateS3UrlList(post)).append("\n");
}
emailContent.append("Google image search links\n").append(PostHelper.generatePostImageSearchUrl(post)).append("\n\n\n");

// Add images to attachment - config driven
Expand All @@ -77,7 +79,6 @@ public boolean sendEmailUpdate(List<InstagramPost> posts){
.withTransportStrategy(TransportStrategy.SMTP_TLS)
.withSessionTimeout(10 * 1000)
.clearEmailValidator()
.withDebugLogging(true)
.buildMailer();

mailer.validate(email);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class ImageGeneratorService {
private final int STAT_Y_COORDINATE = 350;
private final String BASE_IMAGE_FILE_NAME = "_base_player_stat_image.jpg";

public void generatePlayerStatImage(InstagramPost post) {
public void generatePlayerStatImage(InstagramPost post) throws Exception {
if (!imageGeneratorProperies.isEnabled()) {
return;
}
Expand All @@ -45,20 +45,19 @@ public void generatePlayerStatImage(InstagramPost post) {

int attributeCounter = 0;
int createdImageCounter = 0;
// Map<String, Object> attributeValueMap = new HashMap<>();
for (Field field : post.getPlayerMatchPerformanceStats().getClass().getDeclaredFields()) {
field.setAccessible(true); // Make the private field accessible
try {
Object value = field.get(post.getPlayerMatchPerformanceStats()); // Get the field's value
if (value != null && !field.getName().equals("match")) {
// Only use stat values which are populated and filter select stats if they are NOT zero
if (value != null && !field.getName().equals("match") && !field.getName().equals("dataSourceSiteName")) {
List<String> zeroValueFilter = getZeroValueFilter();
if (zeroValueFilter.contains(field.getName()) && value.equals(0)) {
continue;
}
// Generate proper stat name - capitalise words and spacing
ImageStatEntry imageStatEntry = generateDisplayedName(field.getName(), value);

// attributeValueMap.put(field.getName(), value);
graphics.drawString(imageStatEntry.getName(), statNameX, statY);
graphics.drawString(imageStatEntry.getValue(), statValueX, statY);
// Shift y coordinate down to next position
Expand Down Expand Up @@ -87,6 +86,7 @@ public void generatePlayerStatImage(InstagramPost post) {
saveImage(post, image, createdImageCounter);
} catch (Exception ex) {
log.warn(post.getPlayer().getName() + " - Error while generating stat image ", ex);
throw new Exception(post.getPlayer().getName() + " - Error while generating stat image ", ex);
}
}

Expand All @@ -110,6 +110,7 @@ private Graphics2D setUpStatsGraphicsDefaults(BufferedImage image) {
Color textColor = Color.BLACK;
graphics.setFont(font);
graphics.setColor(textColor);
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
return graphics;
}

Expand Down Expand Up @@ -162,5 +163,4 @@ private static List<String> getZeroValueFilter() {
zeroValueFilter.add("gkPenaltiesSaved");
return zeroValueFilter;
}

}
29 changes: 18 additions & 11 deletions src/main/java/com/ko/footballupdater/services/PlayerService.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.ko.footballupdater.services;

import com.ko.footballupdater.models.CheckedStatus;
import com.ko.footballupdater.models.DataSource;
import com.ko.footballupdater.models.DataSourceSiteName;
import com.ko.footballupdater.models.InstagramPost;
import com.ko.footballupdater.models.Player;
import com.ko.footballupdater.models.PlayerMatchPerformanceStats;
import com.ko.footballupdater.repositories.PlayerRepository;
import com.ko.footballupdater.repositories.UpdateStatusRepository;
import com.ko.footballupdater.responses.UpdatePlayersResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

Expand All @@ -18,6 +18,7 @@
import java.util.List;
import java.util.Optional;

@Slf4j
@Service
public class PlayerService {

Expand Down Expand Up @@ -93,10 +94,16 @@ public UpdatePlayersResponse updateDataForPlayers(List<Player> requestPlayersToU
}
// Generate post and caption
InstagramPost post = new InstagramPost(player, playerMatchPerformanceStats);
// Generate stat images
imageGeneratorService.generatePlayerStatImage(post);
// Upload stat images to s3
amazonS3Service.uploadtoS3(post);
try {
// Generate stat images
imageGeneratorService.generatePlayerStatImage(post);
// Upload stat images to s3
amazonS3Service.uploadtoS3(post);
} catch (Exception e) {
// Skip if image generation or upload fails, allows future retry
log.warn(post.getPlayer().getName() + " - Unable to generate or upload image");
continue;
}
posts.add(post);
}

Expand All @@ -105,13 +112,14 @@ public UpdatePlayersResponse updateDataForPlayers(List<Player> requestPlayersToU
return response;
}

// Attempt to send email with updates
boolean isEmailSent = emailService.sendEmailUpdate(posts);

response.setEmailSent(isEmailSent);
// Update player checked status if email was sent
if (isEmailSent) {
List<Player> playersToUpdate = new ArrayList<>();
Date currentDateTime = new Date();
// Update player checked status if email was sent
for (InstagramPost post : posts) {
post.getPlayer().getCheckedStatus().setLastChecked(currentDateTime);
post.getPlayer().getCheckedStatus().setLatestCheckedMatchUrl(post.getPlayerMatchPerformanceStats().getMatch().getUrl());
Expand All @@ -126,9 +134,8 @@ public UpdatePlayersResponse updateDataForPlayers(List<Player> requestPlayersToU
return response;
}


public DataSource updatePlayerDataSource(DataSource dataSource) {
// playerRepository.findByNameEquals();
return dataSource;
}
// public DataSource updatePlayerDataSource(DataSource dataSource) {
//// playerRepository.findByNameEquals();
// return dataSource;
// }
}
9 changes: 5 additions & 4 deletions src/main/java/com/ko/footballupdater/utils/PostHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,11 @@ public static String generatePlayerHashtags(Player player, PlayerMatchPerformanc
teamNameHashtag = "#" + playerMatchPerformanceStats.getMatch().getRelevantTeam().replaceAll(" ", "");
}
return "#" + player.getName().replaceAll(" ", "") + " " +
"#upthetillies" + " " +
"#womensfootball" + " " +
"#womenssoccer" + " " +
"#woso" + " " +
"#upthetillies " +
"#matildas " +
"#womensfootball " +
"#womenssoccer" +
"#woso " +
teamNameHashtag;
}

Expand Down

0 comments on commit 928353d

Please sign in to comment.