diff --git a/application/pom.xml b/application/pom.xml index 5b751a75..36456475 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -34,6 +34,11 @@ rssreader ${rssreader.version} + + org.jsoup + jsoup + ${jsoup.version} + diff --git a/application/sissi-modules/debra/pom.xml b/application/sissi-modules/debra/pom.xml index a49ea8d5..fa01fd88 100644 --- a/application/sissi-modules/debra/pom.xml +++ b/application/sissi-modules/debra/pom.xml @@ -15,6 +15,11 @@ com.google.code.gson gson + + dev.sheldan.abstracto.scheduling + scheduling-int + ${abstracto.version} + org.springframework.boot spring-boot-starter-web @@ -28,6 +33,10 @@ org.springframework spring-context-support + + org.jsoup + jsoup + diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/api/DebraDonationStatusController.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/api/DebraDonationStatusController.java index 0fb2b607..772f0f03 100644 --- a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/api/DebraDonationStatusController.java +++ b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/api/DebraDonationStatusController.java @@ -9,8 +9,6 @@ import org.springframework.web.bind.annotation.RestController; import java.util.List; -import static dev.sheldan.sissi.module.debra.config.DebraFeatureConfig.DEBRA_DONATION_NOTIFICATION_SERVER_ID_ENV_NAME; - @RestController @RequestMapping(value = "/debra") public class DebraDonationStatusController { @@ -20,50 +18,38 @@ public class DebraDonationStatusController { @GetMapping(value = "/latestDonations", produces = "application/json") public DonationStats getLatestDonations() { - Long serverId = Long.parseLong(System.getenv(DEBRA_DONATION_NOTIFICATION_SERVER_ID_ENV_NAME)); - DonationsResponse donationResponse = donationService.getSynchronizedCachedDonationAmount(serverId); + DonationsResponse donationResponse = donationService.getSynchronizedCachedDonationAmount(); List donations = donationService.getLatestDonations(donationResponse, Integer.MAX_VALUE) .stream() .map(DonationInfo::fromDonationItemModel) .toList(); return DonationStats .builder() - .totalAmount(donationResponse.getPage().getCollected()) + .totalAmount(donationResponse.getCurrentDonationAmount()) .donations(donations) .build(); } @GetMapping(value = "/highestDonations", produces = "application/json") public DonationStats getHighestDonations() { - Long serverId = Long.parseLong(System.getenv(DEBRA_DONATION_NOTIFICATION_SERVER_ID_ENV_NAME)); - DonationsResponse donationResponse = donationService.getSynchronizedCachedDonationAmount(serverId); + DonationsResponse donationResponse = donationService.getSynchronizedCachedDonationAmount(); List donations = donationService.getHighestDonations(donationResponse, Integer.MAX_VALUE) .stream() .map(DonationInfo::fromDonationItemModel) .toList(); return DonationStats .builder() - .totalAmount(donationResponse.getPage().getCollected()) + .totalAmount(donationResponse.getCurrentDonationAmount()) .donations(donations) .build(); } @GetMapping(value = "/campaignInfo", produces = "application/json") public CampaignInfo getCampaignInfo() { - Long serverId = Long.parseLong(System.getenv(DEBRA_DONATION_NOTIFICATION_SERVER_ID_ENV_NAME)); - DonationsResponse donationResponse = donationService.getSynchronizedCachedDonationAmount(serverId); + DonationsResponse donationResponse = donationService.getSynchronizedCachedDonationAmount(); - Description pageObject = donationResponse.getPage(); return CampaignInfo .builder() - .collected(pageObject.getCollected()) - .collectedNet(pageObject.getCollectedNet()) - .donationCount(donationResponse.getDonationCount()) - .currency(pageObject.getCurrency()) - .percent(pageObject.getPercent()) - .displayName(pageObject.getDisplayName()) - .slug(pageObject.getSlug()) - .target(pageObject.getTarget()) .build(); } } diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/api/EndlessStreamController.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/api/EndlessStreamController.java index 14be81f2..48bc269a 100644 --- a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/api/EndlessStreamController.java +++ b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/api/EndlessStreamController.java @@ -36,8 +36,8 @@ public class EndlessStreamController { public EndlessStreamInfo getLatestDonations(@PathVariable("id") Long id) { Long serverId = Long.parseLong(System.getenv(DEBRA_DONATION_NOTIFICATION_SERVER_ID_ENV_NAME)); EndlessStream endlessStream = endlessStreamManagementServiceBean.getEndlessStream(id); - DonationsResponse donationInfo = donationService.getSynchronizedCachedDonationAmount(serverId); - BigDecimal collectedAmount = donationInfo.getPage().getCollected(); + DonationsResponse donationInfo = donationService.getSynchronizedCachedDonationAmount(); + BigDecimal collectedAmount = donationInfo.getCurrentDonationAmount(); Long minuteRate = configService.getLongValueOrConfigDefault(DebraFeatureConfig.ENDLESS_STREAM_MINUTE_RATE, serverId); Instant endDate = endlessStream.getStartTime().plus(collectedAmount.multiply(new BigDecimal(minuteRate)).toBigInteger().longValue(), ChronoUnit.MINUTES); return EndlessStreamInfo diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/commands/Donations.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/commands/Donations.java index fc61aa56..4b2519c5 100644 --- a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/commands/Donations.java +++ b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/commands/Donations.java @@ -6,9 +6,9 @@ import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.execution.CommandContext; +import dev.sheldan.abstracto.core.command.execution.CommandParameterKey; import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.config.FeatureDefinition; -import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException; import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService; @@ -26,7 +26,6 @@ import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEve import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -70,11 +69,12 @@ public class Donations extends AbstractConditionableCommand { Integer selectionValue = (Integer) parameters.get(1); Integer top = null; Integer latest = null; - switch (type) { - case "top": top = selectionValue; break; - default: - case "latest" : - latest = selectionValue; break; + if(type != null) { + DonationsTypeParameterKey typeKey = CommandParameterKey.getEnumFromKey(DonationsTypeParameterKey.class, type); + switch (typeKey) { + case LATEST -> latest = selectionValue; + case TOP -> top = selectionValue; + } } messageToSend = getDonationMessageToSend(commandContext.getGuild().getIdLong(), top, latest); } @@ -98,11 +98,10 @@ public class Donations extends AbstractConditionableCommand { Integer top = null; Integer latest = null; if(selectionType != null) { - switch (selectionType) { - case "top": top = selectionValue; break; - default: - case "latest" : - latest = selectionValue; break; + DonationsTypeParameterKey typeKey = CommandParameterKey.getEnumFromKey(DonationsTypeParameterKey.class, selectionType); + switch (typeKey) { + case LATEST -> latest = selectionValue; + case TOP -> top = selectionValue; } } @@ -113,7 +112,7 @@ public class Donations extends AbstractConditionableCommand { private MessageToSend getDonationMessageToSend(Long serverId, Integer top, Integer latest) { DonationsModel donationModel; - DonationsResponse donationResponse = donationService.fetchCurrentDonationAmount(serverId); + DonationsResponse donationResponse = donationService.fetchCurrentDonations(); donationModel = donationConverter.convertDonationResponse(donationResponse); if(top != null) { donationModel.setDonations(donationService.getHighestDonations(donationResponse, top)); @@ -146,7 +145,7 @@ public class Donations extends AbstractConditionableCommand { .templated(true) .name(SELECTION_PARAMETER) .optional(true) - .type(String.class) + .type(DonationsTypeParameterKey.class) .build(); diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/commands/DonationsTypeParameterKey.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/commands/DonationsTypeParameterKey.java new file mode 100644 index 00000000..e0f9027e --- /dev/null +++ b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/commands/DonationsTypeParameterKey.java @@ -0,0 +1,13 @@ +package dev.sheldan.sissi.module.debra.commands; + +import dev.sheldan.abstracto.core.command.execution.CommandParameterKey; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum DonationsTypeParameterKey implements CommandParameterKey { + TOP("top"), LATEST("latest"); + + private String key; +} diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/config/DebraFeatureConfig.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/config/DebraFeatureConfig.java index d5f2a018..d7764e68 100644 --- a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/config/DebraFeatureConfig.java +++ b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/config/DebraFeatureConfig.java @@ -13,7 +13,6 @@ public class DebraFeatureConfig implements FeatureConfig { public static final String DEBRA_DONATION_NOTIFICATION_DELAY_CONFIG_KEY = "debraDonationNotificationDelayMillis"; public static final String ENDLESS_STREAM_MINUTE_RATE = "endlessStreamMinuteRate"; - public static final String DEBRA_DONATION_API_FETCH_SIZE_KEY = "debraDonationApiFetchSize"; public static final String DEBRA_DONATION_NOTIFICATION_SERVER_ID_ENV_NAME = "DEBRA_DONATION_NOTIFICATION_SERVER_ID"; @Override public FeatureDefinition getFeature() { @@ -27,6 +26,6 @@ public class DebraFeatureConfig implements FeatureConfig { @Override public List getRequiredSystemConfigKeys() { - return Arrays.asList(DEBRA_DONATION_NOTIFICATION_DELAY_CONFIG_KEY, DEBRA_DONATION_API_FETCH_SIZE_KEY, ENDLESS_STREAM_MINUTE_RATE); + return Arrays.asList(DEBRA_DONATION_NOTIFICATION_DELAY_CONFIG_KEY, ENDLESS_STREAM_MINUTE_RATE); } } diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/config/DebraProperties.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/config/DebraProperties.java index aa095e54..61694d88 100644 --- a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/config/DebraProperties.java +++ b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/config/DebraProperties.java @@ -10,6 +10,5 @@ import org.springframework.context.annotation.Configuration; @Setter @ConfigurationProperties(prefix = "sissi.debra") public class DebraProperties { - private String websocketURL; - private String donationAPIUrl; + private String donationPageUrl; } diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/converter/DonationConverter.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/converter/DonationConverter.java index 52fda6b9..01b1b0b9 100644 --- a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/converter/DonationConverter.java +++ b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/converter/DonationConverter.java @@ -1,6 +1,6 @@ package dev.sheldan.sissi.module.debra.converter; -import dev.sheldan.sissi.module.debra.model.api.Donation; +import dev.sheldan.sissi.module.debra.model.api.DonationDto; import dev.sheldan.sissi.module.debra.model.api.DonationsResponse; import dev.sheldan.sissi.module.debra.model.commands.DonationItemModel; import dev.sheldan.sissi.module.debra.model.commands.DonationsModel; @@ -9,20 +9,19 @@ import org.springframework.stereotype.Component; @Component public class DonationConverter { - public DonationItemModel convertDonation(Donation donation) { + public DonationItemModel convertDonation(DonationDto donation) { return DonationItemModel .builder() .donationAmount(donation.getAmount()) - .firstName(donation.getFirstname()) - .lastName(donation.getLastname()) - .anonymous(BooleanUtils.toBoolean(donation.getAnonym())) + .name(donation.getName()) + .anonymous(BooleanUtils.toBoolean(donation.getAnonymous())) .build(); } public DonationsModel convertDonationResponse(DonationsResponse response) { return DonationsModel .builder() - .totalAmount(response.getPage().getCollected()) + .totalAmount(response.getCurrentDonationAmount()) .build(); } } diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/job/DonationFetchJob.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/job/DonationFetchJob.java new file mode 100644 index 00000000..fffdcac4 --- /dev/null +++ b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/job/DonationFetchJob.java @@ -0,0 +1,31 @@ +package dev.sheldan.sissi.module.debra.job; + +import dev.sheldan.sissi.module.debra.service.DonationService; +import lombok.extern.slf4j.Slf4j; +import org.quartz.DisallowConcurrentExecution; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.quartz.PersistJobDataAfterExecution; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.quartz.QuartzJobBean; +import org.springframework.stereotype.Component; + +@Slf4j +@DisallowConcurrentExecution +@Component +@PersistJobDataAfterExecution +public class DonationFetchJob extends QuartzJobBean { + + @Autowired + private DonationService donationService; + + @Override + protected void executeInternal(JobExecutionContext context) throws JobExecutionException { + try { + log.info("Checking for new donations."); + donationService.checkForNewDonations(); + } catch (Exception e) { + log.error("Failed to check for new donations.", e); + } + } +} diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/listener/WebsocketListener.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/listener/WebsocketListener.java deleted file mode 100644 index e79abddd..00000000 --- a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/listener/WebsocketListener.java +++ /dev/null @@ -1,96 +0,0 @@ -package dev.sheldan.sissi.module.debra.listener; - -import dev.sheldan.abstracto.core.listener.AsyncStartupListener; -import dev.sheldan.abstracto.core.service.ConfigService; -import dev.sheldan.sissi.module.debra.config.DebraProperties; -import dev.sheldan.sissi.module.debra.model.listener.DonationResponseModel; -import dev.sheldan.sissi.module.debra.service.DonationService; -import lombok.extern.slf4j.Slf4j; -import okhttp3.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import javax.annotation.Nullable; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; - -import static dev.sheldan.sissi.module.debra.config.DebraFeatureConfig.DEBRA_DONATION_NOTIFICATION_DELAY_CONFIG_KEY; -import static dev.sheldan.sissi.module.debra.config.DebraFeatureConfig.DEBRA_DONATION_NOTIFICATION_SERVER_ID_ENV_NAME; - -@Component -@Slf4j -public class WebsocketListener extends WebSocketListener implements AsyncStartupListener { - - @Autowired - private DonationService donationService; - - @Autowired - private DebraProperties debraProperties; - - @Autowired - private ConfigService configService; - - private WebSocket webSocketObj; - private OkHttpClient clientObj; - - @Override - public void onOpen(WebSocket webSocket, Response response) { - log.info("Connected to donation websocket."); - super.onOpen(webSocket, response); - } - - @Override - public void onMessage(WebSocket webSocket, String text) { - CompletableFuture.runAsync(() -> { - log.info("Handling received message on websocket."); - try { - Long targetServerId = Long.parseLong(System.getenv(DEBRA_DONATION_NOTIFICATION_SERVER_ID_ENV_NAME)); - Long delayMillis = configService.getLongValueOrConfigDefault(DEBRA_DONATION_NOTIFICATION_DELAY_CONFIG_KEY, targetServerId); - log.info("Waiting {} milli seconds to send notification.", delayMillis); - Thread.sleep(delayMillis); - log.info("Loading new donation amount and sending notification."); - DonationResponseModel donation = donationService.parseDonationFromMessage(text); - donationService.sendDonationNotification(donation).thenAccept(unused -> { - log.info("Successfully notified about donation."); - }).exceptionally(throwable -> { - log.error("Failed to notify about donation.", throwable); - return null; - }); - } catch (Exception exception) { - log.error("Failed to handle websocket message.", exception); - } - }); - } - - @Override - public void onFailure(WebSocket webSocket, Throwable t, @Nullable Response response) { - log.warn("Websocket connection failed...", t); - } - - @Override - public void onClosing(WebSocket webSocket, int code, String reason) { - log.info("Closing websocket connection. It was closed with code {} and reason {}.", code, reason); - } - - @Override - public void execute() { - if(clientObj != null) { - clientObj.connectionPool().evictAll(); - clientObj.dispatcher().executorService().shutdownNow(); - } - clientObj = new OkHttpClient.Builder() - .readTimeout(0, TimeUnit.MILLISECONDS) - .retryOnConnectionFailure(true) - .build(); - startConnection(clientObj); - clientObj.dispatcher().executorService().shutdown(); - } - - private void startConnection(OkHttpClient client) { - log.info("Starting websocket connection."); - Request request = new Request.Builder() - .url(debraProperties.getWebsocketURL()) - .build(); - this.webSocketObj = client.newWebSocket(request, this); - } -} diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/api/Description.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/api/Description.java deleted file mode 100644 index b6920881..00000000 --- a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/api/Description.java +++ /dev/null @@ -1,28 +0,0 @@ -package dev.sheldan.sissi.module.debra.model.api; - -import com.google.gson.annotations.SerializedName; -import lombok.Builder; -import lombok.Getter; -import lombok.Setter; - -import java.math.BigDecimal; - -@Getter -@Setter -@Builder -public class Description { - @SerializedName("collected") - private BigDecimal collected; - @SerializedName("target") - private BigDecimal target; - @SerializedName("currency") - private String currency; - @SerializedName("slug") - private String slug; - @SerializedName("displayname") - private String displayName; - @SerializedName("collectednet") - private BigDecimal collectedNet; - @SerializedName("percent") - private BigDecimal percent; -} diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/api/Donation.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/api/Donation.java deleted file mode 100644 index d535f5dc..00000000 --- a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/api/Donation.java +++ /dev/null @@ -1,26 +0,0 @@ -package dev.sheldan.sissi.module.debra.model.api; - -import com.google.gson.annotations.SerializedName; -import lombok.Builder; -import lombok.Getter; -import lombok.Setter; - -import java.math.BigDecimal; - -@Getter -@Setter -@Builder -public class Donation { - @SerializedName("amount") - private BigDecimal amount; - @SerializedName("currency") - private String currency; - @SerializedName("text") - private String text; - @SerializedName("anonym") - private Integer anonym; - @SerializedName("firstname") - private String firstname; - @SerializedName("lastname") - private String lastname; -} diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/api/DonationDto.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/api/DonationDto.java new file mode 100644 index 00000000..34740a6b --- /dev/null +++ b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/api/DonationDto.java @@ -0,0 +1,27 @@ +package dev.sheldan.sissi.module.debra.model.api; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +@Getter +@Setter +@Builder +@ToString +public class DonationDto { + private BigDecimal amount; + private String currency; + private String text; + private Boolean anonymous; + private String name; + private LocalDate date; + + public String stringRepresentation() { + return String.format("%s %s %s %s %s", name, amount, text, anonymous, date.format(DateTimeFormatter.ISO_DATE)); + } +} diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/api/DonationInfo.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/api/DonationInfo.java index 3c60f165..54ca8464 100644 --- a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/api/DonationInfo.java +++ b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/api/DonationInfo.java @@ -11,7 +11,7 @@ import java.math.BigDecimal; @Setter @Builder public class DonationInfo { - private String firstName; + private String name; private BigDecimal donationAmount; private Boolean anonymous; @@ -20,7 +20,7 @@ public class DonationInfo { .builder() .donationAmount(donationItemModel.getDonationAmount()) .anonymous(donationItemModel.getAnonymous()) - .firstName(donationItemModel.getFirstName()) + .name(donationItemModel.getName()) .build(); } } diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/api/DonationsResponse.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/api/DonationsResponse.java index 12322bc3..f264bff4 100644 --- a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/api/DonationsResponse.java +++ b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/api/DonationsResponse.java @@ -1,21 +1,18 @@ package dev.sheldan.sissi.module.debra.model.api; -import com.google.gson.annotations.SerializedName; import lombok.Builder; import lombok.Getter; import lombok.Setter; -import java.math.BigInteger; +import java.math.BigDecimal; import java.util.List; @Getter @Setter @Builder public class DonationsResponse { - @SerializedName("page") - private Description page; - @SerializedName("donation_count") - private BigInteger donationCount; - @SerializedName("donations") - private List donations; + private BigDecimal currentDonationAmount; + private BigDecimal donationAmountGoal; + private int donationCount; + private List donations; } diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/commands/DonationItemModel.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/commands/DonationItemModel.java index 8ac1e5e4..99c91294 100644 --- a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/commands/DonationItemModel.java +++ b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/commands/DonationItemModel.java @@ -5,13 +5,14 @@ import lombok.Getter; import lombok.Setter; import java.math.BigDecimal; +import java.time.LocalDate; @Getter @Setter @Builder public class DonationItemModel { - private String firstName; - private String lastName; + private String name; + private LocalDate date; private BigDecimal donationAmount; private Boolean anonymous; } diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/database/Donation.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/database/Donation.java new file mode 100644 index 00000000..7560ede7 --- /dev/null +++ b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/database/Donation.java @@ -0,0 +1,30 @@ +package dev.sheldan.sissi.module.debra.model.database; + +import jakarta.persistence.*; +import lombok.*; + +import java.time.Instant; + +@Builder +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "donation") +@Getter +@Setter +@EqualsAndHashCode +public class Donation { + @Id + @Column(name = "id", nullable = false) + private String id; + + // we cant be sure about duplicates + @Column(name = "count") + private Integer count; + + @Column(name = "created") + private Instant created; + + @Column(name = "updated") + private Instant updated; +} diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/listener/DonationResponseModel.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/listener/DonationResponseModel.java index 996f307c..c25a2a70 100644 --- a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/listener/DonationResponseModel.java +++ b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/model/listener/DonationResponseModel.java @@ -11,6 +11,7 @@ import java.math.BigDecimal; @ToString public class DonationResponseModel { private String donatorName; + private Boolean anonymous; private BigDecimal amount; private String message; } diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/repository/DonationRepository.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/repository/DonationRepository.java new file mode 100644 index 00000000..b1a894d2 --- /dev/null +++ b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/repository/DonationRepository.java @@ -0,0 +1,9 @@ +package dev.sheldan.sissi.module.debra.repository; + +import dev.sheldan.sissi.module.debra.model.database.Donation; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface DonationRepository extends JpaRepository { +} diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/service/DonationService.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/service/DonationService.java index 4758f382..97a1a2cb 100644 --- a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/service/DonationService.java +++ b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/service/DonationService.java @@ -1,52 +1,52 @@ package dev.sheldan.sissi.module.debra.service; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException; import dev.sheldan.abstracto.core.interaction.ComponentPayloadService; import dev.sheldan.abstracto.core.interaction.ComponentService; import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.service.ChannelService; -import dev.sheldan.abstracto.core.service.ConfigService; +import dev.sheldan.abstracto.core.service.HashService; import dev.sheldan.abstracto.core.service.PostTargetService; import dev.sheldan.abstracto.core.service.management.ServerManagementService; import dev.sheldan.abstracto.core.templating.model.MessageToSend; import dev.sheldan.abstracto.core.templating.service.TemplateService; +import dev.sheldan.abstracto.core.utils.CompletableFutureList; import dev.sheldan.abstracto.core.utils.FutureUtils; -import dev.sheldan.sissi.module.debra.exception.DonationAmountNotFoundException; import dev.sheldan.sissi.module.debra.config.DebraPostTarget; import dev.sheldan.sissi.module.debra.config.DebraProperties; import dev.sheldan.sissi.module.debra.converter.DonationConverter; -import dev.sheldan.sissi.module.debra.model.api.Donation; +import dev.sheldan.sissi.module.debra.model.api.DonationDto; import dev.sheldan.sissi.module.debra.model.api.DonationsResponse; import dev.sheldan.sissi.module.debra.model.commands.DebraInfoButtonPayload; import dev.sheldan.sissi.module.debra.model.commands.DebraInfoModel; import dev.sheldan.sissi.module.debra.model.commands.DonationItemModel; import dev.sheldan.sissi.module.debra.model.commands.DonationsModel; +import dev.sheldan.sissi.module.debra.model.database.Donation; import dev.sheldan.sissi.module.debra.model.listener.DonationResponseModel; import dev.sheldan.sissi.module.debra.model.listener.DonationNotificationModel; +import dev.sheldan.sissi.module.debra.service.management.DonationManagementServiceBean; import lombok.extern.slf4j.Slf4j; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; +import org.apache.commons.lang3.tuple.Pair; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; -import java.io.IOException; import java.math.BigDecimal; -import java.util.Comparator; -import java.util.List; -import java.util.Optional; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.*; import java.util.concurrent.CompletableFuture; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Collectors; -import static dev.sheldan.sissi.module.debra.config.DebraFeatureConfig.DEBRA_DONATION_API_FETCH_SIZE_KEY; import static dev.sheldan.sissi.module.debra.config.DebraFeatureConfig.DEBRA_DONATION_NOTIFICATION_SERVER_ID_ENV_NAME; @Component @@ -62,15 +62,9 @@ public class DonationService { @Autowired private TemplateService templateService; - @Autowired - private OkHttpClient okHttpClient; - @Autowired private DonationConverter donationConverter; - @Autowired - private ConfigService configService; - @Autowired private ChannelService channelService; @@ -83,100 +77,209 @@ public class DonationService { @Autowired private ServerManagementService serverManagementService; + @Autowired + private DonationManagementServiceBean donationManagementServiceBean; + + @Autowired + private HashService hashService; + @Autowired private DonationService self; private static final String DEBRA_DONATION_NOTIFICATION_TEMPLATE_KEY = "debra_donation_notification"; - private static final Pattern MESSAGE_PATTERN = Pattern.compile("(.*) hat (\\d{1,9},\\d{2}) Euro gespendet!
Vielen Dank!
Nachricht:
(.*)"); - private static final String DEBRA_INFO_BUTTON_MESSAGE_TEMPLATE_KEY = "debraInfoButton"; public static final String DEBRA_INFO_BUTTON_ORIGIN = "DEBRA_INFO_BUTTON"; - - public DonationResponseModel parseDonationFromMessage(String message) { - Matcher matcher = MESSAGE_PATTERN.matcher(message); - if (matcher.find()) { - String donatorName = matcher.group(1); - String amountString = matcher.group(2); - BigDecimal amount = new BigDecimal(amountString.replace(',', '.')); - String donationMessage = Optional.ofNullable(matcher.group(3)).map(msg -> msg.replaceAll("(
)+", " ")).map(String::trim).orElse(""); - return DonationResponseModel - .builder() - .message(donationMessage) - .donatorName(donatorName) - .amount(amount) - .build(); - } else { - throw new IllegalArgumentException("String in wrong format"); - } - } + private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("d.M.y"); public List getHighestDonations(DonationsResponse response, Integer maxCount) { - List topDonations = response + return response .getDonations() .stream() - .sorted(Comparator.comparing(Donation::getAmount) + .sorted(Comparator.comparing(DonationDto::getAmount) .reversed()) - .collect(Collectors.toList()); - return topDonations - .stream() .limit(maxCount) .map(donation -> donationConverter.convertDonation(donation)) - .collect(Collectors.toList()); + .toList(); } public List getLatestDonations(DonationsResponse response, Integer maxCount) { return response .getDonations() .stream() + .sorted(Comparator.comparing(DonationDto::getDate).reversed()) .limit(maxCount) .map(donation -> donationConverter.convertDonation(donation)) .collect(Collectors.toList()); } - public synchronized DonationsResponse getSynchronizedCachedDonationAmount(Long serverId) { - return self.getCachedDonationAmount(serverId); + public synchronized DonationsResponse getSynchronizedCachedDonationAmount() { + return self.getCachedDonationAmount(); } @Cacheable(value = "donation-cache") - public synchronized DonationsResponse getCachedDonationAmount(Long serverId) { - return self.fetchCurrentDonationAmount(serverId); + public synchronized DonationsResponse getCachedDonationAmount() { + return self.fetchCurrentDonations(); } - public DonationsResponse fetchCurrentDonationAmount(Long serverId) { + public DonationsResponse fetchCurrentDonations() { try { - Long fetchSize = configService.getLongValueOrConfigDefault(DEBRA_DONATION_API_FETCH_SIZE_KEY, serverId); - Request request = new Request.Builder() - .url(String.format(debraProperties.getDonationAPIUrl(), fetchSize)) - .get() - .build(); - Response response = okHttpClient.newCall(request).execute(); - if(!response.isSuccessful()) { - log.error("Failed to retrieve donation response. Response had code {} with body {} and headers {}.", - response.code(), response.body().string(), response.headers()); - throw new DonationAmountNotFoundException(); + Document donationPage = Jsoup.connect(debraProperties.getDonationPageUrl()).get(); + DecimalFormat decimalFormat = getDecimalFormat(); + Element endValueElement = donationPage.getElementById("end-value"); + String endValueString = endValueElement.text(); + Elements currentValueElement = donationPage.getElementsByClass("current_amount").get(0).getElementsByClass("value"); + String[] valueArray = currentValueElement.text().split(" "); + String currentValueString = valueArray[0]; + String currency = valueArray[1]; + BigDecimal currentValue = (BigDecimal) decimalFormat.parse(currentValueString); + BigDecimal endValue = (BigDecimal) decimalFormat.parse(endValueString); + Element list = donationPage.getElementsByClass("donor-list").first(); + Elements donationElements = list.getElementsByClass("list-item"); + List donations = new ArrayList<>(); + for (Element donationMainElement : donationElements.asList()) { + Elements nameElement = donationMainElement.getElementsByClass("donor-list-name"); + Elements dateElement = donationMainElement.getElementsByClass("donor-list-date"); + Elements amountElement = donationMainElement.getElementsByClass("donor-list-amount"); + Elements textElement = donationMainElement.getElementsByClass("donor-list-amount-text"); + LocalDate dateValue; + if (dateElement.hasText()) { + dateValue = LocalDate.parse(dateElement.text(), DATE_FORMAT); + } else { + dateValue = null; + } + BigDecimal amount; + if (amountElement.hasText()) { + String amountText = amountElement.text().split(" ")[0]; + amount = (BigDecimal) decimalFormat.parse(amountText); + } else { + amount = null; + } + String additionalText = textElement.text(); + String name = nameElement.text(); + boolean anonymous = name.isBlank(); + donations.add(DonationDto + .builder() + .anonymous(anonymous) + .name(nameElement.text()) + .amount(amount) + .currency(currency) + .name(name) + .text(additionalText) + .date(dateValue) + .build()); } - Gson gson = getGson(); - return gson.fromJson(response.body().string(), DonationsResponse.class); + return DonationsResponse + .builder() + .donations(donations) + .currentDonationAmount(currentValue) + .donationAmountGoal(endValue) + .donationCount(donations.size()) + .build(); } catch (Exception exception) { throw new AbstractoRunTimeException(exception); } } - private Gson getGson() { - return new GsonBuilder() - .registerTypeAdapter(BigDecimal.class, new BigDecimalGsonAdapter()) - .create(); + private DecimalFormat getDecimalFormat() { + DecimalFormatSymbols symbols = new DecimalFormatSymbols(); + symbols.setGroupingSeparator('.'); + symbols.setDecimalSeparator(','); + String pattern = "#,##0.0#"; + + DecimalFormat decimalFormat = new DecimalFormat(pattern, symbols); + decimalFormat.setParseBigDecimal(true); + return decimalFormat; } - private DonationsModel getDonationInfoModel(Long serverId) { - return donationConverter.convertDonationResponse(fetchCurrentDonationAmount(serverId)); + private DonationsModel getDonationInfoModel() { + return donationConverter.convertDonationResponse(fetchCurrentDonations()); } - public CompletableFuture sendDonationNotification(DonationResponseModel donation) throws IOException { + + private String hashDonation(DonationDto donation) { + return hashService.sha256HashString(donation.stringRepresentation()); + } + + @Transactional + public void checkForNewDonations() { + List allDonations = donationManagementServiceBean.getAllDonations(); + Map existingHashes = allDonations + .stream() + .collect(Collectors.toMap(Donation::getId, Donation::getCount)); + DonationsResponse donationResponse = fetchCurrentDonations(); + Map> donationFromPageHashes = new HashMap<>(); + donationResponse.getDonations().forEach(donationDto -> { + String thisHash = hashDonation(donationDto); + if(donationFromPageHashes.containsKey(thisHash)) { + donationFromPageHashes.put(thisHash, Pair.of(donationFromPageHashes.get(thisHash).getLeft() + 1, donationDto)); + } else { + donationFromPageHashes.put(thisHash, Pair.of(1, donationDto)); + } + }); + + Set pageHashesToRemove = new HashSet<>(); + donationFromPageHashes.entrySet().forEach(pageHash -> { + if(existingHashes.containsKey(pageHash.getKey())) { + Integer existingDonation = existingHashes.get(pageHash.getKey()); + int amountDifference = pageHash.getValue().getKey() - existingDonation; + if(amountDifference == 0) { + pageHashesToRemove.add(pageHash.getKey()); // it matches 1:1, we know about all of them already + } if(amountDifference < 0) { + pageHashesToRemove.add(pageHash.getKey()); + log.warn("We have more donations than on the page of hash {}:{}.", pageHash.getKey(), amountDifference); + } else { + pageHash.setValue(Pair.of(amountDifference, pageHash.getValue().getRight())); + } + } + }); + pageHashesToRemove.forEach(donationFromPageHashes::remove); + if(donationFromPageHashes.isEmpty()) { + log.info("No new donations - ending search."); + return; + } + + List> notificationFutures = new ArrayList<>(); + donationFromPageHashes.values().forEach(donationInfo -> { + for (int i = 0; i < donationInfo.getLeft(); i++) { + DonationDto donationDto = donationInfo.getRight(); + DonationResponseModel model = DonationResponseModel + .builder() + .message(donationDto.getText()) + .donatorName(donationDto.getName()) + .amount(donationDto.getAmount()) + .anonymous(donationDto.getAnonymous()) + .build(); + notificationFutures.add(sendDonationNotification(model)); + } + }); + new CompletableFutureList<>(notificationFutures).getMainFuture().thenAccept(unused -> { + log.info("All {} notifications send.", notificationFutures.size()); + }).exceptionally(throwable -> { + log.warn("Failed to send notifications about {} new donations.", notificationFutures.size(), throwable); + return null; + }); + log.info("Creating/updating {} donation entries.", donationFromPageHashes.size()); + allDonations.forEach(donation -> { + Set donationsToRemoveBecauseUpdate = new HashSet<>(); + donationFromPageHashes.forEach((key, value) -> { + // its assumed that donationFromPageHashes only contains donations that need to be created + if (donation.getId().equals(key)) { + donation.setCount(value.getLeft() + donation.getCount()); + donationManagementServiceBean.updateDonation(donation); + donationsToRemoveBecauseUpdate.add(key); + } + }); + donationsToRemoveBecauseUpdate.forEach(donationFromPageHashes::remove); + }); + donationFromPageHashes.forEach((key, value) -> + donationManagementServiceBean.saveDonation(key, value.getLeft())); + } + + public CompletableFuture sendDonationNotification(DonationResponseModel donation) { Long targetServerId = Long.parseLong(System.getenv(DEBRA_DONATION_NOTIFICATION_SERVER_ID_ENV_NAME)); - DonationsModel donationInfoModel = getDonationInfoModel(targetServerId); + DonationsModel donationInfoModel = getDonationInfoModel(); DonationNotificationModel model = DonationNotificationModel .builder() .donation(donation) diff --git a/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/service/management/DonationManagementServiceBean.java b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/service/management/DonationManagementServiceBean.java new file mode 100644 index 00000000..bc5169b4 --- /dev/null +++ b/application/sissi-modules/debra/src/main/java/dev/sheldan/sissi/module/debra/service/management/DonationManagementServiceBean.java @@ -0,0 +1,33 @@ +package dev.sheldan.sissi.module.debra.service.management; + +import dev.sheldan.sissi.module.debra.model.database.Donation; +import dev.sheldan.sissi.module.debra.repository.DonationRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class DonationManagementServiceBean { + + @Autowired + private DonationRepository donationRepository; + + public List getAllDonations() { + return donationRepository.findAll(); + } + + public void updateDonation(Donation donation) { + donationRepository.save(donation); + } + + public Donation saveDonation(String hash, Integer count) { + Donation donation = Donation + .builder() + .id(hash) + .count(count) + .build(); + return donationRepository.save(donation); + } + +} diff --git a/application/sissi-modules/debra/src/main/resources/debra.properties b/application/sissi-modules/debra/src/main/resources/debra.properties index 8b203e46..feae9e7b 100644 --- a/application/sissi-modules/debra/src/main/resources/debra.properties +++ b/application/sissi-modules/debra/src/main/resources/debra.properties @@ -4,8 +4,7 @@ abstracto.featureFlags.debra.enabled=false abstracto.postTargets.debraDonationNotification.name=debraDonationNotification abstracto.postTargets.debraDonationNotification2.name=debraDonationNotification2 -sissi.debra.websocketURL=ws://spenden.baba.fm:8765/ -sissi.debra.donationAPIUrl=https://www.altruja.de/api/page/discord-schmetterlingsaktion-2024?details=1&num=%s&ort=0 +sissi.debra.donationPageUrl=https://secure.sicherhelfen.org/campaigns/07a3baf6-5cdc-4300-854b-ea2b36b0b218/show abstracto.systemConfigs.debraDonationNotificationDelayMillis.name=debraDonationNotificationDelayMillis abstracto.systemConfigs.debraDonationNotificationDelayMillis.longValue=60000 diff --git a/application/sissi-modules/debra/src/main/resources/migrations/1.5.16/collection.xml b/application/sissi-modules/debra/src/main/resources/migrations/1.5.16/collection.xml new file mode 100644 index 00000000..a390f38e --- /dev/null +++ b/application/sissi-modules/debra/src/main/resources/migrations/1.5.16/collection.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/application/sissi-modules/debra/src/main/resources/migrations/1.5.16/seedData/data.xml b/application/sissi-modules/debra/src/main/resources/migrations/1.5.16/seedData/data.xml new file mode 100644 index 00000000..04ee382e --- /dev/null +++ b/application/sissi-modules/debra/src/main/resources/migrations/1.5.16/seedData/data.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/application/sissi-modules/debra/src/main/resources/migrations/1.5.16/seedData/donation_fetch_job.xml b/application/sissi-modules/debra/src/main/resources/migrations/1.5.16/seedData/donation_fetch_job.xml new file mode 100644 index 00000000..0b007931 --- /dev/null +++ b/application/sissi-modules/debra/src/main/resources/migrations/1.5.16/seedData/donation_fetch_job.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/application/sissi-modules/debra/src/main/resources/migrations/1.5.16/tables/donation.xml b/application/sissi-modules/debra/src/main/resources/migrations/1.5.16/tables/donation.xml new file mode 100644 index 00000000..8ba6cf10 --- /dev/null +++ b/application/sissi-modules/debra/src/main/resources/migrations/1.5.16/tables/donation.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + DROP TRIGGER IF EXISTS donation_update_trigger ON donation; + CREATE TRIGGER donation_update_trigger BEFORE UPDATE ON donation FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure(); + + + DROP TRIGGER IF EXISTS donation_insert_trigger ON donation; + CREATE TRIGGER donation_insert_trigger BEFORE INSERT ON donation FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure(); + + + + \ No newline at end of file diff --git a/application/sissi-modules/debra/src/main/resources/migrations/1.5.16/tables/tables.xml b/application/sissi-modules/debra/src/main/resources/migrations/1.5.16/tables/tables.xml new file mode 100644 index 00000000..6a773ce9 --- /dev/null +++ b/application/sissi-modules/debra/src/main/resources/migrations/1.5.16/tables/tables.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/application/sissi-modules/debra/src/main/resources/migrations/debra-changeLog.xml b/application/sissi-modules/debra/src/main/resources/migrations/debra-changeLog.xml index 93947e67..bf74bb94 100644 --- a/application/sissi-modules/debra/src/main/resources/migrations/debra-changeLog.xml +++ b/application/sissi-modules/debra/src/main/resources/migrations/debra-changeLog.xml @@ -5,4 +5,5 @@ + \ No newline at end of file diff --git a/deployment/helm/sissi/templates/deployment.yaml b/deployment/helm/sissi/templates/deployment.yaml index 4f94fbf2..16a48967 100644 --- a/deployment/helm/sissi/templates/deployment.yaml +++ b/deployment/helm/sissi/templates/deployment.yaml @@ -60,7 +60,7 @@ spec: - name: DB_SCHEMA value: {{ .Values.dbCredentials.schema }} - name: DEBRA_DONATION_NOTIFICATION_SERVER_ID - value: "297910194841583616" + value: "{{ .Values.bot.config.debraNotificationServerId }}" - name: WEEKLY_TEXT_SERVER_ID value: "{{ .Values.bot.config.weeklyTextServerId }}" - name: TOKEN diff --git a/deployment/helm/sissi/values.yaml b/deployment/helm/sissi/values.yaml index caff613a..e91ac456 100644 --- a/deployment/helm/sissi/values.yaml +++ b/deployment/helm/sissi/values.yaml @@ -17,6 +17,7 @@ bot: host: null config: weeklyTextServerId: null + debraNotificationServerId: null restApi: enabled: true repository: harbor.sheldan.dev/sissi diff --git a/pom.xml b/pom.xml index a77578fa..e95d7fc4 100644 --- a/pom.xml +++ b/pom.xml @@ -18,10 +18,11 @@ 17 17 - 1.6.17-SNAPSHOT - 1.4.63-SNAPSHOT + 1.6.17 + 1.4.63 4.9.0 3.5.0 + 1.21.2 diff --git a/templates/sissi-templates/module-templates/debra-templates/src/main/resources/default/commands/donations/donations_response_embed.ftl b/templates/sissi-templates/module-templates/debra-templates/src/main/resources/default/commands/donations/donations_response_embed.ftl index 78155b6f..f336a83d 100644 --- a/templates/sissi-templates/module-templates/debra-templates/src/main/resources/default/commands/donations/donations_response_embed.ftl +++ b/templates/sissi-templates/module-templates/debra-templates/src/main/resources/default/commands/donations/donations_response_embed.ftl @@ -13,7 +13,7 @@ ,"fields": [ <#list donations as donation> { - "name": "<#if donation.anonymous><#include "donations_response_anonymous"><#else>${donation.firstName}", + "name": "<#if donation.anonymous><#include "donations_response_anonymous"><#else>${donation.name}", "value": "${donation.donationAmount}€", "inline": true } diff --git a/templates/sissi-templates/module-templates/debra-templates/src/main/resources/default/listener/debra_donation_notification_embed.ftl b/templates/sissi-templates/module-templates/debra-templates/src/main/resources/default/listener/debra_donation_notification_embed.ftl index 2ef5e495..e119dbd7 100644 --- a/templates/sissi-templates/module-templates/debra-templates/src/main/resources/default/listener/debra_donation_notification_embed.ftl +++ b/templates/sissi-templates/module-templates/debra-templates/src/main/resources/default/listener/debra_donation_notification_embed.ftl @@ -2,12 +2,14 @@ "embeds": [ { "title": { - <#assign donatorName=donation.donatorName> + <#assign donatorName><#if donation.anonymous><#include "donations_response_anonymous"><#else>${donation.donatorName} <#assign donationAmount=donation.amount> "title": "<@safe_include "debra_donation_notification_embed_title"/>" }, - <#assign donationMessage=donation.message> - "description": "${donationMessage?json_string}", + <#if donation.message != 'gespendet'> + <#assign donationMessage=donation.message> + "description": "${donationMessage?json_string}", + "fields": [ { <#assign totalDonationAmount=totalDonationAmount> @@ -24,7 +26,7 @@ "buttons": [ { "label": "<@safe_include "debra_donation_notification_link_button_label"/>", - "url": "http://tiny.cc/schmetterling2024", + "url": "https://tinyurl.com/debra25", "buttonStyle": "link", "metaConfig": { "persistCallback": false diff --git a/templates/sissi-translations/module-translations/debra-translations/src/main/resources/de_DE/commands/donations/donations_response_description_de_DE.ftl b/templates/sissi-translations/module-translations/debra-translations/src/main/resources/de_DE/commands/donations/donations_response_description_de_DE.ftl index 4989bc2d..489aa57f 100644 --- a/templates/sissi-translations/module-translations/debra-translations/src/main/resources/de_DE/commands/donations/donations_response_description_de_DE.ftl +++ b/templates/sissi-translations/module-translations/debra-translations/src/main/resources/de_DE/commands/donations/donations_response_description_de_DE.ftl @@ -1 +1 @@ -Aktuell wurden **${donationAmount} Euro** für Debra Austria gespendet. Spende auch du unter https://tiny.cc/schmetterling2024. \ No newline at end of file +Aktuell wurden **${donationAmount} Euro** für Debra Austria gespendet. Spende auch du unter https://tinyurl.com/debra25. \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/debra-translations/src/main/resources/de_DE/listener/debraInfoMessage_text_de_DE.ftl b/templates/sissi-translations/module-translations/debra-translations/src/main/resources/de_DE/listener/debraInfoMessage_text_de_DE.ftl index 12fd78e5..89886efa 100644 --- a/templates/sissi-translations/module-translations/debra-translations/src/main/resources/de_DE/listener/debraInfoMessage_text_de_DE.ftl +++ b/templates/sissi-translations/module-translations/debra-translations/src/main/resources/de_DE/listener/debraInfoMessage_text_de_DE.ftl @@ -10,7 +10,7 @@ Alle Grafiken von diesem und den letzten Jahren findest du in diesem Ordner. All Spendenlink Wir empfehlen neben dem Einrichten einer 'Kachel' auch, dass ihr einen !spenden Befehl bei eurem Bot (nightbot, moobot, self hosted etc.) hinzufügt. -Bitte verlinke dabei auf +Bitte verlinke dabei auf Live-ping am Discord Damit wir deinen Account zur Going Live Liste hinzufügen können, musst du uns nach der Einrichtung des Streams bescheid geben. diff --git a/templates/sissi-translations/module-translations/debra-translations/src/main/resources/de_DE/listener/debra_donation_notification_embed_footer_de_DE.ftl b/templates/sissi-translations/module-translations/debra-translations/src/main/resources/de_DE/listener/debra_donation_notification_embed_footer_de_DE.ftl index 762ce383..17984722 100644 --- a/templates/sissi-translations/module-translations/debra-translations/src/main/resources/de_DE/listener/debra_donation_notification_embed_footer_de_DE.ftl +++ b/templates/sissi-translations/module-translations/debra-translations/src/main/resources/de_DE/listener/debra_donation_notification_embed_footer_de_DE.ftl @@ -1 +1 @@ -Spende auch du für Debra Austria unter http://tiny.cc/schmetterling2024. \ No newline at end of file +Spende auch du für Debra Austria unter https://tinyurl.com/debra25. \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/debra-translations/src/main/resources/default/commands/donations/help/donations_parameter_type_choice_LATEST.ftl b/templates/sissi-translations/module-translations/debra-translations/src/main/resources/default/commands/donations/help/donations_parameter_type_choice_LATEST.ftl new file mode 100644 index 00000000..3b654509 --- /dev/null +++ b/templates/sissi-translations/module-translations/debra-translations/src/main/resources/default/commands/donations/help/donations_parameter_type_choice_LATEST.ftl @@ -0,0 +1 @@ +The latest donations \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/debra-translations/src/main/resources/default/commands/donations/help/donations_parameter_type_choice_TOP.ftl b/templates/sissi-translations/module-translations/debra-translations/src/main/resources/default/commands/donations/help/donations_parameter_type_choice_TOP.ftl new file mode 100644 index 00000000..56a5530c --- /dev/null +++ b/templates/sissi-translations/module-translations/debra-translations/src/main/resources/default/commands/donations/help/donations_parameter_type_choice_TOP.ftl @@ -0,0 +1 @@ +The highest donations \ No newline at end of file diff --git a/templates/sissi-translations/module-translations/debra-translations/src/main/resources/default/listener/debra_donation_notification_embed_footer.ftl b/templates/sissi-translations/module-translations/debra-translations/src/main/resources/default/listener/debra_donation_notification_embed_footer.ftl index 3dbaebb0..aa6de16d 100644 --- a/templates/sissi-translations/module-translations/debra-translations/src/main/resources/default/listener/debra_donation_notification_embed_footer.ftl +++ b/templates/sissi-translations/module-translations/debra-translations/src/main/resources/default/listener/debra_donation_notification_embed_footer.ftl @@ -1 +1 @@ -Also donate for Debra austria via http://tiny.cc/schmetterling2024. \ No newline at end of file +Also donate for Debra austria via https://tinyurl.com/debra25. \ No newline at end of file