Compare commits

...

30 Commits

Author SHA1 Message Date
Sheldan
37147a866f [maven-release-plugin] prepare release sissi-1.4.28 2023-12-10 14:59:29 +01:00
Sheldan
9a7d0613b1 [SIS-xxx] enabling giveaway module
updating to newer abstracto version
preparing for release
2023-12-10 14:58:19 +01:00
Sheldan
7e60447ae6 [maven-release-plugin] prepare for next development iteration 2023-12-01 23:39:45 +01:00
Sheldan
e4a899a125 [maven-release-plugin] prepare release sissi-1.4.27 2023-12-01 23:39:41 +01:00
Sheldan
ce8341e69a [SIS-xxx] changing caching
prepare for release
2023-12-01 23:38:38 +01:00
Sheldan
fa6333fa49 [maven-release-plugin] prepare for next development iteration 2023-12-01 23:16:02 +01:00
Sheldan
3393dea591 [maven-release-plugin] prepare release sissi-1.4.26 2023-12-01 23:15:57 +01:00
Sheldan
3c3bdfaed9 [SIS-xxx] preparing for release 2023-12-01 23:15:31 +01:00
Sheldan
172e3c4190 [SIS-xxx] adding uuid to clear cache 2023-12-01 23:14:57 +01:00
Sheldan
52b86804b9 [maven-release-plugin] prepare for next development iteration 2023-12-01 22:54:18 +01:00
Sheldan
de8d9982f3 [maven-release-plugin] prepare release sissi-1.4.25 2023-12-01 22:54:14 +01:00
Sheldan
29e1b22783 [SIS-xxx] preparing for release 2023-12-01 22:53:37 +01:00
Sheldan
5852d4837e [SIS-xxx] synchronizing the lookup for donations, so that simultaneous calls are not possible 2023-12-01 22:49:34 +01:00
Sheldan
b345fa5502 [SIS-xxx] fixing logging setup in case of a debra donation loading error 2023-11-30 21:02:16 +01:00
Sheldan
d6470e3714 [SIS-xxx] changing meetup time display to include week day name 2023-11-30 19:55:47 +01:00
Sheldan
b4cebe2b41 [maven-release-plugin] prepare for next development iteration 2023-11-29 21:08:14 +01:00
Sheldan
f3dd85d7d5 [maven-release-plugin] prepare release sissi-1.4.24 2023-11-29 21:08:10 +01:00
Sheldan
db318afb2b [SIS-xxx] preparing for release 2023-11-29 21:07:34 +01:00
Sheldan
ddd710d1c2 [SIS-xxx] changing wording of debra campaign info image 2023-11-29 21:05:02 +01:00
Sheldan
81824db1f1 [SIS-xxx] adding html wrapper for debra images
restructuring and splitting image generation into multiple files
adding doge sun image generation
2023-11-29 00:04:29 +01:00
Sheldan
0390d7c8ca [maven-release-plugin] prepare for next development iteration 2023-11-23 01:04:11 +01:00
Sheldan
61412f434c [maven-release-plugin] prepare release sissi-1.4.23 2023-11-23 01:04:07 +01:00
Sheldan
12e69a18fb [SIS-xxx] preparing for release 2023-11-23 01:02:35 +01:00
Sheldan
170ddd9c33 [SIS-xxx] fixing cache setup to add additional caches instead of overwriting the provided configuration 2023-11-23 01:01:40 +01:00
Sheldan
de8bbdcbee [SIS-xxx] fixing rest api image version 2023-11-21 00:39:07 +01:00
Sheldan
b5bf53fb6a [maven-release-plugin] prepare for next development iteration 2023-11-21 00:25:40 +01:00
Sheldan
159326dde3 [maven-release-plugin] prepare release sissi-1.4.22 2023-11-21 00:25:32 +01:00
Sheldan
7124d4e1d8 [SIS-xxx] prepare for release 2023-11-21 00:24:47 +01:00
Sheldan
c6f20d617d [SIS-xxx] adding rendering of current Debra donation information
updating for Debra 2023 campaign
adding internal rest api for debra information
adding a debra button to receive information
2023-11-21 00:23:03 +01:00
Sheldan
7449c05462 [maven-release-plugin] prepare for next development iteration 2023-11-14 23:41:52 +01:00
124 changed files with 1234 additions and 95 deletions

View File

@@ -28,6 +28,7 @@ docker_build_with_restart(
) )
docker_build(registry + 'sissi-db-data', 'deployment/image-packaging/src/main/docker/db-data/') docker_build(registry + 'sissi-db-data', 'deployment/image-packaging/src/main/docker/db-data/')
docker_build(registry + 'sissi-rest-api', 'deployment/image-packaging/src/main/docker/rest-api/')
docker_build(registry + 'sissi-template-data', 'deployment/image-packaging/src/main/docker/template-data/') docker_build(registry + 'sissi-template-data', 'deployment/image-packaging/src/main/docker/template-data/')

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.sissi.application</groupId> <groupId>dev.sheldan.sissi.application</groupId>
<artifactId>application</artifactId> <artifactId>application</artifactId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>executable</artifactId> <artifactId>executable</artifactId>
@@ -136,6 +136,11 @@
<artifactId>statistic-impl</artifactId> <artifactId>statistic-impl</artifactId>
</dependency> </dependency>
<dependency>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>giveaway-impl</artifactId>
</dependency>
<!-- sissi modules --> <!-- sissi modules -->
<dependency> <dependency>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.sissi</groupId> <groupId>dev.sheldan.sissi</groupId>
<artifactId>sissi</artifactId> <artifactId>sissi</artifactId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.sissi.application.module.custom</groupId> <groupId>dev.sheldan.sissi.application.module.custom</groupId>
<artifactId>sissi-customizations</artifactId> <artifactId>sissi-customizations</artifactId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>application</artifactId> <artifactId>application</artifactId>
<groupId>dev.sheldan.sissi.application</groupId> <groupId>dev.sheldan.sissi.application</groupId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.sissi.application</groupId> <groupId>dev.sheldan.sissi.application</groupId>
<artifactId>sissi-modules</artifactId> <artifactId>sissi-modules</artifactId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@@ -15,6 +15,19 @@
<groupId>com.google.code.gson</groupId> <groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId> <artifactId>gson</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<classifier>jakarta</classifier>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@@ -0,0 +1,69 @@
package dev.sheldan.sissi.module.debra.api;
import dev.sheldan.sissi.module.debra.model.api.*;
import dev.sheldan.sissi.module.debra.service.DonationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
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 {
@Autowired
private DonationService donationService;
@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);
List<DonationInfo> donations = donationService.getLatestDonations(donationResponse, Integer.MAX_VALUE)
.stream()
.map(DonationInfo::fromDonationItemModel)
.toList();
return DonationStats
.builder()
.totalAmount(donationResponse.getPage().getCollected())
.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);
List<DonationInfo> donations = donationService.getHighestDonations(donationResponse, Integer.MAX_VALUE)
.stream()
.map(DonationInfo::fromDonationItemModel)
.toList();
return DonationStats
.builder()
.totalAmount(donationResponse.getPage().getCollected())
.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);
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();
}
}

View File

@@ -0,0 +1,91 @@
package dev.sheldan.sissi.module.debra.commands;
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
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.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.sissi.module.debra.config.DebraFeatureDefinition;
import dev.sheldan.sissi.module.debra.config.DebraSlashCommandNames;
import dev.sheldan.sissi.module.debra.service.DonationService;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Component
public class DebraInfoButton extends AbstractConditionableCommand {
private static final String DEBRA_INFO_BUTTON = "debraInfoButton";
private static final String DEBRA_INFO_BUTTON_RESPONSE_TEMPLATE_KEY = "debraInfoButton_response";
private static final String TARGET_CHANNEL_PARAMETER_KEY = "targetChannel";
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private InteractionService interactionService;
@Autowired
private DonationService donationService;
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
GuildMessageChannel targetChannel = slashCommandParameterService.getCommandOption(TARGET_CHANNEL_PARAMETER_KEY, event, GuildMessageChannel.class);
return donationService.sendDebraInfoButtonMessage(targetChannel)
.thenCompose(unused -> interactionService.replyEmbed(DEBRA_INFO_BUTTON_RESPONSE_TEMPLATE_KEY, event))
.thenApply(interactionHook -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.rootCommandName(DebraSlashCommandNames.DEBRA_INTERNAL)
.commandName("debrainfobutton")
.build();
Parameter targetChannelParameter = Parameter
.builder()
.templated(true)
.name(TARGET_CHANNEL_PARAMETER_KEY)
.type(GuildMessageChannel.class)
.build();
List<Parameter> parameters = Arrays.asList(targetChannelParameter);
return CommandConfiguration.builder()
.name(DEBRA_INFO_BUTTON)
.module(UtilityModuleDefinition.UTILITY)
.templated(true)
.slashCommandConfig(slashCommandConfig)
.async(true)
.slashCommandOnly(true)
.parameters(parameters)
.supportsEmbedException(true)
.causesReaction(false)
.help(helpInfo)
.build();
}
@Override
public FeatureDefinition getFeature() {
return DebraFeatureDefinition.DEBRA;
}
}

View File

@@ -113,20 +113,16 @@ public class Donations extends AbstractConditionableCommand {
private MessageToSend getDonationMessageToSend(Long serverId, Integer top, Integer latest) { private MessageToSend getDonationMessageToSend(Long serverId, Integer top, Integer latest) {
DonationsModel donationModel; DonationsModel donationModel;
try { DonationsResponse donationResponse = donationService.fetchCurrentDonationAmount(serverId);
DonationsResponse donationResponse = donationService.fetchCurrentDonationAmount(serverId); donationModel = donationConverter.convertDonationResponse(donationResponse);
donationModel = donationConverter.convertDonationResponse(donationResponse); if(top != null) {
if(top != null) { donationModel.setDonations(donationService.getHighestDonations(donationResponse, top));
donationModel.setDonations(donationService.getHighestDonations(donationResponse, top)); donationModel.setType(DonationsModel.DonationType.TOP);
donationModel.setType(DonationsModel.DonationType.TOP); } else if(latest != null) {
} else if(latest != null) { donationModel.setType(DonationsModel.DonationType.LATEST);
donationModel.setType(DonationsModel.DonationType.LATEST); donationModel.setDonations(donationService.getLatestDonations(donationResponse, latest));
donationModel.setDonations(donationService.getLatestDonations(donationResponse, latest)); } else {
} else { donationModel.setDonations(new ArrayList<>());
donationModel.setDonations(new ArrayList<>());
}
} catch (IOException e) {
throw new AbstractoRunTimeException("Failed to load donation amount.", e);
} }
return templateService.renderEmbedTemplate(DONATIONS_RESPONSE_TEMPLATE_KEY, donationModel); return templateService.renderEmbedTemplate(DONATIONS_RESPONSE_TEMPLATE_KEY, donationModel);
} }

View File

@@ -0,0 +1,33 @@
package dev.sheldan.sissi.module.debra.config;
import lombok.extern.slf4j.Slf4j;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.jsr107.Eh107Configuration;
import org.ehcache.xml.XmlConfiguration;
import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.net.URL;
@Configuration
@Slf4j
@EnableCaching
public class CacheConfig {
@Bean
public JCacheManagerCustomizer cacheManagerCustomizer() {
URL myUrl = getClass().getResource("/donation-cache-config.xml");
XmlConfiguration xmlConfig = new XmlConfiguration(myUrl);
org.ehcache.CacheManager myCacheManager = CacheManagerBuilder.newCacheManager(xmlConfig);
return cm -> {
myCacheManager.getRuntimeConfiguration().getCacheConfigurations().entrySet().forEach(cacheConfiguration -> {
javax.cache.configuration.Configuration<?, ?> jConfiguration = Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfiguration.getValue());
log.info("Creating custom cache: " + cacheConfiguration.getKey());
cm.createCache(cacheConfiguration.getKey(), jConfiguration);
});
};
}
}

View File

@@ -2,4 +2,5 @@ package dev.sheldan.sissi.module.debra.config;
public class DebraSlashCommandNames { public class DebraSlashCommandNames {
public static final String DEBRA = "debra"; public static final String DEBRA = "debra";
public static final String DEBRA_INTERNAL = "debrainternal";
} }

View File

@@ -0,0 +1,71 @@
package dev.sheldan.sissi.module.debra.listener;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.config.ListenerPriority;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListener;
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerModel;
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerResult;
import dev.sheldan.abstracto.core.service.MessageService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.sissi.module.debra.config.DebraFeatureDefinition;
import dev.sheldan.sissi.module.debra.service.DonationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class DebraInfoButtonClickedListener implements ButtonClickedListener {
@Autowired
private MessageService messageService;
@Autowired
private TemplateService templateService;
@Autowired
private InteractionService interactionService;
private static final String DEBRA_INFO_MESSAGE_TEMPLATE_KEY = "debraInfoMessage";
private static final String DEBRA_INFO_MESSAGE_RESPONSE_TEMPLATE_KEY = "debraInfoMessage_response";
@Override
public ButtonClickedListenerResult execute(ButtonClickedListenerModel model) {
MessageToSend messageToSend = templateService.renderEmbedTemplate(DEBRA_INFO_MESSAGE_TEMPLATE_KEY, new Object(), model.getServerId());
messageService.sendMessageToSendToUser(model.getEvent().getUser(), messageToSend).thenAccept(interactionHook -> {
log.info("Send debra info message to user {}", model.getEvent().getUser().getIdLong());
}).exceptionally(throwable -> {
log.error("Failed to send debra info message to user {}", model.getEvent().getUser().getIdLong(), throwable);
return null;
});
MessageToSend responseMessageToSend = templateService.renderEmbedTemplate(DEBRA_INFO_MESSAGE_RESPONSE_TEMPLATE_KEY, new Object(), model.getServerId());
FutureUtils.toSingleFutureGeneric(interactionService.sendMessageToInteraction(responseMessageToSend, model.getEvent().getInteraction().getHook()))
.thenAccept(interactionHook -> {
log.info("Send debra info message response to user {}", model.getEvent().getUser().getIdLong());
}).exceptionally(throwable -> {
log.error("Failed to send debra info message response to user {}", model.getEvent().getUser().getIdLong(), throwable);
return null;
});
return ButtonClickedListenerResult.ACKNOWLEDGED;
}
@Override
public Boolean handlesEvent(ButtonClickedListenerModel model) {
return model.getOrigin().equals(DonationService.DEBRA_INFO_BUTTON_ORIGIN);
}
@Override
public FeatureDefinition getFeature() {
return DebraFeatureDefinition.DEBRA;
}
@Override
public Integer getPriority() {
return ListenerPriority.MEDIUM;
}
}

View File

@@ -0,0 +1,20 @@
package dev.sheldan.sissi.module.debra.model.api;
import lombok.Builder;
import lombok.Getter;
import java.math.BigDecimal;
import java.math.BigInteger;
@Builder
@Getter
public class CampaignInfo {
private BigInteger donationCount;
private BigDecimal collected;
private BigDecimal target;
private String currency;
private String slug;
private String displayName;
private BigDecimal collectedNet;
private BigDecimal percent;
}

View File

@@ -1,5 +1,6 @@
package dev.sheldan.sissi.module.debra.model.api; package dev.sheldan.sissi.module.debra.model.api;
import com.google.gson.annotations.SerializedName;
import lombok.Builder; import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -10,11 +11,18 @@ import java.math.BigDecimal;
@Setter @Setter
@Builder @Builder
public class Description { public class Description {
@SerializedName("collected")
private BigDecimal collected; private BigDecimal collected;
@SerializedName("target")
private BigDecimal target; private BigDecimal target;
@SerializedName("currency")
private String currency; private String currency;
@SerializedName("slug")
private String slug; private String slug;
@SerializedName("displayname")
private String displayName; private String displayName;
@SerializedName("collectednet")
private BigDecimal collectedNet; private BigDecimal collectedNet;
@SerializedName("percent")
private BigDecimal percent; private BigDecimal percent;
} }

View File

@@ -1,5 +1,6 @@
package dev.sheldan.sissi.module.debra.model.api; package dev.sheldan.sissi.module.debra.model.api;
import com.google.gson.annotations.SerializedName;
import lombok.Builder; import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -10,10 +11,16 @@ import java.math.BigDecimal;
@Setter @Setter
@Builder @Builder
public class Donation { public class Donation {
@SerializedName("amount")
private BigDecimal amount; private BigDecimal amount;
@SerializedName("currency")
private String currency; private String currency;
@SerializedName("text")
private String text; private String text;
@SerializedName("anonym")
private Integer anonym; private Integer anonym;
@SerializedName("firstname")
private String firstname; private String firstname;
@SerializedName("lastname")
private String lastname; private String lastname;
} }

View File

@@ -0,0 +1,26 @@
package dev.sheldan.sissi.module.debra.model.api;
import dev.sheldan.sissi.module.debra.model.commands.DonationItemModel;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
@Getter
@Setter
@Builder
public class DonationInfo {
private String firstName;
private BigDecimal donationAmount;
private Boolean anonymous;
public static DonationInfo fromDonationItemModel(DonationItemModel donationItemModel) {
return DonationInfo
.builder()
.donationAmount(donationItemModel.getDonationAmount())
.anonymous(donationItemModel.getAnonymous())
.firstName(donationItemModel.getFirstName())
.build();
}
}

View File

@@ -0,0 +1,14 @@
package dev.sheldan.sissi.module.debra.model.api;
import lombok.Builder;
import lombok.Getter;
import java.math.BigDecimal;
import java.util.List;
@Getter
@Builder
public class DonationStats {
private List<DonationInfo> donations;
private BigDecimal totalAmount;
}

View File

@@ -1,5 +1,6 @@
package dev.sheldan.sissi.module.debra.model.api; package dev.sheldan.sissi.module.debra.model.api;
import com.google.gson.annotations.SerializedName;
import lombok.Builder; import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -11,7 +12,10 @@ import java.util.List;
@Setter @Setter
@Builder @Builder
public class DonationsResponse { public class DonationsResponse {
@SerializedName("page")
private Description page; private Description page;
@SerializedName("donation_count")
private BigInteger donationCount; private BigInteger donationCount;
@SerializedName("donations")
private List<Donation> donations; private List<Donation> donations;
} }

View File

@@ -0,0 +1,12 @@
package dev.sheldan.sissi.module.debra.model.commands;
import dev.sheldan.abstracto.core.interaction.button.ButtonPayload;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Builder
@Getter
@Setter
public class DebraInfoButtonPayload implements ButtonPayload {
}

View File

@@ -0,0 +1,10 @@
package dev.sheldan.sissi.module.debra.model.commands;
import lombok.Builder;
import lombok.Getter;
@Getter
@Builder
public class DebraInfoModel {
private String buttonId;
}

View File

@@ -2,10 +2,12 @@ package dev.sheldan.sissi.module.debra.model.commands;
import lombok.Builder; import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal; import java.math.BigDecimal;
@Getter @Getter
@Setter
@Builder @Builder
public class DonationItemModel { public class DonationItemModel {
private String firstName; private String firstName;

View File

@@ -0,0 +1,18 @@
package dev.sheldan.sissi.module.debra.service;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Component;
@Component
public class DonationCacheService implements InitializingBean {
@Autowired
private CacheManager cacheManager;
@Override
public void afterPropertiesSet() throws Exception {
cacheManager.getCache("donations");
}
}

View File

@@ -2,8 +2,14 @@ package dev.sheldan.sissi.module.debra.service;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; 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.ConfigService;
import dev.sheldan.abstracto.core.service.PostTargetService; 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.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService; import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.core.utils.FutureUtils; import dev.sheldan.abstracto.core.utils.FutureUtils;
@@ -13,17 +19,22 @@ import dev.sheldan.sissi.module.debra.config.DebraProperties;
import dev.sheldan.sissi.module.debra.converter.DonationConverter; 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.Donation;
import dev.sheldan.sissi.module.debra.model.api.DonationsResponse; 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.DonationItemModel;
import dev.sheldan.sissi.module.debra.model.commands.DonationsModel; import dev.sheldan.sissi.module.debra.model.commands.DonationsModel;
import dev.sheldan.sissi.module.debra.model.listener.DonationResponseModel; import dev.sheldan.sissi.module.debra.model.listener.DonationResponseModel;
import dev.sheldan.sissi.module.debra.model.listener.DonationNotificationModel; import dev.sheldan.sissi.module.debra.model.listener.DonationNotificationModel;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
@@ -60,10 +71,28 @@ public class DonationService {
@Autowired @Autowired
private ConfigService configService; private ConfigService configService;
@Autowired
private ChannelService channelService;
@Autowired
private ComponentService componentService;
@Autowired
private ComponentPayloadService componentPayloadService;
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private DonationService self;
private static final String DEBRA_DONATION_NOTIFICATION_TEMPLATE_KEY = "debra_donation_notification"; 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!<br \\/>Vielen Dank!<br \\/>Nachricht:<br \\/>(.*)"); private static final Pattern MESSAGE_PATTERN = Pattern.compile("(.*) hat (\\d{1,9},\\d{2}) Euro gespendet!<br \\/>Vielen Dank!<br \\/>Nachricht:<br \\/>(.*)");
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) { public DonationResponseModel parseDonationFromMessage(String message) {
Matcher matcher = MESSAGE_PATTERN.matcher(message); Matcher matcher = MESSAGE_PATTERN.matcher(message);
if (matcher.find()) { if (matcher.find()) {
@@ -105,23 +134,34 @@ public class DonationService {
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
public DonationsResponse fetchCurrentDonationAmount(Long serverId) throws IOException { public synchronized DonationsResponse getSynchronizedCachedDonationAmount(Long serverId) {
Long fetchSize = configService.getLongValueOrConfigDefault(DEBRA_DONATION_API_FETCH_SIZE_KEY, serverId); return self.getCachedDonationAmount(serverId);
Request request = new Request.Builder() }
.url(String.format(debraProperties.getDonationAPIUrl(), fetchSize))
.get() @Cacheable(value = "donation-cache")
.build(); public synchronized DonationsResponse getCachedDonationAmount(Long serverId) {
Response response = okHttpClient.newCall(request).execute(); return self.fetchCurrentDonationAmount(serverId);
if(!response.isSuccessful()) { }
if (log.isDebugEnabled()) {
log.error("Failed to retrieve urban dictionary definition. Response had code {} with body {}.", public DonationsResponse fetchCurrentDonationAmount(Long serverId) {
response.code(), response.body()); try {
} Long fetchSize = configService.getLongValueOrConfigDefault(DEBRA_DONATION_API_FETCH_SIZE_KEY, serverId);
throw new DonationAmountNotFoundException(); Request request = new Request.Builder()
} .url(String.format(debraProperties.getDonationAPIUrl(), fetchSize))
Gson gson = getGson(); .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();
}
Gson gson = getGson();
return gson.fromJson(response.body().string(), DonationsResponse.class);
} catch (Exception exception) {
throw new AbstractoRunTimeException(exception);
}
return gson.fromJson(response.body().string(), DonationsResponse.class);
} }
private Gson getGson() { private Gson getGson() {
@@ -130,7 +170,7 @@ public class DonationService {
.create(); .create();
} }
private DonationsModel getDonationInfoModel(Long serverId) throws IOException { private DonationsModel getDonationInfoModel(Long serverId) {
return donationConverter.convertDonationResponse(fetchCurrentDonationAmount(serverId)); return donationConverter.convertDonationResponse(fetchCurrentDonationAmount(serverId));
} }
@@ -148,4 +188,26 @@ public class DonationService {
firstMessage.addAll(secondMessage); firstMessage.addAll(secondMessage);
return FutureUtils.toSingleFutureGeneric(firstMessage); return FutureUtils.toSingleFutureGeneric(firstMessage);
} }
public CompletableFuture<Void> sendDebraInfoButtonMessage(GuildMessageChannel guildMessageChannel) {
String buttonId = componentService.generateComponentId();
DebraInfoModel model = DebraInfoModel
.builder()
.buttonId(buttonId)
.build();
MessageToSend messageToSend = templateService.renderEmbedTemplate(DEBRA_INFO_BUTTON_MESSAGE_TEMPLATE_KEY, model, guildMessageChannel.getGuild().getIdLong());
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, guildMessageChannel)).thenAccept(unused -> {
self.persistButtonPayload(guildMessageChannel, buttonId);
});
}
@Transactional
public void persistButtonPayload(GuildMessageChannel guildMessageChannel, String buttonId) {
DebraInfoButtonPayload payload = DebraInfoButtonPayload
.builder()
.build();
AServer server = serverManagementService.loadServer(guildMessageChannel.getGuild().getIdLong());
componentPayloadService.createButtonPayload(buttonId, payload, DEBRA_INFO_BUTTON_ORIGIN, server);
}
} }

View File

@@ -5,7 +5,7 @@ abstracto.postTargets.debraDonationNotification.name=debraDonationNotification
abstracto.postTargets.debraDonationNotification2.name=debraDonationNotification2 abstracto.postTargets.debraDonationNotification2.name=debraDonationNotification2
sissi.debra.websocketURL=ws://spenden.baba.fm:8765/ sissi.debra.websocketURL=ws://spenden.baba.fm:8765/
sissi.debra.donationAPIUrl=https://www.altruja.de/api/page/discord-fuer-debra-2022?details=1&num=%s&ort=0 sissi.debra.donationAPIUrl=https://www.altruja.de/api/page/discord-gg-austria-fuer-debra-2023?details=1&num=%s&ort=0
abstracto.systemConfigs.debraDonationNotificationDelayMillis.name=debraDonationNotificationDelayMillis abstracto.systemConfigs.debraDonationNotificationDelayMillis.name=debraDonationNotificationDelayMillis
abstracto.systemConfigs.debraDonationNotificationDelayMillis.longValue=60000 abstracto.systemConfigs.debraDonationNotificationDelayMillis.longValue=60000

View File

@@ -0,0 +1,24 @@
<config
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://www.ehcache.org/v3'
xsi:schemaLocation="
http://www.ehcache.org/v3
http://www.ehcache.org/schema/ehcache-core-3.8-1.xsd">
<cache uses-template="default" alias="donation-cache">
<expiry>
<ttl unit="seconds">120</ttl>
</expiry>
<resources>
<heap unit="entries">5</heap>
</resources>
</cache>
<cache-template name="default">
<expiry>
<ttl unit="seconds">600</ttl>
</expiry>
<resources>
<heap>50</heap>
</resources>
</cache-template>
</config>

View File

@@ -0,0 +1,10 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<include file="seedData/data.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,20 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<property name="utilityModule" value="(SELECT id FROM module WHERE name = 'utility')"/>
<property name="debraFeature" value="(SELECT id FROM feature WHERE key = 'debra')"/>
<changeSet author="Sheldan" id="debraInfoButton-command">
<insert tableName="command">
<column name="name" value="debraInfoButton"/>
<column name="module_id" valueComputed="${utilityModule}"/>
<column name="feature_id" valueComputed="${debraFeature}"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,10 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<include file="command.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -7,4 +7,5 @@
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" > http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
<include file="1.3.6/collection.xml" relativeToChangelogFile="true"/> <include file="1.3.6/collection.xml" relativeToChangelogFile="true"/>
<include file="1.4.21/collection.xml" relativeToChangelogFile="true"/>
</databaseChangeLog> </databaseChangeLog>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.sissi.application</groupId> <groupId>dev.sheldan.sissi.application</groupId>
<artifactId>sissi-modules</artifactId> <artifactId>sissi-modules</artifactId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.sissi.application</groupId> <groupId>dev.sheldan.sissi.application</groupId>
<artifactId>application</artifactId> <artifactId>application</artifactId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.sissi.application</groupId> <groupId>dev.sheldan.sissi.application</groupId>
<artifactId>sissi-modules</artifactId> <artifactId>sissi-modules</artifactId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>sissi-modules</artifactId> <artifactId>sissi-modules</artifactId>
<groupId>dev.sheldan.sissi.application</groupId> <groupId>dev.sheldan.sissi.application</groupId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -15,10 +15,10 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes # This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version. # to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/) # Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 1.4.21 version: 1.4.28
# This is the version number of the application being deployed. This version number should be # This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to # incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using. # follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes. # It is recommended to use it with quotes.
appVersion: "1.4.21" appVersion: "1.4.28"

View File

@@ -0,0 +1,70 @@
{{- if .Values.restApi.enabled -}}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "sissi.fullname" . }}-rest-api
spec:
replicas: 1
selector:
matchLabels:
app: rest-api
template:
metadata:
{{- with .Values.restApi.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
app: rest-api
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "sissi.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.restApi.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.restApi.securityContext | nindent 12 }}
image: "{{ .Values.restApi.repository }}/{{ .Values.restApi.image }}:{{ .Values.restApi.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.restApi.pullPolicy }}
env:
- name: SISSI_HOST
value: "{{ include "sissi.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local"
- name: SISSI_PORT
value: "{{ .Values.service.port }}"
ports:
- name: {{ .Values.restApi.service.name }}
containerPort: {{ .Values.restApi.service.port }}
protocol: TCP
livenessProbe:
httpGet:
path: /
port: {{ .Values.restApi.service.port }}
initialDelaySeconds: {{ $.Values.restApi.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ $.Values.restApi.livenessProbe.periodSeconds }}
failureThreshold: {{ $.Values.restApi.livenessProbe.failureThreshold }}
readinessProbe:
httpGet:
path: /
port: {{ .Values.restApi.service.port }}
initialDelaySeconds: {{ $.Values.restApi.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ $.Values.restApi.readinessProbe.periodSeconds }}
failureThreshold: {{ $.Values.restApi.readinessProbe.failureThreshold }}
resources:
{{- toYaml .Values.restApi.resources | nindent 12 }}
{{- with .Values.restApi.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.restApi.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.restApi.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,45 @@
{{- if .Values.restApi.enabled -}}
{{- $servicePort := .Values.restApi.service.port -}}
{{- $serviceName := .Values.restApi.service.name -}}
{{- $ingressPath := .Values.restApi.ingress.path -}}
{{- $ingressPathType := .Values.restApi.ingress.pathType -}}
{{- $extraPaths := .Values.restApi.ingress.extraPaths -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-rest-api
labels:
{{- with .Values.restApi.ingress.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.restApi.ingress.annotations }}
annotations:
{{- range $key, $value := . }}
{{ $key }}: {{ tpl $value $ | quote }}
{{- end }}
{{- end }}
spec:
ingressClassName: nginx
{{- with .Values.restApi.ingress.tls }}
tls:
{{- tpl (toYaml .) $ | nindent 4 }}
{{- end }}
rules:
{{- if .Values.restApi.ingress.hosts }}
{{- range .Values.restApi.ingress.hosts }}
- host: {{ tpl . $ }}
http:
paths:
{{- with $extraPaths }}
{{- toYaml . | nindent 10 }}
{{- end }}
- path: {{ $ingressPath }}
pathType: {{ $ingressPathType }}
backend:
service:
name: {{ $serviceName }}
port:
number: {{ $servicePort }}
{{- end }}
{{- end -}}
{{- end }}

View File

@@ -0,0 +1,12 @@
{{- if .Values.restApi.enabled -}}
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.restApi.service.name }}
spec:
selector:
app: rest-api
ports:
- port: {{ .Values.restApi.service.targetPort }}
targetPort: {{ .Values.restApi.service.port }}
{{- end }}

View File

@@ -8,7 +8,7 @@ bot:
repository: harbor.sheldan.dev/sissi repository: harbor.sheldan.dev/sissi
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
image: sissi-bot image: sissi-bot
tag: 1.4.21 tag: 1.4.28
livenessProbe: livenessProbe:
initialDelaySeconds: 60 initialDelaySeconds: 60
periodSeconds: 5 periodSeconds: 5
@@ -20,31 +20,74 @@ bot:
propertyConfig: propertyConfig:
hikariPoolSize: 10 hikariPoolSize: 10
restApi:
enabled: true
repository: harbor.sheldan.dev/sissi
pullPolicy: IfNotPresent
image: sissi-rest-api
tag: 1.4.28
podAnnotations: {}
podSecurityContext: {}
securityContext: {}
livenessProbe:
initialDelaySeconds: 2
periodSeconds: 5
failureThreshold: 3
readinessProbe:
initialDelaySeconds: 2
periodSeconds: 5
failureThreshold: 3
service:
port: 8080
targetPort: 80
name: rest-api
resources:
limits:
cpu:
memory:
requests:
cpu:
memory:
nodeSelector: {}
tolerations: []
affinity: {}
ingress:
enabled: false
annotations: {}
labels: {}
path: /
pathType: Prefix
hosts:
extraPaths: []
tls: []
templateDeployment: templateDeployment:
enabled: true enabled: true
repository: harbor.sheldan.dev/abstracto repository: harbor.sheldan.dev/abstracto
pullPolicy: Always pullPolicy: Always
image: abstracto-template-deployment image: abstracto-template-deployment
tag: 1.5.12 tag: 1.5.13
templateDeploymentData: templateDeploymentData:
repository: harbor.sheldan.dev/sissi repository: harbor.sheldan.dev/sissi
pullPolicy: Always pullPolicy: Always
image: sissi-template-data image: sissi-template-data
tag: 1.4.21 tag: 1.4.28
dbConfigDeployment: dbConfigDeployment:
enabled: true enabled: true
repository: harbor.sheldan.dev/abstracto repository: harbor.sheldan.dev/abstracto
pullPolicy: Always pullPolicy: Always
image: abstracto-db-deployment image: abstracto-db-deployment
tag: 1.5.12 tag: 1.5.13
dbConfigDeploymentData: dbConfigDeploymentData:
repository: harbor.sheldan.dev/sissi repository: harbor.sheldan.dev/sissi
pullPolicy: Always pullPolicy: Always
image: sissi-db-data image: sissi-db-data
tag: 1.4.21 tag: 1.4.28
dbCredentials: dbCredentials:
host: host:

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.sissi</groupId> <groupId>dev.sheldan.sissi</groupId>
<artifactId>deployment</artifactId> <artifactId>deployment</artifactId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@@ -203,6 +203,16 @@
<destFileName>statistic.zip</destFileName> <destFileName>statistic.zip</destFileName>
</artifactItem> </artifactItem>
<artifactItem>
<groupId>dev.sheldan.abstracto-templates.templates</groupId>
<artifactId>giveaway</artifactId>
<version>${abstracto.templates.version}</version>
<type>zip</type>
<overWrite>true</overWrite>
<outputDirectory>${file.basedir}/template-data/template-artifacts/</outputDirectory>
<destFileName>giveaway.zip</destFileName>
</artifactItem>
<!-- sissi template artefacts --> <!-- sissi template artefacts -->
<artifactItem> <artifactItem>
<groupId>dev.sheldan.sissi.templates</groupId> <groupId>dev.sheldan.sissi.templates</groupId>
@@ -418,6 +428,16 @@
<destFileName>statistic.zip</destFileName> <destFileName>statistic.zip</destFileName>
</artifactItem> </artifactItem>
<artifactItem>
<groupId>dev.sheldan.abstracto-templates.translations</groupId>
<artifactId>giveaway</artifactId>
<version>${abstracto.templates.version}</version>
<type>zip</type>
<overWrite>true</overWrite>
<outputDirectory>${file.basedir}/template-data/translation-artifacts/</outputDirectory>
<destFileName>giveaway.zip</destFileName>
</artifactItem>
<!-- sissi translation artefacts --> <!-- sissi translation artefacts -->
<artifactItem> <artifactItem>
@@ -707,6 +727,17 @@
<destFileName>statistic.zip</destFileName> <destFileName>statistic.zip</destFileName>
</artifactItem> </artifactItem>
<artifactItem>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>giveaway-impl</artifactId>
<version>${abstracto.version}</version>
<classifier>liquibase</classifier>
<type>zip</type>
<overWrite>true</overWrite>
<outputDirectory>${file.basedir}/db-data/liquibase-artifacts/</outputDirectory>
<destFileName>giveaway.zip</destFileName>
</artifactItem>
<!-- customizations --> <!-- customizations -->
<artifactItem> <artifactItem>
@@ -797,6 +828,27 @@
</artifactItems> </artifactItems>
</configuration> </configuration>
</plugin> </plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>src/main/docker/rest-api/python</outputDirectory>
<resources>
<resource>
<directory>../../python/modules/rest-api/</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins> </plugins>
</build> </build>

View File

@@ -1,2 +1,2 @@
REGISTRY_PREFIX=harbor.sheldan.dev/sissi/ REGISTRY_PREFIX=harbor.sheldan.dev/sissi/
VERSION=1.4.21 VERSION=1.4.28

View File

@@ -8,6 +8,7 @@
{ "zip": "statistic", "file": "statistic-changeLog.xml"}, { "zip": "statistic", "file": "statistic-changeLog.xml"},
{ "zip": "starboard", "file": "starboard-changeLog.xml"}, { "zip": "starboard", "file": "starboard-changeLog.xml"},
{ "zip": "quotes", "file": "quotes-changeLog.xml"}, { "zip": "quotes", "file": "quotes-changeLog.xml"},
{ "zip": "giveaway", "file": "giveaway-changeLog.xml"},
{ "zip": "meetup", "file": "meetup-changeLog.xml"}, { "zip": "meetup", "file": "meetup-changeLog.xml"},
{ "zip": "rss-news", "file": "rssNews-changeLog.xml"}, { "zip": "rss-news", "file": "rssNews-changeLog.xml"},
{ "zip": "debra", "file": "debra-changeLog.xml"}, { "zip": "debra", "file": "debra-changeLog.xml"},

View File

@@ -5,6 +5,10 @@ services:
build: build:
context: sissi context: sissi
image: ${REGISTRY_PREFIX}sissi-bot:${VERSION:-latest} image: ${REGISTRY_PREFIX}sissi-bot:${VERSION:-latest}
rest-api:
build:
context: rest-api
image: ${REGISTRY_PREFIX}sissi-rest-api:${VERSION:-latest}
db-data: db-data:
build: build:
context: db-data context: db-data

View File

@@ -0,0 +1,9 @@
FROM python:3.10.13-alpine3.18
ADD requirements.txt /
RUN pip install -r requirements.txt
RUN apk --no-cache add msttcorefonts-installer fontconfig && \
update-ms-fonts && \
fc-cache -f
ADD wrapper /
ADD python /python
CMD ["/run.sh"]

View File

@@ -0,0 +1 @@
*

View File

@@ -0,0 +1,16 @@
blinker==1.7.0
certifi==2023.7.22
charset-normalizer==3.3.2
click==8.1.7
Flask==3.0.0
idna==3.4
importlib-metadata==6.8.0
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.3
Pillow==10.1.0
requests==2.31.0
urllib3==2.0.7
waitress==2.1.2
Werkzeug==3.0.1
zipp==3.17.0

View File

@@ -0,0 +1,4 @@
#!/bin/sh
echo "Starting python server..."
cd python && python3 -u main.py

View File

@@ -1,13 +1,13 @@
{ {
"template_artifacts": [ "template_artifacts": [
"core","starboard", "link-embed", "moderation", "entertainment", "custom-command", "utility", "webservices", "remind", "suggestion", "modmail", "assignable-roles", "experience-tracking", "logging", "statistic", "twitch", "core","starboard", "link-embed", "moderation", "entertainment", "custom-command", "utility", "webservices", "remind", "suggestion", "modmail", "assignable-roles", "experience-tracking", "logging", "statistic", "twitch", "giveaway",
"quotes", "meetup", "debra", "rss-news", "quotes", "meetup", "debra", "rss-news",
"moderation-custom", "moderation-custom",
"moderation-template-overrides", "experience-template-overrides", "logging-template-overrides" "moderation-template-overrides", "experience-template-overrides", "logging-template-overrides"
], ],
"translation_artifacts": [ "translation_artifacts": [
"core", "core",
"starboard", "link-embed", "moderation", "entertainment", "custom-command", "utility", "webservices", "suggestion", "remind", "modmail", "assignable-roles", "experience-tracking", "logging", "statistic", "twitch", "starboard", "link-embed", "moderation", "entertainment", "custom-command", "utility", "webservices", "suggestion", "remind", "modmail", "assignable-roles", "experience-tracking", "logging", "statistic", "twitch", "giveaway",
"quotes", "meetup", "debra", "rss-news", "quotes", "meetup", "debra", "rss-news",
"moderation-custom", "moderation-custom",
"moderation-translation-overrides", "experience-translation-overrides", "logging-translation-overrides" "moderation-translation-overrides", "experience-translation-overrides", "logging-translation-overrides"

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.sissi</groupId> <groupId>dev.sheldan.sissi</groupId>
<artifactId>sissi</artifactId> <artifactId>sissi</artifactId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -13,15 +13,15 @@
<groupId>dev.sheldan.sissi</groupId> <groupId>dev.sheldan.sissi</groupId>
<artifactId>sissi</artifactId> <artifactId>sissi</artifactId>
<name>Sissi</name> <name>Sissi</name>
<version>1.4.21</version> <version>1.4.28</version>
<properties> <properties>
<maven.compiler.target>17</maven.compiler.target> <maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source> <maven.compiler.source>17</maven.compiler.source>
<!-- edit in release.yml as well --> <!-- edit in release.yml as well -->
<!-- when releasing a new bot version, update the .env as well--> <!-- when releasing a new bot version, update the .env as well-->
<abstracto.version>1.5.12</abstracto.version> <abstracto.version>1.5.13</abstracto.version>
<abstracto.templates.version>1.4.23</abstracto.templates.version> <abstracto.templates.version>1.4.24</abstracto.templates.version>
<apache-jena.version>4.9.0</apache-jena.version> <apache-jena.version>4.9.0</apache-jena.version>
<rssreader.version>3.5.0</rssreader.version> <rssreader.version>3.5.0</rssreader.version>
</properties> </properties>
@@ -59,7 +59,7 @@
<scm> <scm>
<url>https://maven.pkg.github.com/Sheldan/Sissi</url> <url>https://maven.pkg.github.com/Sheldan/Sissi</url>
<developerConnection>scm:git:git@github.com:Sheldan/Sissi.git</developerConnection> <developerConnection>scm:git:git@github.com:Sheldan/Sissi.git</developerConnection>
<tag>sissi-1.4.21</tag> <tag>sissi-1.4.28</tag>
</scm> </scm>
</project> </project>

View File

@@ -0,0 +1,225 @@
from flask import request, render_template
from PIL import Image, ImageDraw, ImageFont
import requests
import os
import json
import logging
import uuid
from __main__ import app
from utils import serve_pil_image
sissi_host = os.getenv('SISSI_HOST')
sissi_port = os.getenv('SISSI_PORT')
latest_donations_url = f'http://{sissi_host}:{sissi_port}/debra/latestDonations'
highest_donations_url = f'http://{sissi_host}:{sissi_port}/debra/highestDonations'
campaign_info_url = f'http://{sissi_host}:{sissi_port}/debra/campaignInfo'
class DonationImageGenerationParameters:
validation_message = ''
validation_value = ''
validated = None
def __init__(self, font_name, font_size, canvas_width, canvas_height, donation_count, r, g, b):
self.font_name = font_name
self.font_size = font_size
self.canvas_width = canvas_width
self.canvas_height = canvas_height
self.donation_count = donation_count
self.color = (r, g, b)
def validate(self):
self.validated = True
if self.font_name not in DonationImageGenerationConstants.allowed_fonts:
self.validated = False
self.validation_message = f'Font must be one of ' + ','.join(DonationImageGenerationConstants.allowed_fonts)
self.validation_value = self.font_name
if self.font_size > DonationImageGenerationConstants.font_range[1] or self.font_size < DonationImageGenerationConstants.font_range[0]:
self.validated = False
self.validation_message = f'Font size must be between {DonationImageGenerationConstants.font_range[0]} and {DonationImageGenerationConstants.font_range[1]}'
self.validation_value = self.font_size
if self.canvas_height > DonationImageGenerationConstants.canvas_height_range[1] or self.canvas_height < DonationImageGenerationConstants.canvas_height_range[0]:
self.validated = False
self.validation_message = f'Canvas height must be between {DonationImageGenerationConstants.canvas_height_range[0]} and {DonationImageGenerationConstants.canvas_height_range[1]}'
self.validation_value = self.canvas_height
if self.canvas_width > DonationImageGenerationConstants.canvas_width_range[1] or self.canvas_width < DonationImageGenerationConstants.canvas_width_range[0]:
self.validated = False
self.validation_message = f'Canvas width must be between {DonationImageGenerationConstants.canvas_width_range[0]} and {DonationImageGenerationConstants.color_range[1]}'
self.validation_value = self.canvas_width
if self.donation_count > DonationImageGenerationConstants.donation_count_range[1] or self.donation_count < DonationImageGenerationConstants.donation_count_range[0]:
self.validated = False
self.validation_message = f'Donation count must be between {DonationImageGenerationConstants.donation_count_range[0]} and {DonationImageGenerationConstants.donation_count_range[1]}'
self.validation_value = self.donation_count
if self.color[0] > DonationImageGenerationConstants.color_range[1] or self.color[0] < DonationImageGenerationConstants.color_range[0]:
self.validated = False
self.validation_message = f'Red must be between {DonationImageGenerationConstants.color_range[0]} and {DonationImageGenerationConstants.color_range[1]} inclusively'
self.validation_value = self.color[0]
if self.color[1] > DonationImageGenerationConstants.color_range[1] or self.color[1] < DonationImageGenerationConstants.color_range[0]:
self.validated = False
self.validation_message = f'Green must be between {DonationImageGenerationConstants.color_range[0]} and {DonationImageGenerationConstants.color_range[1]} inclusively'
self.validation_value = self.color[1]
if self.color[2] > DonationImageGenerationConstants.color_range[1] or self.color[2] < DonationImageGenerationConstants.color_range[0]:
self.validated = False
self.validation_message = f'Blue must be between {DonationImageGenerationConstants.color_range[0]} and {DonationImageGenerationConstants.color_range[1]} inclusively'
self.validation_value = self.color[2]
@app.route('/debra/latestDonations')
def latest_donations():
donation_stats = requests.get(latest_donations_url)
logging.info(f'returning latest donations')
return donation_stats.text
@app.route('/debra/highestDonations')
def highest_donations():
donation_stats = requests.get(highest_donations_url)
logging.info(f'returning highest donations')
return donation_stats.text
@app.route('/debra/campaignInfo')
def campaign_info_route():
donation_stats = requests.get(campaign_info_url)
logging.info(f'returning campaign info')
return donation_stats.text
@app.route('/debra/image/help')
def show_image_generation_help():
def make_param(parameters_obj, name, default, values):
parameters_obj[name] = {
'default': default,
'values': values
}
parameters = {}
make_param(parameters, 'font', DonationImageGenerationConstants.font_default, DonationImageGenerationConstants.allowed_fonts)
make_param(parameters, 'fontSize', DonationImageGenerationConstants.font_size_default, DonationImageGenerationConstants.font_range)
make_param(parameters, 'canvasWidth', DonationImageGenerationConstants.canvas_width_default, DonationImageGenerationConstants.canvas_width_range)
make_param(parameters, 'canvasHeight', DonationImageGenerationConstants.canvas_height_default, DonationImageGenerationConstants.canvas_height_range)
make_param(parameters, 'donationCount', DonationImageGenerationConstants.donation_count_default, DonationImageGenerationConstants.donation_count_range)
make_param(parameters, 'r', DonationImageGenerationConstants.r_default, DonationImageGenerationConstants.color_range)
make_param(parameters, 'g', DonationImageGenerationConstants.g_default, DonationImageGenerationConstants.color_range)
make_param(parameters, 'b', DonationImageGenerationConstants.b_default, DonationImageGenerationConstants.color_range)
info_object = {
'parameters': parameters
}
return json.dumps(info_object)
@app.route('/debra/image/info')
def total_donations_image():
campaign_info = json.loads(requests.get(campaign_info_url).text)
logging.info(f'rendering campaign info')
parameters = parse_image_parameters()
if not parameters.validated:
return parameters.validation_message, 400
img = Image.new('RGBA', (parameters.canvas_width, parameters.canvas_height), (255, 0, 0, 0))
d1 = ImageDraw.Draw(img)
font = ImageFont.truetype(f'{parameters.font_name}.ttf', parameters.font_size)
d1.text((0, 0), f"{campaign_info['collected']}/{campaign_info['target']}", fill=parameters.color, font=font)
return serve_pil_image(img)
@app.route('/debra/image/latestDonations')
def latest_donation_image():
donation_stats = json.loads(requests.get(latest_donations_url).text)
logging.info(f'rendering latest donations')
parameters = parse_image_parameters()
if not parameters.validated:
return parameters.validation_message, 400
return rendering_donation_image(donation_stats, parameters)
@app.route('/debra/image/highestDonations')
def highest_donation_image():
donation_stats = json.loads(requests.get(highest_donations_url).text)
logging.info(f'rendering highest donations')
parameters = parse_image_parameters()
if not parameters.validated:
return parameters.validation_message, 400
return rendering_donation_image(donation_stats, parameters)
@app.route('/debra/image/highestDonations/html')
def highest_donations_image_html_wrapper():
refresh_interval = int(request.args.get('refreshInterval', 30, type=int))
random_bit = str(uuid.uuid4())
parameters_query = request.query_string.decode()
return render_template('image_refresh_wrapper.html', imagePath=f'/debra/image/highestDonations?{parameters_query}&{random_bit}', refreshInterval=refresh_interval)
@app.route('/debra/image/latestDonations/html')
def latest_donations_image_html_wrapper():
refresh_interval = int(request.args.get('refreshInterval', 30, type=int))
random_bit = str(uuid.uuid4())
parameters_query = request.query_string.decode()
return render_template('image_refresh_wrapper.html', imagePath=f'/debra/image/latestDonations?{parameters_query}&{random_bit}', refreshInterval=refresh_interval)
@app.route('/debra/image/info/html')
def total_donations_image_html_wrapper():
refresh_interval = int(request.args.get('refreshInterval', 30, type=int))
random_bit = str(uuid.uuid4())
parameters_query = request.query_string.decode()
return render_template('image_refresh_wrapper.html', imagePath=f'/debra/image/info?{parameters_query}&{random_bit}', refreshInterval=refresh_interval)
def rendering_donation_image(donation_stats, parameters):
img = Image.new('RGBA', (parameters.canvas_width, parameters.canvas_height), (255, 0, 0, 0))
d1 = ImageDraw.Draw(img)
font = ImageFont.truetype(f'{parameters.font_name}.ttf', parameters.font_size)
donations_to_draw = donation_stats['donations'][:parameters.donation_count]
height = parameters.font_size
it = 0
for donation in donations_to_draw:
name = donation['firstName'] if not donation['anonymous'] else 'anonym'
d1.text((0, height * it), f"{donation['donationAmount']}€ von {name}", fill=parameters.color, font=font)
it += 1
return serve_pil_image(img)
def parse_image_parameters() -> DonationImageGenerationParameters:
font = request.args.get('font', DonationImageGenerationConstants.font_default, type=str)
font_size = int(request.args.get('fontSize', DonationImageGenerationConstants.font_size_default, type=int))
canvas_width = int(request.args.get('canvasWidth', DonationImageGenerationConstants.canvas_width_default, type=int))
canvas_height = int(request.args.get('canvasHeight', DonationImageGenerationConstants.canvas_height_default, type=int))
donation_count = int(request.args.get('donationCount', DonationImageGenerationConstants.donation_count_default, type=int))
r = int(request.args.get('r', DonationImageGenerationConstants.r_default, type=int))
g = int(request.args.get('g', DonationImageGenerationConstants.g_default, type=int))
b = int(request.args.get('b', DonationImageGenerationConstants.b_default, type=int))
parameters = DonationImageGenerationParameters(font, font_size, canvas_width, canvas_height, donation_count, r, g, b)
parameters.validate()
return parameters
class DonationImageGenerationConstants:
allowed_fonts = ['Andale_Mono', 'Courier_New', 'Impact', 'Trebuchet_MS_Italic',
'Arial', 'Courier_New_Bold', 'Times_New_Roman', 'Verdana',
'Arial_Black', 'Courier_New_Bold_Italic', 'Times_New_Roman_Bold', 'Verdana_Bold',
'Arial_Bold', 'Courier_New_Italic', 'Times_New_Roman_Bold_Italic', 'Verdana_Bold_Italic',
'Arial_Bold_Italic', 'Georgia', 'Times_New_Roman_Italic', 'Verdana_Italic',
'Arial_Italic', 'Georgia_Bold', 'Trebuchet_MS',
'Comic_Sans_MS', 'Georgia_Bold_Italic', 'Trebuchet_MS_Bold',
'Comic_Sans_MS_Bold', 'Georgia_Italic', 'Trebuchet_MS_Bold_Italic']
font_range = (2, 150)
canvas_width_range = (1, 2500)
canvas_height_range = (1, 2500)
donation_count_range = (1, 25)
color_range = (0, 255)
font_default = 'Arial'
font_size_default = 40
canvas_width_default = 1024
canvas_height_default = 300
donation_count_default = 5
r_default = 0
g_default = 0
b_default = 0

View File

@@ -0,0 +1,19 @@
from __main__ import app
from PIL import Image, ImageDraw, ImageFont
from flask import request
from utils import serve_pil_image
@app.route('/memes/doge/orangeSun/')
def image_gen():
text = request.args.get('text')
with Image.open('res/img/semf_template.jpg') as im:
d1 = ImageDraw.Draw(im)
text_box_size = (300, 240)
W, H = text_box_size
font = ImageFont.truetype(f'Impact.ttf', 60)
_, _, w, h = d1.textbbox((0, 0), text, font=font)
d1.text(((W-w)/2 + 320, (H-h)/2 + 120), text, font=font, fill=(255, 255, 255))
return serve_pil_image(im)

View File

@@ -0,0 +1,23 @@
import logging
import os
from flask import Flask
FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
logging.basicConfig(encoding='utf-8', level=logging.INFO, format=FORMAT)
template_dir = os.path.abspath('res/templates')
app = Flask(__name__, template_folder=template_dir)
# loads the api end points
import debra
import image_gen
@app.route('/')
def hello():
return 'Hello, World?'
if __name__ == "__main__":
from waitress import serve
serve(app, host="0.0.0.0", port=8080)

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,7 @@
<meta http-equiv="refresh" content="{{ refreshInterval }}">
<html>
<head></head>
<body>
<img src="{{ imagePath }}">
</body>
</html>

View File

@@ -0,0 +1,17 @@
from io import BytesIO
from flask import send_file
def serve_pil_image(pil_img):
img_io = BytesIO()
pil_img.save(img_io, 'PNG')
img_io.seek(0)
return send_file(img_io, mimetype='image/png')
class ValidationException(Exception):
def __init__(self, provided_value, message):
self.provided_value = provided_value
self.message = message
super().__init__(f'{self.message}: provided value: {provided_value}')

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.sissi</groupId> <groupId>dev.sheldan.sissi</groupId>
<artifactId>sissi</artifactId> <artifactId>sissi</artifactId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.sissi.templates</groupId> <groupId>dev.sheldan.sissi.templates</groupId>
<artifactId>customization-templates</artifactId> <artifactId>customization-templates</artifactId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>sissi-templates</artifactId> <artifactId>sissi-templates</artifactId>
<groupId>dev.sheldan.sissi.templates</groupId> <groupId>dev.sheldan.sissi.templates</groupId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>module-templates</artifactId> <artifactId>module-templates</artifactId>
<groupId>dev.sheldan.sissi.templates</groupId> <groupId>dev.sheldan.sissi.templates</groupId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -0,0 +1,11 @@
{
<#setting locale="de_DE">
"additionalMessage": "<@safe_include "debraInfoButton_text"/>",
"buttons": [
{
"label": "<@safe_include "debraInfoButton_button_label"/>",
"id": "${buttonId}",
"buttonStyle": "success"
}
]
}

View File

@@ -0,0 +1,6 @@
{
"additionalMessage": "<@safe_include "debraInfoButton_response_text"/>",
"messageConfig": {
"ephemeral": true
}
}

View File

@@ -0,0 +1,4 @@
{
<#setting locale="de_DE">
"additionalMessage": "<@safe_include "debraInfoMessage_text"/>"
}

View File

@@ -0,0 +1,7 @@
{
<#setting locale="de_DE">
"additionalMessage": "<@safe_include "debraInfoMessage_response_text"/>",
"messageConfig": {
"ephemeral": true
}
}

View File

@@ -25,7 +25,7 @@
"buttons": [ "buttons": [
{ {
"label": "<@safe_include "debra_donation_notification_link_button_label"/>", "label": "<@safe_include "debra_donation_notification_link_button_label"/>",
"url": "http://tiny.cc/schmetterling2022", "url": "http://tiny.cc/schmetterling2023",
"buttonStyle": "link", "buttonStyle": "link",
"metaConfig": { "metaConfig": {
"persistCallback": false "persistCallback": false

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>module-templates</artifactId> <artifactId>module-templates</artifactId>
<groupId>dev.sheldan.sissi.templates</groupId> <groupId>dev.sheldan.sissi.templates</groupId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
"embeds": [ "embeds": [
{ {
<#include "abstracto_color">, <#include "abstracto_color">,
<#assign time><@format_instant_date_time instant=meetupTime/></#assign> <#assign time><@format_instant_long_date_time instant=meetupTime/></#assign>
<#assign topicText>${topic?json_string}</#assign> <#assign topicText>${topic?json_string}</#assign>
"description": "<#include "meetup_cancel_notification_description">" "description": "<#include "meetup_cancel_notification_description">"
} }

View File

@@ -6,7 +6,7 @@
"title": { "title": {
"title": "${topic?json_string}" "title": "${topic?json_string}"
}, },
"description": "<@format_instant_date_time instant=meetupTime/> "description": "<@format_instant_long_date_time instant=meetupTime/>
${description?json_string}" ${description?json_string}"
} }
], ],

View File

@@ -4,8 +4,8 @@
{ {
<#include "abstracto_color">, <#include "abstracto_color">,
<#assign topicText=meetupTopic> <#assign topicText=meetupTopic>
<#assign oldTime><@format_instant_date_time instant=oldDate/></#assign> <#assign oldTime><@format_instant_long_date_time instant=oldDate/></#assign>
<#assign newTime><@format_instant_date_time instant=newDate/></#assign> <#assign newTime><@format_instant_long_date_time instant=newDate/></#assign>
<#assign messageLink=meetupMessage.jumpUrl> <#assign messageLink=meetupMessage.jumpUrl>
"description": "<@safe_include "changeMeetupTime_notification_text"/>" "description": "<@safe_include "changeMeetupTime_notification_text"/>"
} }

View File

@@ -6,7 +6,7 @@
"title": { "title": {
"title": "${topic?json_string}" "title": "${topic?json_string}"
}, },
"description": "<@format_instant_date_time instant=meetupTime/> "description": "<@format_instant_long_date_time instant=meetupTime/>
${description?json_string}" ${description?json_string}"
<#if location?? && location != "%22%22">, <#if location?? && location != "%22%22">,
"fields": [ "fields": [

View File

@@ -3,7 +3,7 @@
"embeds": [ "embeds": [
{ {
<#include "abstracto_color">, <#include "abstracto_color">,
"description": "<#list meetups as meetup><#assign meetup=meetup><#assign topic=meetup.topic><#assign time><@format_instant_date_time instant=meetup.meetupTime/></#assign><#assign timeRelative><@format_instant_relative instant=meetup.meetupTime/></#assign><#assign link=meetup.meetupMessage.jumpUrl><#include "meetup_list_meetup_display"> "description": "<#list meetups as meetup><#assign meetup=meetup><#assign topic=meetup.topic><#assign time><@format_instant_long_date_time instant=meetup.meetupTime/></#assign><#assign timeRelative><@format_instant_relative instant=meetup.meetupTime/></#assign><#assign link=meetup.meetupMessage.jumpUrl><#include "meetup_list_meetup_display">
<#else><#include "meetup_list_no_meetups"></#list>" <#else><#include "meetup_list_no_meetups"></#list>"
} }
] ]

View File

@@ -8,7 +8,7 @@
"title": { "title": {
"title": "${topic?json_string} - <@safe_include "meetup_message_id_display"/>" "title": "${topic?json_string} - <@safe_include "meetup_message_id_display"/>"
}, },
<#assign time><@format_instant_date_time instant=meetupTime/></#assign> <#assign time><@format_instant_long_date_time instant=meetupTime/></#assign>
<#assign timeRelative><@format_instant_relative instant=meetupTime/></#assign> <#assign timeRelative><@format_instant_relative instant=meetupTime/></#assign>
<#assign organizerText>${organizer.memberMention}</#assign> <#assign organizerText>${organizer.memberMention}</#assign>
<#assign meetupId=meetupId/> <#assign meetupId=meetupId/>

View File

@@ -3,7 +3,7 @@
"embeds": [ "embeds": [
{ {
<#include "abstracto_color">, <#include "abstracto_color">,
<#assign time><@format_instant_date_time instant=meetupTime/></#assign> <#assign time><@format_instant_long_date_time instant=meetupTime/></#assign>
<#assign topicText>${topic?json_string}</#assign> <#assign topicText>${topic?json_string}</#assign>
"description": "<#include "meetup_reminder_notification_description">" "description": "<#include "meetup_reminder_notification_description">"
} }

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.sissi.templates</groupId> <groupId>dev.sheldan.sissi.templates</groupId>
<artifactId>sissi-templates</artifactId> <artifactId>sissi-templates</artifactId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.sissi.templates</groupId> <groupId>dev.sheldan.sissi.templates</groupId>
<artifactId>module-templates</artifactId> <artifactId>module-templates</artifactId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>module-templates</artifactId> <artifactId>module-templates</artifactId>
<groupId>dev.sheldan.sissi.templates</groupId> <groupId>dev.sheldan.sissi.templates</groupId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -9,7 +9,7 @@
"title": "${title}", "title": "${title}",
"url": "${url}" "url": "${url}"
}, },
"description": "${url}<#if description?has_content>\n${description}</#if>", "description": "${url?json_string}<#if description?has_content>\n${description?json_string}</#if>",
"footer": { "footer": {
"text": "${category}" "text": "${category}"
} }

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.sissi.templates</groupId> <groupId>dev.sheldan.sissi.templates</groupId>
<artifactId>templates</artifactId> <artifactId>templates</artifactId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.sissi.templates</groupId> <groupId>dev.sheldan.sissi.templates</groupId>
<artifactId>template-overrides</artifactId> <artifactId>template-overrides</artifactId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.sissi.templates</groupId> <groupId>dev.sheldan.sissi.templates</groupId>
<artifactId>template-overrides</artifactId> <artifactId>template-overrides</artifactId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.sissi.templates</groupId> <groupId>dev.sheldan.sissi.templates</groupId>
<artifactId>template-overrides</artifactId> <artifactId>template-overrides</artifactId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>sissi-templates</artifactId> <artifactId>sissi-templates</artifactId>
<groupId>dev.sheldan.sissi.templates</groupId> <groupId>dev.sheldan.sissi.templates</groupId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.sissi.templates.translations</groupId> <groupId>dev.sheldan.sissi.templates.translations</groupId>
<artifactId>customization-translations</artifactId> <artifactId>customization-translations</artifactId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>sissi-translations</artifactId> <artifactId>sissi-translations</artifactId>
<groupId>dev.sheldan.sissi.templates.translations</groupId> <groupId>dev.sheldan.sissi.templates.translations</groupId>
<version>1.4.21</version> <version>1.4.28</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

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