mirror of
https://github.com/Sheldan/Sissi.git
synced 2026-01-02 15:56:31 +00:00
Compare commits
176 Commits
2024040513
...
release-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d33ce3da6c | ||
|
|
16553e0299 | ||
|
|
dd02b07ff6 | ||
|
|
43e372e07a | ||
|
|
ba42a10122 | ||
|
|
28d68b13c7 | ||
|
|
ea0f1fde15 | ||
|
|
4904980935 | ||
|
|
222e48021f | ||
|
|
c39996f117 | ||
|
|
f90defbc64 | ||
|
|
48c06cf370 | ||
|
|
14d90722b7 | ||
|
|
6c48dd790f | ||
|
|
9e1f7f0263 | ||
|
|
15ec88c03f | ||
|
|
aeb89533e2 | ||
|
|
483d6fde66 | ||
|
|
f95beddffa | ||
|
|
7faafc9ad1 | ||
|
|
1de0cae589 | ||
|
|
dfbf15ad61 | ||
|
|
db271cd448 | ||
|
|
8f289baadd | ||
|
|
2ee5578f4e | ||
|
|
b458d8d3a8 | ||
|
|
f8353ca19b | ||
|
|
023b22b2c2 | ||
|
|
9ada2c39a2 | ||
|
|
d61d378a6a | ||
|
|
09af4b516f | ||
|
|
0e50a7b826 | ||
|
|
d4dc118f66 | ||
|
|
be35a84dcf | ||
|
|
5f6df14c24 | ||
|
|
a60cf5d745 | ||
|
|
6e7ae8b36f | ||
|
|
3f22955df2 | ||
|
|
938f9e5cd4 | ||
|
|
45516f2458 | ||
|
|
9d9c8beb88 | ||
|
|
427250e0bc | ||
|
|
35d20be13b | ||
|
|
693bc2cd2c | ||
|
|
c62757590a | ||
|
|
1b2d326655 | ||
|
|
180c2681e0 | ||
|
|
80d0552d65 | ||
|
|
f76f8afef5 | ||
|
|
8bf9fe6c45 | ||
|
|
de8301750a | ||
|
|
555c60caad | ||
|
|
0481deae4a | ||
|
|
edb887f51a | ||
|
|
4dc424b87a | ||
|
|
290e59f8da | ||
|
|
aca7e3449c | ||
|
|
aa1a7344de | ||
|
|
faa85173cc | ||
|
|
2ee2907c72 | ||
|
|
51d9ec2931 | ||
|
|
dc801dc220 | ||
|
|
71aaa31fa1 | ||
|
|
80a56f4426 | ||
|
|
9f3d1a0080 | ||
|
|
ecf30513b1 | ||
|
|
4f9369ce22 | ||
|
|
c0369d6cf3 | ||
|
|
0bd4082f72 | ||
|
|
cda1b2d61c | ||
|
|
e9d2ceb2af | ||
|
|
3c9e8606fa | ||
|
|
f726a4ca95 | ||
|
|
311eb7d3fa | ||
|
|
7c47159508 | ||
|
|
5edba2c037 | ||
|
|
e6b35af78a | ||
|
|
f11f74507d | ||
|
|
9bdc023e99 | ||
|
|
f343a5a280 | ||
|
|
2312892f0a | ||
|
|
d69c4b5b79 | ||
|
|
2ffa0feb3f | ||
|
|
5a3b7216fc | ||
|
|
5676d7291c | ||
|
|
f6452077f0 | ||
|
|
2602d073d3 | ||
|
|
d85ebedfcc | ||
|
|
841bfc19ac | ||
|
|
d02f2d3088 | ||
|
|
c164969afb | ||
|
|
af37454918 | ||
|
|
5e915713e2 | ||
|
|
1f7ffc16e2 | ||
|
|
3734d271f0 | ||
|
|
f219c4ab54 | ||
|
|
2c984cd183 | ||
|
|
d06a1db108 | ||
|
|
6125f39670 | ||
|
|
c020a3a0f2 | ||
|
|
91a0265e6e | ||
|
|
a822c5486f | ||
|
|
fd50050870 | ||
|
|
9a5e6e1df2 | ||
|
|
423bf33402 | ||
|
|
f9b193a95b | ||
|
|
b46c8a1348 | ||
|
|
109a770524 | ||
|
|
3001b14782 | ||
|
|
49932641b3 | ||
|
|
829d6cc136 | ||
|
|
c28a864a47 | ||
|
|
fae50c2914 | ||
|
|
8f80df1484 | ||
|
|
1b5ed0d70d | ||
|
|
098d748b96 | ||
|
|
075f3b3201 | ||
|
|
d5e996e1d0 | ||
|
|
198054ecfe | ||
|
|
efcf93492b | ||
|
|
564e22d948 | ||
|
|
29a1473073 | ||
|
|
208dd8c893 | ||
|
|
752be470e8 | ||
|
|
b9cee83afd | ||
|
|
ed9bf49e19 | ||
|
|
8fe46f6172 | ||
|
|
1bc47d962e | ||
|
|
b9ce6f22a7 | ||
|
|
45b8c3c588 | ||
|
|
ba5f34d667 | ||
|
|
1f5ed1b623 | ||
|
|
170588d638 | ||
|
|
4d69a90d5d | ||
|
|
19ed221329 | ||
|
|
5ba3036e1d | ||
|
|
25a4d47dc0 | ||
|
|
3347fdd8f1 | ||
|
|
47eef33850 | ||
|
|
583a49df5b | ||
|
|
ca938a0164 | ||
|
|
e22f94ff1e | ||
|
|
307c9eac67 | ||
|
|
6002c979d9 | ||
|
|
df49c313a4 | ||
|
|
68bf6b5062 | ||
|
|
29eb743c35 | ||
|
|
03f9b64db2 | ||
|
|
212bc09d90 | ||
|
|
e1f327a687 | ||
|
|
7af0d2db1c | ||
|
|
b4f740fcf6 | ||
|
|
dda7ed7db8 | ||
|
|
af006ee880 | ||
|
|
125febc02a | ||
|
|
13f92247cf | ||
|
|
79ed55d988 | ||
|
|
7bc04a7906 | ||
|
|
89d743987d | ||
|
|
32ddd4e6f0 | ||
|
|
68afc31b2e | ||
|
|
d0ba46c440 | ||
|
|
554d197ca4 | ||
|
|
8826796fcb | ||
|
|
c8ed0e2195 | ||
|
|
25d19bfa26 | ||
|
|
f7e19b580e | ||
|
|
5f6bd0d88e | ||
|
|
a110c54411 | ||
|
|
a4a729dfc2 | ||
|
|
85eee4835f | ||
|
|
cab11140fa | ||
|
|
5854ca2ba7 | ||
|
|
3f613eeddf | ||
|
|
5fda777a62 | ||
|
|
e447eca9dd |
4
.env
4
.env
@@ -1,4 +1,4 @@
|
||||
REGISTRY_PREFIX=harbor.sheldan.dev/sissi/
|
||||
ABSTRACTO_PREFIX=harbor.sheldan.dev/abstracto/
|
||||
VERSION=1.4.51
|
||||
ABSTRACTO_VERSION=1.5.35
|
||||
VERSION=1.5.12
|
||||
ABSTRACTO_VERSION=1.6.14
|
||||
22
.github/workflows/build.yml
vendored
22
.github/workflows/build.yml
vendored
@@ -14,7 +14,7 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@@ -31,3 +31,23 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
user: Sheldan
|
||||
token: ${{ secrets.ABSTRACTO_PAT }}
|
||||
- name: Login to Harbor
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: harbor.sheldan.dev
|
||||
username: ${{ secrets.HARBOR_USERNAME }}
|
||||
password: ${{ secrets.HARBOR_TOKEN }}
|
||||
- name: Load env file
|
||||
id: dotenv
|
||||
uses: falti/dotenv-action@v1.0.4
|
||||
with:
|
||||
path: .env
|
||||
- name: Docker build
|
||||
run: docker compose build
|
||||
env:
|
||||
REGISTRY_PREFIX: ${{ steps.dotenv.outputs.registry_prefix }}
|
||||
VERSION: ${{ steps.dotenv.outputs.version }}
|
||||
- name: Helm package and push
|
||||
working-directory: ./deployment/helm/
|
||||
run: |-
|
||||
helm package sissi
|
||||
|
||||
6
.github/workflows/release_manual.yaml
vendored
6
.github/workflows/release_manual.yaml
vendored
@@ -5,7 +5,7 @@ permissions:
|
||||
contents: write
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
maven-args: "-Dmaven.javadoc.skip=true -s settings.xml -DskipTests"
|
||||
access-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Login to Harbor
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: harbor.sheldan.dev
|
||||
username: ${{ secrets.HARBOR_USERNAME }}
|
||||
@@ -72,7 +72,7 @@ jobs:
|
||||
with:
|
||||
path: .env
|
||||
- name: Build and push Docker containers
|
||||
run: docker-compose build && docker-compose push
|
||||
run: docker compose build && docker compose push
|
||||
env:
|
||||
REGISTRY_PREFIX: ${{ steps.dotenv.outputs.registry_prefix }}
|
||||
VERSION: ${{ steps.dotenv.outputs.version }}
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Sheldan
|
||||
Copyright (c) 2025 Sheldan
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
164
PRIVACY_POLICY.md
Normal file
164
PRIVACY_POLICY.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# Sissi Discord bot privacy policy
|
||||
|
||||
Last updated: 23.02.2025
|
||||
|
||||
## Description
|
||||
|
||||
The bot requires some information to function properly and in a reasonable way. These features heavily depend which features are enabled for which server, and this list just presents ALL of the features available.
|
||||
The detailed list of what information is stored and processed is the following:
|
||||
|
||||
### General
|
||||
* your Discord user ID (in combination with the server ID) is used to uniquely identify you and associate various properties, such as experience, level, opened modmail threads etc
|
||||
* the IDs of the servers this bot is in
|
||||
* the IDs of the channel in the servers this bot is in
|
||||
* the names of channel groups which were given by their creator
|
||||
* the server aliases which were created for commands
|
||||
* the name of emotes which are used in the bot for convenience, if they are customized
|
||||
* towards which channel (identified by ID) certain messages by the bot are posted. e.g. logging, news, starboard
|
||||
* **no message content, username, channel name or role name is stored, except at the places where its mentioned**
|
||||
* most of the stored records have a 'created' and 'updated' timestamp, in order to assist in examining bugs and malfunctions
|
||||
* which commands have which cooldown in which channel group and in which channel group they are disabled
|
||||
* which channel is in which channel group
|
||||
* which role is allowed to execute which command
|
||||
* which features are enabled
|
||||
* which feature modes are enabled
|
||||
* **aliases** created for the commands
|
||||
* **information** necessary to handle components (buttons, select menus). This information is of varying nature and can be user identifiable information
|
||||
* **emotes** which should be used for varying places (assignable roles, particular emotes which are overwriten, such as star board)
|
||||
|
||||
|
||||
### Moderation
|
||||
* **mute reason**, duration, mute date, who muted whom and in which message was the mute executed
|
||||
* the names of filtered invite link servers in order to find out if it would be valid to allow the invite
|
||||
* any configured allowed invite links the server ID and the actually used invite
|
||||
* this is necessary in order to determine the server via its ID and allow other unknown invite links. The invite link is necessary as there is no way to map server ID to actual server
|
||||
* configured profanity regexes
|
||||
* reported profanities, including which message contains the profanity, and the message which was used to report the profanity, and whether it was identified as a true profanity
|
||||
* **the text of notes regarding users**
|
||||
* this is used to enable taking notes about users, and the content is stored directly
|
||||
* meta information regarding warnings
|
||||
* **reason for the warning**
|
||||
* date of the warning
|
||||
* the user who warned a user
|
||||
* whether the warning was decayed and when
|
||||
* the infractions of each user accompanied with **reason** (if available): warns, mutes, bans, kicks
|
||||
|
||||
### Giveaway
|
||||
* the give away information: **description**, provider, manager, target date, winners and participants
|
||||
|
||||
### Embedded messages
|
||||
* embedded message information
|
||||
* this information includes who embedded which message in which channel and is deleted after a few days
|
||||
|
||||
### Emote usage tracking
|
||||
* the name of emotes which are being tracked in the emote usage tracking system for purely convenience reasons
|
||||
* **who** used which emote is **not** tracked
|
||||
* at which day an emote was used how many times
|
||||
* whether the emote was a reaction
|
||||
|
||||
### Reminder
|
||||
* **the message content** in order to provide you with the reminder text
|
||||
* the date it was created, and the date it is due
|
||||
* the id of the message which contained the command
|
||||
* whether you have been reminded
|
||||
* the users who have joined the reminders
|
||||
|
||||
### Modmail
|
||||
* the information that a modmail thread existed (creation, status and close date), and the IDs of the messages that have been sent in both directions
|
||||
|
||||
### News
|
||||
* the ORF integration stores which posts from ORF RSS were already sent.
|
||||
* which ORF RSS feeds were subscribed
|
||||
|
||||
### Polls
|
||||
* the **text** of polls, the creator of polls and who made which decision in polls
|
||||
|
||||
### Starboard (best-of)
|
||||
* the message which was the origin for the starboard post
|
||||
* the message which was the resulting starboard post
|
||||
* the author of the message and the amount of stars
|
||||
* who reacted to a starboard post
|
||||
* this is necessary to provide the information about 'top star giver' and to disallow duplicate starboard reactions
|
||||
|
||||
### Suggestion
|
||||
* **the message content** of the message used to create the suggestion
|
||||
* this was used for the message used to update the status of a suggestion, but this is currently disabled
|
||||
* the author of the suggestion and the message which has been posted in the suggestions channel
|
||||
* every suggestion will be deleted completely from the database a few days after it has reached a final state (rejected, denied, accepted)
|
||||
* whether you voted for a suggestion and which decision you made
|
||||
|
||||
### Leveling system
|
||||
* the amount of messages which were considered for the leveling system
|
||||
* it only considers a message once per minute, so it does not directly translate to your absolute message count
|
||||
* the amount of experience, and the experience level you have
|
||||
* whether experience gain has been disabled for you
|
||||
* the role you received because of the experience system
|
||||
* which roles are configured to be used as experience roles and at which level they are assigned
|
||||
* which roles are used to disable experience gain
|
||||
|
||||
### Entertainment
|
||||
* PressF: for **what** the pressF was initiated by whom and who participated
|
||||
|
||||
### Economy
|
||||
* The amount of credits for each user
|
||||
|
||||
### Assignable roles
|
||||
* the names of assignable role places and assignable role button text, together with the associated emote markdown (if given)
|
||||
* the assigned assignable roles for each member in order to provide the 'unique' assignable role functionality
|
||||
* custom configured conditions to enable a level restriction
|
||||
|
||||
### Weekly items (for Miepscord)
|
||||
* The text of the weekly art posts and the creator of them
|
||||
|
||||
### Sticky roles
|
||||
* The roles a user had when leaving the server to be re-applied when re-joining (opt out possible)
|
||||
|
||||
### Meetups
|
||||
* The meta data of meetups: text, location, creator and the decision of each user interacting with the meetup. This information will be deleted a few days after a meetup has passed/is cancelled.
|
||||
|
||||
### Twitch
|
||||
* The ID/**name** of streamers to follow accompanied with their discord ID
|
||||
* The start/end dates of their streams
|
||||
* The individual sections of streams identified by title and game for updating the message
|
||||
|
||||
### Custom commands
|
||||
* the **names** given to custom commands and the configured **response text**
|
||||
|
||||
## Grafana dashboard
|
||||
|
||||
There is also a [Grafana](https://grafana.com/) dashboard in order to inspect how the bot is operating.
|
||||
The information visible in this dashboard is:
|
||||
|
||||
* message events
|
||||
* Discord gateway ping
|
||||
* starboard reactions
|
||||
* amount of command executions
|
||||
* emotes currently being processed for tracking
|
||||
* embedded messages
|
||||
* invite filter activity
|
||||
* amount of experience which is currently being processed
|
||||
|
||||
All of this information cannot be linked to any user (or any server for that matter, if the bot would be in multiple servers) and is deleted after 15 days.
|
||||
|
||||
|
||||
## How can I decide which information is collected?
|
||||
It is not possible to opt-out of singular sub-services of the bot. Should you decide that your information should not be collected, please cease usage of the bot immediately (leave any guild the bot operates in).
|
||||
|
||||
_Should you decide to no longer utilize the bot, you may request your data to be erased within 30 days as per GDPR if you are a citizen of the EU. You can do this by sending a message to the user "sheldan" on Discord: GDPR Data removal <Username> <UserId>. If your request is incomplete, we cannot acknowledge it and therefore your data will not be removed. In order to identify authentic requests, please contact modmail beforehand by sending a direct message to the bot and stating your intention._
|
||||
|
||||
## Open source content
|
||||
This bot uses the following open source libraries and frameworks:
|
||||
|
||||
* [abstracto](https://github.com/Sheldan/abstracto) is used as a base for this bot, providing most of the functionalities
|
||||
* [JDA](https://github.com/DV8FromTheWorld/JDA/) The Discord API Wrapper used
|
||||
* [Spring boot](https://github.com/spring-projects/spring-boot) is used as a framework to create standalone application in Java with Java EE methods. (including Dependency injection and more)
|
||||
* [Hibernate](https://github.com/hibernate/hibernate-orm) is used as a reference implementation of JPA.
|
||||
* [Freemarker](https://github.com/apache/freemarker) is used as a templating engine. This is used to provide internationalization for user facing text and enable dynamic embed configuration.
|
||||
* [Ehcache](https://github.com/ehcache/ehcache3) is used as a caching implementation.
|
||||
* [Lombok](https://github.com/rzwitserloot/lombok) is used as a framework in order to speed up creation of container classes and builders.
|
||||
* [Quartz](https://github.com/quartz-scheduler/quartz) is used as a scheduling framework in order to provide functionalities which either require a delayed or cronjob behaviour.
|
||||
* [Docker](https://github.com/docker) is used to package the application into a container and [k3s](https://k3s.io/) to orchestrate the containers
|
||||
* [Liquibase](https://github.com/liquibase/liquibase) is used to manage changes to the database
|
||||
* [Prometheus](https://prometheus.io) to scrap and collect the metrics about how the bot is operating
|
||||
|
||||
* [Grafana](https://grafana.com) to visualize metrics of the bot and [Loki](https://grafana.com/oss/loki/) for logging
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.application</groupId>
|
||||
<artifactId>application</artifactId>
|
||||
<version>1.4.52-SNAPSHOT</version>
|
||||
<version>1.5.13-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>executable</artifactId>
|
||||
@@ -55,12 +55,13 @@
|
||||
<artifactId>metrics-impl</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- modules containing commands -->
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.scheduling</groupId>
|
||||
<artifactId>scheduling-impl</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- modules containing commands -->
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>link-embed-impl</artifactId>
|
||||
@@ -165,6 +166,13 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.sissi.application.module</groupId>
|
||||
<artifactId>miepscord</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.sissi.application.module</groupId>
|
||||
<artifactId>rss-news</artifactId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi</groupId>
|
||||
<artifactId>sissi</artifactId>
|
||||
<version>1.4.52-SNAPSHOT</version>
|
||||
<version>1.5.13-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.application.module.custom</groupId>
|
||||
<artifactId>sissi-customizations</artifactId>
|
||||
<version>1.4.52-SNAPSHOT</version>
|
||||
<version>1.5.13-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>image-generation-custom</artifactId>
|
||||
|
||||
@@ -50,18 +50,15 @@ public class OrangeSunDogeCommandAlternative implements CommandAlternative {
|
||||
|
||||
@Override
|
||||
public boolean shouldExecute(UnParsedCommandParameter parameter, Guild guild, Message message) {
|
||||
String contentStripped = message.getContentRaw();
|
||||
String[] parameters = contentStripped.split(" ");
|
||||
return parameters.length == 1 && featureFlagService.isFeatureEnabled(imageGenerationFeatureConfig, guild.getIdLong());
|
||||
return featureFlagService.isFeatureEnabled(imageGenerationFeatureConfig, guild.getIdLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(UnParsedCommandParameter parameter, Message message) {
|
||||
String contentStripped = message.getContentRaw();
|
||||
List<String> parameters = Arrays.asList(contentStripped.split(" "));
|
||||
String inputText = commandRegistry.getCommandName(parameters.get(0), message.getGuild().getIdLong());
|
||||
String inputText = commandRegistry.getCommandName(contentStripped, message.getGuild().getIdLong());
|
||||
File triggeredGifFile = imageGenerationService.getOrangeSunDogeImage(inputText);
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(DOGE_ORANGE_SUN_RESPONSE_TEMPLATE_KEY, new Object());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(DOGE_ORANGE_SUN_RESPONSE_TEMPLATE_KEY, new Object(), message.getGuildIdLong());
|
||||
// template support does not support binary files
|
||||
AttachedFile file = AttachedFile
|
||||
.builder()
|
||||
|
||||
@@ -8,6 +8,8 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@Component
|
||||
public class ImageGenerationService {
|
||||
@@ -20,7 +22,7 @@ public class ImageGenerationService {
|
||||
|
||||
public File getOrangeSunDogeImage(String inputText) {
|
||||
try {
|
||||
return httpService.downloadFileToTempFile(dogeOrangeSunUrl.replace("{1}", inputText));
|
||||
return httpService.downloadFileToTempFile(dogeOrangeSunUrl.replace("{1}", URLEncoder.encode(inputText, StandardCharsets.UTF_8)));
|
||||
} catch (IOException e) {
|
||||
throw new AbstractoRunTimeException(String.format("Failed to download orange doge image for url %s with error %s", inputText, e.getMessage()));
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.application.module.custom</groupId>
|
||||
<artifactId>sissi-customizations</artifactId>
|
||||
<version>1.4.52-SNAPSHOT</version>
|
||||
<version>1.5.13-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ 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.SlashCommandPrivilegeLevels;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.moderation.config.ModerationModuleDefinition;
|
||||
import dev.sheldan.sissi.module.custom.moderation.config.ModerationCustomFeatureDefinition;
|
||||
@@ -72,6 +73,7 @@ public class ModMode extends AbstractConditionableCommand {
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(ModerationCustomSlashCommandNames.MODERATION)
|
||||
.defaultPrivilege(SlashCommandPrivilegeLevels.ADMIN)
|
||||
.commandName(MOD_MODE_COMMAND)
|
||||
.build();
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package dev.sheldan.sissi.module.custom.moderation.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.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.sissi.module.custom.moderation.config.ModerationCustomFeatureDefinition;
|
||||
import dev.sheldan.sissi.module.custom.moderation.service.SelfMuteServiceBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class SelfMute extends AbstractConditionableCommand {
|
||||
|
||||
public static final String DURATION_PARAMETER = "duration";
|
||||
|
||||
@Autowired
|
||||
private SelfMuteServiceBean selfMuteServiceBean;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
Duration muteDuration = (Duration) parameters.get(0);
|
||||
return selfMuteServiceBean.selfMuteMember(commandContext.getAuthor(), muteDuration)
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter durationParameter = Parameter
|
||||
.builder()
|
||||
.name(DURATION_PARAMETER)
|
||||
.type(Duration.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(durationParameter);
|
||||
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name("selfMute")
|
||||
.async(true)
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return ModerationCustomFeatureDefinition.MODERATION_CUSTOM;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package dev.sheldan.sissi.module.custom.moderation.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.service.MemberService;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class SelfMuteServiceBean {
|
||||
|
||||
@Autowired
|
||||
private MemberService memberService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
private static final String SELF_MUTE_REASON_TEMPLATE = "self_mute_reason";
|
||||
|
||||
public CompletableFuture<Void> selfMuteMember(Member member, Duration duration) {
|
||||
String reason = templateService.renderSimpleTemplate(SELF_MUTE_REASON_TEMPLATE, member.getGuild().getIdLong());
|
||||
log.info("Self muting user {} in server {}.", member.getIdLong(), member.getGuild().getIdLong());
|
||||
return memberService.timeoutUser(member, duration, reason);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="seedData/data.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<property name="moderationCustomFeature" value="(SELECT id FROM feature WHERE key = 'moderationCustom')"/>
|
||||
<property name="utilityModule" value="(SELECT id FROM module WHERE name = 'utility')"/>
|
||||
<changeSet author="Sheldan" id="moderationCustom_selfmute-commands">
|
||||
<insert tableName="command">
|
||||
<column name="name" value="selfMute"/>
|
||||
<column name="module_id" valueComputed="${utilityModule}"/>
|
||||
<column name="feature_id" valueComputed="${moderationCustomFeature}"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="command.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -5,4 +5,5 @@
|
||||
<include file="1.1.0/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.2.1/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.4.45/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.5.9/collection.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>application</artifactId>
|
||||
<groupId>dev.sheldan.sissi.application</groupId>
|
||||
<version>1.4.52-SNAPSHOT</version>
|
||||
<version>1.5.13-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.application</groupId>
|
||||
<artifactId>sissi-modules</artifactId>
|
||||
<version>1.4.52-SNAPSHOT</version>
|
||||
<version>1.5.13-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ 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.SlashCommandPrivilegeLevels;
|
||||
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;
|
||||
@@ -58,6 +59,7 @@ public class DebraInfoButton extends AbstractConditionableCommand {
|
||||
.enabled(true)
|
||||
.rootCommandName(DebraSlashCommandNames.DEBRA_INTERNAL)
|
||||
.commandName("debrainfobutton")
|
||||
.defaultPrivilege(SlashCommandPrivilegeLevels.ADMIN)
|
||||
.build();
|
||||
|
||||
Parameter targetChannelParameter = Parameter
|
||||
|
||||
@@ -124,7 +124,7 @@ public class Donations extends AbstractConditionableCommand {
|
||||
} else {
|
||||
donationModel.setDonations(new ArrayList<>());
|
||||
}
|
||||
return templateService.renderEmbedTemplate(DONATIONS_RESPONSE_TEMPLATE_KEY, donationModel);
|
||||
return templateService.renderEmbedTemplate(DONATIONS_RESPONSE_TEMPLATE_KEY, donationModel, serverId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -182,7 +182,7 @@ public class DonationService {
|
||||
.donation(donation)
|
||||
.totalDonationAmount(donationInfoModel.getTotalAmount())
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(DEBRA_DONATION_NOTIFICATION_TEMPLATE_KEY, model);
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(DEBRA_DONATION_NOTIFICATION_TEMPLATE_KEY, model, targetServerId);
|
||||
List<CompletableFuture<Message>> firstMessage = postTargetService.sendEmbedInPostTarget(messageToSend, DebraPostTarget.DEBRA_DONATION_NOTIFICATION, targetServerId);
|
||||
List<CompletableFuture<Message>> secondMessage = postTargetService.sendEmbedInPostTarget(messageToSend, DebraPostTarget.DEBRA_DONATION_NOTIFICATION2, targetServerId);
|
||||
firstMessage.addAll(secondMessage);
|
||||
|
||||
@@ -5,7 +5,7 @@ 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-gg-austria-fuer-debra-2023?details=1&num=%s&ort=0
|
||||
sissi.debra.donationAPIUrl=https://www.altruja.de/api/page/discord-schmetterlingsaktion-2024?details=1&num=%s&ort=0
|
||||
|
||||
abstracto.systemConfigs.debraDonationNotificationDelayMillis.name=debraDonationNotificationDelayMillis
|
||||
abstracto.systemConfigs.debraDonationNotificationDelayMillis.longValue=60000
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.application</groupId>
|
||||
<artifactId>sissi-modules</artifactId>
|
||||
<version>1.4.52-SNAPSHOT</version>
|
||||
<version>1.5.13-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ 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.SlashCommandPrivilegeLevels;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.sissi.module.meetup.config.MeetupFeatureDefinition;
|
||||
@@ -88,6 +89,7 @@ public class CancelMeetup extends AbstractConditionableCommand {
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(MeetupSlashCommandNames.MEETUP)
|
||||
.defaultPrivilege(SlashCommandPrivilegeLevels.ADMIN)
|
||||
.commandName("cancel")
|
||||
.build();
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ 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.SlashCommandPrivilegeLevels;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.sissi.module.meetup.config.MeetupFeatureDefinition;
|
||||
import dev.sheldan.sissi.module.meetup.config.MeetupSlashCommandNames;
|
||||
@@ -131,6 +132,7 @@ public class ChangeMeetup extends AbstractConditionableCommand {
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(MeetupSlashCommandNames.MEETUP)
|
||||
.defaultPrivilege(SlashCommandPrivilegeLevels.ADMIN)
|
||||
.commandName("changeMeetup")
|
||||
.build();
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.ComponentService;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
@@ -150,6 +151,7 @@ public class ChangeMeetupTime extends AbstractConditionableCommand {
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(MeetupSlashCommandNames.MEETUP)
|
||||
.defaultPrivilege(SlashCommandPrivilegeLevels.ADMIN)
|
||||
.commandName("changeTime")
|
||||
.build();
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.interaction.ComponentService;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
@@ -165,6 +166,7 @@ public class CreateMeetup extends AbstractConditionableCommand {
|
||||
Parameter topicParameter = Parameter
|
||||
.builder()
|
||||
.templated(true)
|
||||
.validators(Arrays.asList(MaxStringLengthValidator.max(256)))
|
||||
.name(TOPIC_PARAMETER)
|
||||
.type(String.class)
|
||||
.build();
|
||||
@@ -173,6 +175,7 @@ public class CreateMeetup extends AbstractConditionableCommand {
|
||||
.builder()
|
||||
.templated(true)
|
||||
.name(DESCRIPTION_PARAMETER)
|
||||
.validators(Arrays.asList(MaxStringLengthValidator.max(2048)))
|
||||
.remainder(true)
|
||||
.optional(true)
|
||||
.type(String.class)
|
||||
@@ -183,6 +186,7 @@ public class CreateMeetup extends AbstractConditionableCommand {
|
||||
.templated(true)
|
||||
.name(LOCATION_PARAMETER)
|
||||
.remainder(true)
|
||||
.validators(Arrays.asList(MaxStringLengthValidator.max(100)))
|
||||
.optional(true)
|
||||
.slashCommandOnly(true)
|
||||
.type(String.class)
|
||||
@@ -198,6 +202,7 @@ public class CreateMeetup extends AbstractConditionableCommand {
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(MeetupSlashCommandNames.MEETUP)
|
||||
.defaultPrivilege(SlashCommandPrivilegeLevels.ADMIN)
|
||||
.commandName("create")
|
||||
.build();
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ 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.SlashCommandPrivilegeLevels;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.sissi.module.meetup.config.MeetupFeatureDefinition;
|
||||
import dev.sheldan.sissi.module.meetup.config.MeetupSlashCommandNames;
|
||||
@@ -22,6 +23,7 @@ import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEve
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -48,19 +50,6 @@ public class NotifyMeetupParticipants extends AbstractConditionableCommand {
|
||||
private static final String NOTIFY_MEETUP_PARTICIPANTS_COMMAND = "notifyMeetupParticipants";
|
||||
private static final String NOTIFY_MEETUP_PARTICIPANTS_RESPONSE = "notifyMeetupParticipants_response";
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
Long meetupId = (Long) parameters.get(0);
|
||||
Meetup meetup = meetupManagementServiceBean.getMeetup(meetupId, commandContext.getGuild().getIdLong());
|
||||
if(!meetup.getOrganizer().getUserReference().getId().equals(commandContext.getAuthor().getIdLong())) {
|
||||
throw new NotMeetupOrganizerException();
|
||||
}
|
||||
String notificationMessage = (String) parameters.get(1);
|
||||
return meetupServiceBean.notifyMeetupParticipants(meetup, notificationMessage, null)
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
Long meetupId = slashCommandParameterService.getCommandOption(MEETUP_ID_PARAMETER, event, Integer.class).longValue();
|
||||
@@ -68,12 +57,15 @@ public class NotifyMeetupParticipants extends AbstractConditionableCommand {
|
||||
if(!meetup.getOrganizer().getUserReference().getId().equals(event.getMember().getIdLong())) {
|
||||
throw new NotMeetupOrganizerException();
|
||||
}
|
||||
MeetupDecision toNotify = null;
|
||||
if(slashCommandParameterService.hasCommandOption(NOTIFICATION_MEETUP_DECISION, event)) {
|
||||
toNotify = MeetupDecision.valueOf(slashCommandParameterService.getCommandOption(NOTIFICATION_MEETUP_DECISION, event, String.class));
|
||||
List<MeetupDecision> decisionsToNotify = new ArrayList<>();
|
||||
for (int i = 0; i < MeetupDecision.values().length; i++) {
|
||||
if(slashCommandParameterService.hasCommandOption(NOTIFICATION_MEETUP_DECISION + "_" + i, event)) {
|
||||
String choice = slashCommandParameterService.getCommandOption(NOTIFICATION_MEETUP_DECISION + "_" + i, event, String.class);
|
||||
decisionsToNotify.add(MeetupDecision.valueOf(choice));
|
||||
}
|
||||
}
|
||||
String notificationMessage = slashCommandParameterService.getCommandOption(NOTIFICATION_MESSAGE_PARAMETER, event, String.class);
|
||||
return meetupServiceBean.notifyMeetupParticipants(meetup, notificationMessage, toNotify)
|
||||
return meetupServiceBean.notifyMeetupParticipants(meetup, notificationMessage, decisionsToNotify)
|
||||
.thenCompose(unused -> interactionService.replyEmbed(NOTIFY_MEETUP_PARTICIPANTS_RESPONSE, event))
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
@@ -105,6 +97,8 @@ public class NotifyMeetupParticipants extends AbstractConditionableCommand {
|
||||
.templated(true)
|
||||
.name(NOTIFICATION_MEETUP_DECISION)
|
||||
.type(String.class)
|
||||
.listSize(MeetupDecision.values().length)
|
||||
.isListParam(true)
|
||||
.optional(true)
|
||||
.choices(meetupDecisions)
|
||||
.slashCommandOnly(true)
|
||||
@@ -120,6 +114,7 @@ public class NotifyMeetupParticipants extends AbstractConditionableCommand {
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(MeetupSlashCommandNames.MEETUP)
|
||||
.defaultPrivilege(SlashCommandPrivilegeLevels.ADMIN)
|
||||
.commandName("notify")
|
||||
.build();
|
||||
|
||||
@@ -129,6 +124,7 @@ public class NotifyMeetupParticipants extends AbstractConditionableCommand {
|
||||
.templated(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.async(true)
|
||||
.slashCommandOnly(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
|
||||
@@ -115,7 +115,7 @@ public class MeetupConfirmationListener implements ButtonClickedListener {
|
||||
messageModel.setCancelled(false);
|
||||
Long meetupId = payload.getMeetupId();
|
||||
Long serverId = payload.getGuildId();
|
||||
MessageToSend messageToSend = meetupServiceBean.getMeetupMessage(messageModel);
|
||||
MessageToSend messageToSend = meetupServiceBean.getMeetupMessage(messageModel, model.getServerId());
|
||||
List<CompletableFuture<Message>> messageFutures = channelService.sendMessageToSendToChannel(messageToSend, model.getEvent().getMessageChannel());
|
||||
FutureUtils.toSingleFutureGeneric(messageFutures).thenAccept(unused -> {
|
||||
messageService.deleteMessage(model.getEvent().getMessage());
|
||||
|
||||
@@ -59,8 +59,8 @@ public class MeetupDecisionListener implements ButtonClickedListener {
|
||||
}
|
||||
MeetupMessageModel meetupMessageModel = meetupServiceBean.getMeetupMessageModel(meetup);
|
||||
addParticipationToModel(meetupMessageModel, userInAServer, payload.getMeetupDecision());
|
||||
MessageToSend messageToSend = meetupServiceBean.getMeetupMessage(meetupMessageModel);
|
||||
channelService.editEmbedMessageInAChannel(messageToSend.getEmbeds().get(0), model.getEvent().getChannel(), meetup.getMessageId())
|
||||
MessageToSend messageToSend = meetupServiceBean.getMeetupMessage(meetupMessageModel, model.getServerId());
|
||||
channelService.editMessageInAChannelFuture(messageToSend, model.getEvent().getChannel(), meetup.getMessageId())
|
||||
.thenAccept(message -> log.info("Updated message of meetup {} in channel {} in server {}.", meetup.getId().getId(), meetup.getMeetupChannel().getId(), meetup.getServer().getId()))
|
||||
.exceptionally(throwable -> {
|
||||
log.info("Failed to update message of meetup {} in channel {} in server {}.", meetup.getId().getId(), meetup.getMeetupChannel().getId(), meetup.getServer().getId(), throwable);
|
||||
|
||||
@@ -206,8 +206,8 @@ public class MeetupServiceBean {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public MessageToSend getMeetupMessage(MeetupMessageModel model) {
|
||||
return templateService.renderEmbedTemplate(MEETUP_DISPLAY_TEMPLATE, model);
|
||||
public MessageToSend getMeetupMessage(MeetupMessageModel model, Long serverId) {
|
||||
return templateService.renderEmbedTemplate(MEETUP_DISPLAY_TEMPLATE, model, serverId);
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> cancelMeetup(Meetup meetup) {
|
||||
@@ -221,7 +221,7 @@ public class MeetupServiceBean {
|
||||
.map(meetupComponent -> meetupComponent.getId().getComponentId())
|
||||
.collect(Collectors.toList());
|
||||
model.setCancelled(true);
|
||||
MessageToSend meetupMessage = getMeetupMessage(model);
|
||||
MessageToSend meetupMessage = getMeetupMessage(model, serverId);
|
||||
return messageService.editMessageInChannel(channel, meetupMessage, meetup.getMessageId())
|
||||
.thenAccept(unused -> self.notifyParticipants(meetupId, serverId))
|
||||
.thenAccept(unused -> self.cleanupMeetup(meetupId, serverId, componentPayloads));
|
||||
@@ -231,7 +231,7 @@ public class MeetupServiceBean {
|
||||
public void notifyParticipants(Long meetupId, Long serverId) {
|
||||
Meetup meetup = meetupManagementServiceBean.getMeetup(meetupId, serverId);
|
||||
MeetupMessageModel model = getMeetupMessageModel(meetup);
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(MEETUP_CANCELLATION_TEMPLATE, model);
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(MEETUP_CANCELLATION_TEMPLATE, model, serverId);
|
||||
meetup
|
||||
.getParticipants()
|
||||
.stream()
|
||||
@@ -293,8 +293,8 @@ public class MeetupServiceBean {
|
||||
}
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> notifyMeetupParticipants(Meetup meetup, String message, MeetupDecision toNotify) {
|
||||
List<MeetupDecision> decisionsToBeNotified = toNotify == null ? Arrays.asList(MeetupDecision.MAYBE, MeetupDecision.YES) : Arrays.asList(toNotify);
|
||||
public CompletableFuture<Void> notifyMeetupParticipants(Meetup meetup, String message, List<MeetupDecision> toNotify) {
|
||||
List<MeetupDecision> decisionsToBeNotified = toNotify == null || toNotify.isEmpty() ? Arrays.asList(MeetupDecision.MAYBE, MeetupDecision.YES) : toNotify;
|
||||
List<MemberDisplay> participants = meetup
|
||||
.getParticipants()
|
||||
.stream()
|
||||
@@ -319,7 +319,7 @@ public class MeetupServiceBean {
|
||||
public void remindParticipants(Long meetupId, Long serverId) {
|
||||
Meetup meetup = meetupManagementServiceBean.getMeetup(meetupId, serverId);
|
||||
MeetupMessageModel model = getMeetupMessageModel(meetup);
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(MEETUP_REMINDER_TEMPLATE, model);
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(MEETUP_REMINDER_TEMPLATE, model, serverId);
|
||||
meetup
|
||||
.getParticipants()
|
||||
.stream()
|
||||
@@ -372,7 +372,7 @@ public class MeetupServiceBean {
|
||||
List<Long> userIdsToNotify = participants
|
||||
.stream()
|
||||
.map(meetupParticipator -> meetupParticipator.getParticipator().getUserReference().getId())
|
||||
.collect(Collectors.toList());
|
||||
.toList();
|
||||
|
||||
Long serverId = meetup.getServer().getId();
|
||||
|
||||
@@ -415,7 +415,7 @@ public class MeetupServiceBean {
|
||||
List<Long> userInServerIds = participants
|
||||
.stream()
|
||||
.map(meetupParticipant -> meetupParticipant.getParticipator().getUserInServerId())
|
||||
.collect(Collectors.toList());
|
||||
.toList();
|
||||
meetup
|
||||
.getParticipants().removeIf(meetupParticipant -> userInServerIds.contains(meetupParticipant.getParticipator().getUserInServerId()));
|
||||
MeetupMessageModel meetupMessageModel = getMeetupMessageModel(meetup);
|
||||
@@ -423,7 +423,7 @@ public class MeetupServiceBean {
|
||||
meetupMessageModel.setMaybeParticipants(new ArrayList<>());
|
||||
meetupMessageModel.setNoTimeParticipants(new ArrayList<>());
|
||||
|
||||
MessageToSend updatedMeetupMessage = getMeetupMessage(meetupMessageModel);
|
||||
MessageToSend updatedMeetupMessage = getMeetupMessage(meetupMessageModel, serverId);
|
||||
GuildMessageChannel meetupChannel = channelService.getMessageChannelFromServer(serverId, meetup.getMeetupChannel().getId());
|
||||
return channelService.editMessageInAChannelFuture(updatedMeetupMessage, meetupChannel, meetup.getMessageId())
|
||||
.thenAccept(message -> log.info("Updated message of meetup {} in channel {} in server {}.", meetupId, meetup.getMeetupChannel().getId(), serverId))
|
||||
@@ -457,7 +457,7 @@ public class MeetupServiceBean {
|
||||
Long meetupId = meetup.getId().getId();
|
||||
Long serverId = meetup.getId().getServerId();
|
||||
MeetupMessageModel meetupMessageModel = getMeetupMessageModel(meetup);
|
||||
MessageToSend updatedMeetupMessage = getMeetupMessage(meetupMessageModel);
|
||||
MessageToSend updatedMeetupMessage = getMeetupMessage(meetupMessageModel, serverId);
|
||||
GuildMessageChannel meetupChannel = channelService.getMessageChannelFromServer(serverId, meetup.getMeetupChannel().getId());
|
||||
return channelService.editMessageInAChannelFuture(updatedMeetupMessage, meetupChannel, meetup.getMessageId())
|
||||
.thenAccept(message -> log.info("Updated message of meetup {} in channel {} in server {}.", meetupId, meetup.getMeetupChannel().getId(), serverId))
|
||||
|
||||
43
application/sissi-modules/miepscord/pom.xml
Normal file
43
application/sissi-modules/miepscord/pom.xml
Normal file
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>sissi-modules</artifactId>
|
||||
<groupId>dev.sheldan.sissi.application</groupId>
|
||||
<version>1.5.13-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>dev.sheldan.sissi.application.module</groupId>
|
||||
<artifactId>miepscord</artifactId>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly/liquibase.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.scheduling</groupId>
|
||||
<artifactId>scheduling-int</artifactId>
|
||||
<version>${abstracto.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,18 @@
|
||||
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
|
||||
<id>liquibase</id>
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<outputDirectory>.</outputDirectory>
|
||||
<directory>${project.basedir}/src/main/resources/migrations</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.sissi.module.miepscord;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum MiepscordFeatureDefinition implements FeatureDefinition {
|
||||
WEEKLY_TEXT("weeklyText");
|
||||
|
||||
private String key;
|
||||
|
||||
MiepscordFeatureDefinition(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package dev.sheldan.sissi.module.miepscord;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
||||
@Configuration
|
||||
@PropertySource("classpath:miepscord.properties")
|
||||
public class MiepscordProperties {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.sissi.module.miepscord;
|
||||
|
||||
public class MiepscordSlashCommandNames {
|
||||
public static final String MIEPSCORD_ROOT_NAME = "miepscord";
|
||||
public static final String MIEPSCORD_ROOT_NAME_CONFIG = "miepscordManage";
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package dev.sheldan.sissi.module.miepscord.weeklytext.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.SlashCommandPrivilegeLevels;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.sissi.module.miepscord.MiepscordFeatureDefinition;
|
||||
import dev.sheldan.sissi.module.miepscord.MiepscordSlashCommandNames;
|
||||
import dev.sheldan.sissi.module.miepscord.weeklytext.service.TextItemServiceBean;
|
||||
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 AddTextItem extends AbstractConditionableCommand {
|
||||
|
||||
private static final String ADD_WEEKLY_TEXT_TEXT_PARAMETER = "text";
|
||||
private static final String ADD_WEEKLY_TEXT_COMMAND_NAME = "addWeeklyText";
|
||||
private static final String ADD_WEEKLY_TEXT_RESPONSE = "addWeeklyText_response";
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private TextItemServiceBean textItemServiceBean;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String weeklyText = slashCommandParameterService.getCommandOption(ADD_WEEKLY_TEXT_TEXT_PARAMETER, event, String.class);
|
||||
textItemServiceBean.createTextItem(weeklyText, event.getMember());
|
||||
return interactionService.replyEmbed(ADD_WEEKLY_TEXT_RESPONSE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter textitemTextParameter = Parameter
|
||||
.builder()
|
||||
.templated(true)
|
||||
.name(ADD_WEEKLY_TEXT_TEXT_PARAMETER)
|
||||
.type(String.class)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(textitemTextParameter);
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(MiepscordSlashCommandNames.MIEPSCORD_ROOT_NAME_CONFIG)
|
||||
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
|
||||
.groupName("weeklytexts")
|
||||
.commandName("add")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name(ADD_WEEKLY_TEXT_COMMAND_NAME)
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.slashCommandOnly(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return MiepscordFeatureDefinition.WEEKLY_TEXT;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package dev.sheldan.sissi.module.miepscord.weeklytext.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.SlashCommandPrivilegeLevels;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.sissi.module.miepscord.MiepscordFeatureDefinition;
|
||||
import dev.sheldan.sissi.module.miepscord.MiepscordSlashCommandNames;
|
||||
import dev.sheldan.sissi.module.miepscord.weeklytext.service.TextItemServiceBean;
|
||||
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 RemoveTextItem extends AbstractConditionableCommand {
|
||||
|
||||
private static final String REMOVE_WEEKLY_TEXT_ID_PARAMETER = "id";
|
||||
private static final String REMOVE_WEEKLY_TEXT_COMMAND_NAME = "removeWeeklyText";
|
||||
|
||||
private static final String REMOVE_WEEKLY_TEXT_RESPONSE = "removeWeeklyText_response";
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private TextItemServiceBean textItemServiceBean;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
Long itemId = slashCommandParameterService.getCommandOption(REMOVE_WEEKLY_TEXT_ID_PARAMETER, event, Integer.class).longValue();
|
||||
textItemServiceBean.removeTextItem(itemId);
|
||||
return interactionService.replyEmbed(REMOVE_WEEKLY_TEXT_RESPONSE, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter textItemId = Parameter
|
||||
.builder()
|
||||
.templated(true)
|
||||
.name(REMOVE_WEEKLY_TEXT_ID_PARAMETER)
|
||||
.type(Long.class)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(textItemId);
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(MiepscordSlashCommandNames.MIEPSCORD_ROOT_NAME_CONFIG)
|
||||
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
|
||||
.groupName("weeklytexts")
|
||||
.commandName("remove")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name(REMOVE_WEEKLY_TEXT_COMMAND_NAME)
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.slashCommandOnly(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return MiepscordFeatureDefinition.WEEKLY_TEXT;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package dev.sheldan.sissi.module.miepscord.weeklytext.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.abstracto.core.service.PaginatorService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.sissi.module.miepscord.MiepscordFeatureDefinition;
|
||||
import dev.sheldan.sissi.module.miepscord.MiepscordSlashCommandNames;
|
||||
import dev.sheldan.sissi.module.miepscord.weeklytext.model.database.TextItem;
|
||||
import dev.sheldan.sissi.module.miepscord.weeklytext.model.template.ShowTextItemModel;
|
||||
import dev.sheldan.sissi.module.miepscord.weeklytext.model.template.ShowTextItemsModel;
|
||||
import dev.sheldan.sissi.module.miepscord.weeklytext.service.management.TextItemServiceManagementBean;
|
||||
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.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
|
||||
@Component
|
||||
public class ShowTextItems extends AbstractConditionableCommand {
|
||||
|
||||
private static final String SHOW_WEEKLY_TEXTS_COMMAND_NAME = "showWeeklyTexts";
|
||||
private static final String SHOW_WEEKLY_TEXTS_RESPONSE_TEMPLATE = "showWeeklyTexts";
|
||||
public static final String NO_ITEMS_TEMPLATE_KEY = "showWeeklyTexts_no_items_found";
|
||||
|
||||
private static final String SHOW_WEEKLY_TEXT_SHOW_ALL_PARAMETER = "showAll";
|
||||
|
||||
@Autowired
|
||||
private TextItemServiceManagementBean textItemServiceManagementBean;
|
||||
|
||||
@Autowired
|
||||
private PaginatorService paginatorService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
boolean showAll = false;
|
||||
if(slashCommandParameterService.hasCommandOption(SHOW_WEEKLY_TEXT_SHOW_ALL_PARAMETER, event)) {
|
||||
showAll = slashCommandParameterService.getCommandOption(SHOW_WEEKLY_TEXT_SHOW_ALL_PARAMETER, event, Boolean.class);
|
||||
}
|
||||
List<TextItem> textItems;
|
||||
if(showAll) {
|
||||
textItems = textItemServiceManagementBean.getAllTextItems();
|
||||
} else {
|
||||
textItems = textItemServiceManagementBean.getAllTextItemsWithDoneFlag(false);
|
||||
}
|
||||
textItems.sort(Comparator.comparing(TextItem::getCreated));
|
||||
if(textItems.isEmpty()) {
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(NO_ITEMS_TEMPLATE_KEY, new Object(), event.getGuild().getIdLong());
|
||||
return interactionService.replyMessageToSend(messageToSend, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
|
||||
}
|
||||
List<ShowTextItemModel> convertedTextItems = textItems.stream().map(this::convertTextItem).toList();
|
||||
ShowTextItemsModel items = ShowTextItemsModel
|
||||
.builder()
|
||||
.items(convertedTextItems)
|
||||
.build();
|
||||
return paginatorService.createPaginatorFromTemplate(SHOW_WEEKLY_TEXTS_RESPONSE_TEMPLATE, items, event)
|
||||
.thenApply(unused -> CommandResult.fromIgnored());
|
||||
}
|
||||
|
||||
private ShowTextItemModel convertTextItem(TextItem textItem) {
|
||||
return ShowTextItemModel
|
||||
.builder()
|
||||
.text(textItem.getText())
|
||||
.id(textItem.getId())
|
||||
.done(textItem.getDone())
|
||||
.created(textItem.getCreated())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
Parameter showAllItems = Parameter
|
||||
.builder()
|
||||
.name(SHOW_WEEKLY_TEXT_SHOW_ALL_PARAMETER)
|
||||
.type(Boolean.class)
|
||||
.optional(true)
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(showAllItems);
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(MiepscordSlashCommandNames.MIEPSCORD_ROOT_NAME)
|
||||
.groupName("weeklytexts")
|
||||
.commandName("show")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name(SHOW_WEEKLY_TEXTS_COMMAND_NAME)
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.slashCommandOnly(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.async(true)
|
||||
.parameters(parameters)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return MiepscordFeatureDefinition.WEEKLY_TEXT;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package dev.sheldan.sissi.module.miepscord.weeklytext.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.PostTargetEnum;
|
||||
import dev.sheldan.sissi.module.miepscord.MiepscordFeatureDefinition;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Component
|
||||
public class WeeklyTextFeatureConfig implements FeatureConfig {
|
||||
|
||||
public static final String WEEKLY_TEXT_SERVER_ID = "WEEKLY_TEXT_SERVER_ID";
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return MiepscordFeatureDefinition.WEEKLY_TEXT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PostTargetEnum> getRequiredPostTargets() {
|
||||
return Arrays.asList(WeeklyTextPostTarget.TEXT_ITEM_TARGET);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.sissi.module.miepscord.weeklytext.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.PostTargetEnum;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum WeeklyTextPostTarget implements PostTargetEnum {
|
||||
TEXT_ITEM_TARGET("textItemTarget");
|
||||
|
||||
private String key;
|
||||
|
||||
WeeklyTextPostTarget(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package dev.sheldan.sissi.module.miepscord.weeklytext.job;
|
||||
|
||||
import dev.sheldan.sissi.module.miepscord.weeklytext.service.TextItemServiceBean;
|
||||
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 WeeklyTextJob extends QuartzJobBean {
|
||||
|
||||
@Autowired
|
||||
private TextItemServiceBean textItemServiceBean;
|
||||
|
||||
@Override
|
||||
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
|
||||
try {
|
||||
log.info("Executing text item job.");
|
||||
textItemServiceBean.sendTexItem();
|
||||
} catch (Exception e) {
|
||||
log.error("Text item job failed.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package dev.sheldan.sissi.module.miepscord.weeklytext.model.database;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@Builder
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "text_item")
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
public class TextItem {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id", nullable = false)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "text")
|
||||
private String text;
|
||||
|
||||
@Column(name = "done")
|
||||
private Boolean done;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "creator_id", nullable = false)
|
||||
private AUserInAServer creator;
|
||||
|
||||
@Column(name = "created")
|
||||
private Instant created;
|
||||
|
||||
@Column(name = "updated")
|
||||
private Instant updated;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.sissi.module.miepscord.weeklytext.model.template;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class ShowTextItemModel {
|
||||
private String text;
|
||||
private Boolean done;
|
||||
private Instant created;
|
||||
private Long id;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package dev.sheldan.sissi.module.miepscord.weeklytext.model.template;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class ShowTextItemsModel {
|
||||
private List<ShowTextItemModel> items;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.sissi.module.miepscord.weeklytext.model.template;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class TextItemPostModel {
|
||||
private String text;
|
||||
private Long id;
|
||||
private Instant created;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.sissi.module.miepscord.weeklytext.repository;
|
||||
|
||||
import dev.sheldan.sissi.module.miepscord.weeklytext.model.database.TextItem;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface TextItemRepository extends JpaRepository<TextItem, Long> {
|
||||
List<TextItem> findByDoneFalseOrderByCreated();
|
||||
List<TextItem> findByDone(Boolean done);
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package dev.sheldan.sissi.module.miepscord.weeklytext.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
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.sissi.module.miepscord.weeklytext.config.WeeklyTextPostTarget;
|
||||
import dev.sheldan.sissi.module.miepscord.weeklytext.model.database.TextItem;
|
||||
import dev.sheldan.sissi.module.miepscord.weeklytext.model.template.TextItemPostModel;
|
||||
import dev.sheldan.sissi.module.miepscord.weeklytext.service.management.TextItemServiceManagementBean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static dev.sheldan.sissi.module.miepscord.weeklytext.config.WeeklyTextFeatureConfig.WEEKLY_TEXT_SERVER_ID;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class TextItemServiceBean {
|
||||
|
||||
public static final String WEEKLY_TEXT_ITEM_POST_TEMPLATE = "weekly_text_item_post";
|
||||
@Autowired
|
||||
private TextItemServiceManagementBean textItemServiceManagementBean;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private PostTargetService postTargetService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private TextItemServiceBean self;
|
||||
|
||||
public TextItem createTextItem(String text, Member creator) {
|
||||
log.info("Creating new text item in server {} from user {}.", creator.getGuild().getIdLong(), creator.getIdLong());
|
||||
AUserInAServer creatorUser = userInServerManagementService.loadOrCreateUser(creator);
|
||||
return textItemServiceManagementBean.createTextItem(text, creatorUser);
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> sendTexItem() {
|
||||
Long serverId = Long.parseLong(System.getenv(WEEKLY_TEXT_SERVER_ID));
|
||||
Optional<TextItem> nextTextItemOptional = textItemServiceManagementBean.getNextTextItem();
|
||||
if(nextTextItemOptional.isEmpty()) {
|
||||
log.info("No next text item found.");
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
TextItem textItem = nextTextItemOptional.get();
|
||||
log.info("Sending text item {}.", textItem.getId());
|
||||
Long textItemId = textItem.getId();
|
||||
TextItemPostModel model = TextItemPostModel
|
||||
.builder()
|
||||
.id(textItemId)
|
||||
.created(textItem.getCreated())
|
||||
.text(textItem.getText())
|
||||
.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(WEEKLY_TEXT_ITEM_POST_TEMPLATE, model, serverId);
|
||||
List<CompletableFuture<Message>> futures = postTargetService.sendEmbedInPostTarget(messageToSend, WeeklyTextPostTarget.TEXT_ITEM_TARGET, serverId);
|
||||
CompletableFutureList<Message> futureList = new CompletableFutureList<>(futures);
|
||||
return futureList.getMainFuture().thenAccept(unused -> {
|
||||
self.setTexItemToDone(textItemId);
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void setTexItemToDone(Long id) {
|
||||
Optional<TextItem> textItemOptional = textItemServiceManagementBean.findTextItemById(id);
|
||||
textItemOptional.ifPresentOrElse(textItem -> {
|
||||
log.info("Setting textItem with ID {} to done.", id);
|
||||
textItem.setDone(true);
|
||||
}, () -> log.info("TextItem {} not found.", id));
|
||||
}
|
||||
|
||||
public void removeTextItem(Long id) {
|
||||
log.info("Deleting text item with ID {}.", id);
|
||||
textItemServiceManagementBean.deleteById(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package dev.sheldan.sissi.module.miepscord.weeklytext.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.sissi.module.miepscord.weeklytext.model.database.TextItem;
|
||||
import dev.sheldan.sissi.module.miepscord.weeklytext.repository.TextItemRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
public class TextItemServiceManagementBean {
|
||||
|
||||
@Autowired
|
||||
private TextItemRepository textItemRepository;
|
||||
|
||||
@Autowired
|
||||
private SecureRandom secureRandom;
|
||||
|
||||
public TextItem createTextItem(String text, AUserInAServer aUserInAServer) {
|
||||
TextItem textItem = TextItem
|
||||
.builder()
|
||||
.text(text)
|
||||
.creator(aUserInAServer)
|
||||
.done(false)
|
||||
.build();
|
||||
return textItemRepository.save(textItem);
|
||||
}
|
||||
|
||||
public Optional<TextItem> getNextTextItem() {
|
||||
List<TextItem> allItems = textItemRepository.findByDoneFalseOrderByCreated();
|
||||
if(allItems.isEmpty()) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
return Optional.of(allItems.get(secureRandom.nextInt(allItems.size())));
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<TextItem> findTextItemById(Long id) {
|
||||
return textItemRepository.findById(id);
|
||||
}
|
||||
|
||||
public void deleteById(Long id) {
|
||||
textItemRepository.deleteById(id);
|
||||
}
|
||||
|
||||
public List<TextItem> getAllTextItems() {
|
||||
return textItemRepository.findAll();
|
||||
}
|
||||
|
||||
public List<TextItem> getAllTextItemsWithDoneFlag(boolean done) {
|
||||
return textItemRepository.findByDone(done);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
abstracto.featureFlags.weeklyText.featureName=weeklyText
|
||||
abstracto.featureFlags.weeklyText.enabled=false
|
||||
|
||||
abstracto.postTargets.textItemTarget.name=textItemTarget
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="tables/tables.xml" relativeToChangelogFile="true"/>
|
||||
<include file="seedData/data.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<property name="utilityModule" value="(SELECT id FROM module WHERE name = 'utility')"/>
|
||||
<property name="weeklyTextFeature" value="(SELECT id FROM feature WHERE key = 'weeklyText')"/>
|
||||
<changeSet author="Sheldan" id="weeklyText-commands" >
|
||||
<insert tableName="command">
|
||||
<column name="name" value="addWeeklyText"/>
|
||||
<column name="module_id" valueComputed="${utilityModule}"/>
|
||||
<column name="feature_id" valueComputed="${weeklyTextFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="removeWeeklyText"/>
|
||||
<column name="module_id" valueComputed="${utilityModule}"/>
|
||||
<column name="feature_id" valueComputed="${weeklyTextFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="showWeeklyTexts"/>
|
||||
<column name="module_id" valueComputed="${utilityModule}"/>
|
||||
<column name="feature_id" valueComputed="${weeklyTextFeature}"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="feature.xml" relativeToChangelogFile="true"/>
|
||||
<include file="command.xml" relativeToChangelogFile="true"/>
|
||||
<include file="weekly_text_job.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<changeSet author="Sheldan" id="weeklyText_feature-insertion">
|
||||
<insert tableName="feature">
|
||||
<column name="key" value="weeklyText"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<changeSet author="Sheldan" id="weekly_text_job-insert">
|
||||
<insert tableName="scheduler_job">
|
||||
<column name="name" value="weeklyTextJob"/>
|
||||
<column name="group_name" value="miepscord"/>
|
||||
<column name="clazz" value="dev.sheldan.sissi.module.miepscord.weeklytext.job.WeeklyTextJob"/>
|
||||
<column name="active" value="true"/>
|
||||
<column name="cron_expression" value="0 0 14 ? * FRI *"/>
|
||||
<column name="recovery" value="false"/>
|
||||
</insert>
|
||||
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="text_item.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
|
||||
<changeSet author="Sheldan" id="text_item-table">
|
||||
<createTable tableName="text_item">
|
||||
<column name="id" autoIncrement="true" type="BIGINT">
|
||||
<constraints nullable="false" primaryKey="true" primaryKeyName="pk_text_item"/>
|
||||
</column>
|
||||
<column name="text" type="VARCHAR">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="done" type="BOOLEAN">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="creator_id" type="BIGINT">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
|
||||
<constraints nullable="true"/>
|
||||
</column>
|
||||
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
</createTable>
|
||||
<addForeignKeyConstraint baseColumnNames="creator_id" baseTableName="text_item" constraintName="fk_text_item_creator"
|
||||
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION"
|
||||
referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS text_item_update_trigger ON text_item;
|
||||
CREATE TRIGGER repost_check_channel_group_update_trigger BEFORE UPDATE ON text_item FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
|
||||
</sql>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS text_item_insert_trigger ON text_item;
|
||||
CREATE TRIGGER repost_check_channel_group_insert_trigger BEFORE INSERT ON text_item FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="1.4.61/collection.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.application</groupId>
|
||||
<artifactId>application</artifactId>
|
||||
<version>1.4.52-SNAPSHOT</version>
|
||||
<version>1.5.13-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<module>quotes</module>
|
||||
<module>meetup</module>
|
||||
<module>debra</module>
|
||||
<module>miepscord</module>
|
||||
<module>rss-news</module>
|
||||
</modules>
|
||||
|
||||
|
||||
@@ -3,13 +3,21 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.application</groupId>
|
||||
<artifactId>sissi-modules</artifactId>
|
||||
<version>1.4.52-SNAPSHOT</version>
|
||||
<version>1.5.13-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>dev.sheldan.sissi.application.module</groupId>
|
||||
<artifactId>quotes</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>starboard-int</artifactId>
|
||||
<version>${abstracto.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -23,6 +23,7 @@ import dev.sheldan.sissi.module.quotes.config.QuotesModuleDefinition;
|
||||
import dev.sheldan.sissi.module.quotes.exception.QuoteNotFoundException;
|
||||
import dev.sheldan.sissi.module.quotes.model.database.Quote;
|
||||
import dev.sheldan.sissi.module.quotes.service.QuoteServiceBean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
@@ -37,6 +38,7 @@ import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class QuoteCommand extends AbstractConditionableCommand {
|
||||
|
||||
private static final String QUOTE_COMMAND = "quote";
|
||||
@@ -76,6 +78,7 @@ public class QuoteCommand extends AbstractConditionableCommand {
|
||||
foundQuote = quoteServiceBean.getRandomQuoteForMember(user);
|
||||
}
|
||||
Quote quoteToDisplay = foundQuote.orElseThrow(QuoteNotFoundException::new);
|
||||
log.info("Displaying quote {} in server {}.", quoteToDisplay.getId(), quoteToDisplay.getServer().getId());
|
||||
return quoteServiceBean.renderQuoteToMessageToSend(quoteToDisplay)
|
||||
.thenCompose(messageToSend -> self.sendMessageToChannel(messageToSend, commandContext.getChannel()))
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
@@ -98,6 +101,7 @@ public class QuoteCommand extends AbstractConditionableCommand {
|
||||
foundQuote = quoteServiceBean.getRandomQuote(server);
|
||||
}
|
||||
Quote quoteToDisplay = foundQuote.orElseThrow(QuoteNotFoundException::new);
|
||||
log.info("Displaying quote {} in server {}.", quoteToDisplay.getId(), quoteToDisplay.getServer().getId());
|
||||
return quoteServiceBean.renderQuoteToMessageToSend(quoteToDisplay)
|
||||
.thenCompose(messageToSend -> self.replyMessage(event, messageToSend))
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
|
||||
@@ -9,6 +9,7 @@ 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.SlashCommandPrivilegeLevels;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
@@ -79,6 +80,7 @@ public class QuoteDelete extends AbstractConditionableCommand {
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(QuoteSlashCommandNames.QUOTE_INTERNAL)
|
||||
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
|
||||
.commandName("delete")
|
||||
.build();
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ public class QuoteStats extends AbstractConditionableCommand {
|
||||
targetMember = (Member) parameters.get(0);
|
||||
}
|
||||
QuoteStatsModel model = quoteServiceBean.getQuoteStats(targetMember);
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInMessageChannelList(QUOTE_STATS_RESPONSE_TEMPLATE_KEY, model, commandContext.getChannel()))
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInMessageChannel(QUOTE_STATS_RESPONSE_TEMPLATE_KEY, model, commandContext.getChannel()))
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum QuotesFeatureDefinition implements FeatureDefinition {
|
||||
QUOTES("quotes");
|
||||
QUOTES("quotes"), STARBOARD_QUOTE_SYNC("starboardQuoteSync");
|
||||
|
||||
private String key;
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package dev.sheldan.sissi.module.quotes.config;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureConfig;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class StarboardQuoteSyncFeatureConfig implements FeatureConfig {
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return QuotesFeatureDefinition.STARBOARD_QUOTE_SYNC;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package dev.sheldan.sissi.module.quotes.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.starboard.listener.StarboardPostCreatedListener;
|
||||
import dev.sheldan.abstracto.starboard.model.StarboardPostCreatedModel;
|
||||
import dev.sheldan.sissi.module.quotes.config.QuotesFeatureDefinition;
|
||||
import dev.sheldan.sissi.module.quotes.service.QuoteServiceBean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class StarboardPostCreatedListenerBean implements StarboardPostCreatedListener {
|
||||
|
||||
@Autowired
|
||||
private MessageService messageService;
|
||||
|
||||
@Autowired
|
||||
private QuoteServiceBean quoteServiceBean;
|
||||
|
||||
@Autowired
|
||||
private StarboardPostCreatedListenerBean self;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(StarboardPostCreatedModel model) {
|
||||
Long serverId = model.getServerId();
|
||||
Long starboardPostId = model.getStarboardPostId();
|
||||
messageService.loadMessage(serverId, model.getStarredMessage().getChannelId(), model.getStarredMessage().getMessageId())
|
||||
.thenAccept(message -> self.storeQuote(message, model))
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Failed to persist quote for starboard post {} in server {}.", starboardPostId, serverId, throwable);
|
||||
return null;
|
||||
});
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void storeQuote(Message message, StarboardPostCreatedModel model) {
|
||||
log.info("Creating quote from starboard post {} in server {} from user {} because of user {}.", model.getStarboardPostId(), model.getServerId(),
|
||||
model.getStarredUser().getUserId(), model.getLastStarrer().getUserId());
|
||||
quoteServiceBean.createQuote(model.getStarredUser(), model.getLastStarrer(), message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return QuotesFeatureDefinition.STARBOARD_QUOTE_SYNC;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package dev.sheldan.sissi.module.quotes.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.starboard.listener.StarboardPostDeletedListener;
|
||||
import dev.sheldan.abstracto.starboard.model.StarboardPostDeletedModel;
|
||||
import dev.sheldan.sissi.module.quotes.config.QuotesFeatureDefinition;
|
||||
import dev.sheldan.sissi.module.quotes.service.QuoteServiceBean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class StarboardPostDeletedListenerBean implements StarboardPostDeletedListener {
|
||||
|
||||
@Autowired
|
||||
private QuoteServiceBean quoteServiceBean;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(StarboardPostDeletedModel model) {
|
||||
log.info("Handling delete of starboard post {}, causing the quote of message {} in server {} to be deleted.", model.getStarboardPostId(), model.getStarredMessage().getMessageId(), model.getServerId());
|
||||
quoteServiceBean.deleteByMessageId(model.getStarredMessage().getMessageId());
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return QuotesFeatureDefinition.STARBOARD_QUOTE_SYNC;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package dev.sheldan.sissi.module.quotes.model.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.models.template.display.UserDisplay;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@@ -11,14 +13,14 @@ import java.util.List;
|
||||
@Builder
|
||||
public class QuoteResponseModel {
|
||||
private Long quoteId;
|
||||
private String authorAvatarURL;
|
||||
private String authorName;
|
||||
private UserDisplay authorUserDisplay;
|
||||
private MemberDisplay authorMemberDisplay;
|
||||
private ServerChannelMessage quotedMessage;
|
||||
private String quoteContent;
|
||||
private List<String> imageAttachmentURLs;
|
||||
private List<String> mediaAttachmentURLs;
|
||||
private List<String> fileAttachmentURLs;
|
||||
private String adderAvatarURL;
|
||||
private String adderName;
|
||||
private UserDisplay adderUserDisplay;
|
||||
private MemberDisplay adderMemberDisplay;
|
||||
private Instant creationDate;
|
||||
private String sourceChannelName;
|
||||
}
|
||||
|
||||
@@ -21,12 +21,12 @@ import java.util.List;
|
||||
@EqualsAndHashCode
|
||||
public class Quote {
|
||||
|
||||
@EmbeddedId
|
||||
@Getter
|
||||
private ServerSpecificId id;
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id", nullable = false)
|
||||
private Long id;
|
||||
|
||||
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY)
|
||||
@MapsId("serverId")
|
||||
@JoinColumn(name = "server_id", nullable = false)
|
||||
private AServer server;
|
||||
|
||||
@@ -58,9 +58,9 @@ public class Quote {
|
||||
@Column(name = "text")
|
||||
private String text;
|
||||
|
||||
@Column(name = "created")
|
||||
@Column(name = "created", insertable = false, updatable = false)
|
||||
private Instant created;
|
||||
|
||||
@Column(name = "updated")
|
||||
@Column(name = "updated", insertable = false, updatable = false)
|
||||
private Instant updated;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.sissi.module.quotes.model.database;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import lombok.*;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
@@ -16,7 +17,7 @@ public class QuoteAttachment {
|
||||
|
||||
@Id
|
||||
@Getter
|
||||
@Setter
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id", nullable = false)
|
||||
private Long id;
|
||||
|
||||
@@ -25,8 +26,7 @@ public class QuoteAttachment {
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumns(
|
||||
{
|
||||
@JoinColumn(updatable = false, insertable = false, name = "quote_id", referencedColumnName = "id"),
|
||||
@JoinColumn(updatable = false, insertable = false, name = "server_id", referencedColumnName = "server_id")
|
||||
@JoinColumn(updatable = false, name = "quote_id", referencedColumnName = "id")
|
||||
})
|
||||
private Quote quote;
|
||||
|
||||
@@ -35,10 +35,14 @@ public class QuoteAttachment {
|
||||
@Column(name = "url", nullable = false)
|
||||
private String url;
|
||||
|
||||
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "server_id", nullable = false)
|
||||
private AServer server;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Column(name = "is_image", nullable = false)
|
||||
@Column(name = "is_media", nullable = false)
|
||||
@Builder.Default
|
||||
private Boolean isImage = false;
|
||||
private Boolean isMedia = false;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package dev.sheldan.sissi.module.quotes.repository;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.sissi.module.quotes.model.database.Quote;
|
||||
@@ -8,13 +7,16 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface QuoteRepository extends JpaRepository<Quote, ServerSpecificId> {
|
||||
public interface QuoteRepository extends JpaRepository<Quote, Long> {
|
||||
List<Quote> findByTextContainingAndServer(String text, AServer server);
|
||||
List<Quote> findByTextContainingAndServerAndAuthor(String text, AServer server, AUserInAServer author);
|
||||
List<Quote> findByServer(AServer server);
|
||||
List<Quote> findByAuthor(AUserInAServer author);
|
||||
Long countByAuthor(AUserInAServer author);
|
||||
Long countByAdder(AUserInAServer adder);
|
||||
|
||||
Optional<Quote> findByMessageId(Long messageId);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package dev.sheldan.sissi.module.quotes.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.models.template.display.UserDisplay;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.MemberService;
|
||||
import dev.sheldan.abstracto.core.service.UserService;
|
||||
@@ -16,11 +18,12 @@ import dev.sheldan.sissi.module.quotes.model.command.QuoteResponseModel;
|
||||
import dev.sheldan.sissi.module.quotes.model.command.QuoteStatsModel;
|
||||
import dev.sheldan.sissi.module.quotes.model.database.Quote;
|
||||
import dev.sheldan.sissi.module.quotes.model.database.QuoteAttachment;
|
||||
import dev.sheldan.sissi.module.quotes.repository.QuoteRepository;
|
||||
import dev.sheldan.sissi.module.quotes.service.management.QuoteManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
import net.dv8tion.jda.api.entities.channel.Channel;
|
||||
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -35,9 +38,6 @@ import java.util.stream.Collectors;
|
||||
@Slf4j
|
||||
public class QuoteServiceBean {
|
||||
|
||||
@Autowired
|
||||
private QuoteRepository quoteRepository;
|
||||
|
||||
@Autowired
|
||||
private MemberService memberService;
|
||||
|
||||
@@ -56,11 +56,14 @@ public class QuoteServiceBean {
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private QuoteManagementService quoteManagementService;
|
||||
|
||||
private static final String QUOTE_RESPONSE_TEMPLATE_KEY = "quote_response";
|
||||
|
||||
public Optional<Quote> getRandomQuoteForMember(AUserInAServer aUserInAServer) {
|
||||
// not nice, but good enough for now
|
||||
List<Quote> allQuotes = quoteRepository.findByAuthor(aUserInAServer);
|
||||
List<Quote> allQuotes = quoteManagementService.getFromAuthor(aUserInAServer);
|
||||
if(allQuotes.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
@@ -69,7 +72,7 @@ public class QuoteServiceBean {
|
||||
|
||||
public Optional<Quote> getRandomQuote(AServer server) {
|
||||
// not nice, but good enough for now
|
||||
List<Quote> allQuotes = quoteRepository.findByServer(server);
|
||||
List<Quote> allQuotes = quoteManagementService.getFromServer(server);
|
||||
if(allQuotes.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
@@ -79,7 +82,7 @@ public class QuoteServiceBean {
|
||||
public void deleteQuote(Long quoteId, AServer server) {
|
||||
Optional<Quote> existingQuote = getQuote(quoteId, server);
|
||||
if(existingQuote.isPresent()) {
|
||||
quoteRepository.delete(existingQuote.get());
|
||||
quoteManagementService.deleteQuote(existingQuote.get());
|
||||
log.info("Deleting quote with id {} in server {}.", quoteId, server.getId());
|
||||
} else {
|
||||
throw new QuoteNotFoundException();
|
||||
@@ -87,9 +90,8 @@ public class QuoteServiceBean {
|
||||
}
|
||||
|
||||
public Optional<Quote> getQuote(Long quoteId, AServer server) {
|
||||
ServerSpecificId id = new ServerSpecificId(server.getId(), quoteId);
|
||||
log.info("Loading quote with id {} in server {}.", quoteId, server.getId());
|
||||
return quoteRepository.findById(id);
|
||||
return quoteManagementService.getQuote(quoteId);
|
||||
}
|
||||
|
||||
public CompletableFuture<MessageToSend> renderQuoteToMessageToSend(Quote quote) {
|
||||
@@ -103,22 +105,22 @@ public class QuoteServiceBean {
|
||||
List<String> imageAttachments = quote
|
||||
.getAttachments()
|
||||
.stream()
|
||||
.filter(QuoteAttachment::getIsImage)
|
||||
.filter(QuoteAttachment::getIsMedia)
|
||||
.map(QuoteAttachment::getUrl)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<String> fileAttachments = quote
|
||||
.getAttachments()
|
||||
.stream()
|
||||
.filter(quoteAttachment -> !quoteAttachment.getIsImage())
|
||||
.filter(quoteAttachment -> !quoteAttachment.getIsMedia())
|
||||
.map(QuoteAttachment::getUrl)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
QuoteResponseModel.QuoteResponseModelBuilder modelBuilder = QuoteResponseModel
|
||||
.builder()
|
||||
.quoteContent(quote.getText())
|
||||
.imageAttachmentURLs(imageAttachments)
|
||||
.quoteId(quote.getId().getId())
|
||||
.mediaAttachmentURLs(imageAttachments)
|
||||
.quoteId(quote.getId())
|
||||
.fileAttachmentURLs(fileAttachments)
|
||||
.creationDate(quote.getCreated())
|
||||
.quotedMessage(quotedMessage);
|
||||
@@ -166,42 +168,14 @@ public class QuoteServiceBean {
|
||||
.filter(user -> user.getIdLong() == quoteAdderUserId)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
String adderAvatar = Optional
|
||||
.ofNullable(adderMember)
|
||||
.map(member -> member.getUser().getAvatarUrl())
|
||||
.orElse(Optional
|
||||
.ofNullable(adderUser)
|
||||
.map(User::getAvatarUrl)
|
||||
.orElse(null));
|
||||
String authorAvatar = Optional
|
||||
.ofNullable(authorMember)
|
||||
.map(member -> member.getUser().getAvatarUrl())
|
||||
.orElse(Optional
|
||||
.ofNullable(authorUser)
|
||||
.map(User::getAvatarUrl)
|
||||
.orElse(null));
|
||||
String adderName = Optional
|
||||
.ofNullable(adderMember)
|
||||
.map(Member::getEffectiveName)
|
||||
.orElse(Optional
|
||||
.ofNullable(adderUser)
|
||||
.map(User::getName)
|
||||
.orElse(null));
|
||||
String authorName = Optional
|
||||
.ofNullable(authorMember)
|
||||
.map(Member::getEffectiveName)
|
||||
.orElse(Optional
|
||||
.ofNullable(authorUser)
|
||||
.map(User::getName)
|
||||
.orElse(null));
|
||||
String channelName = sourceChannel
|
||||
.map(Channel::getName)
|
||||
.orElse(null);
|
||||
QuoteResponseModel model = modelBuilder
|
||||
.adderAvatarURL(adderAvatar)
|
||||
.authorAvatarURL(authorAvatar)
|
||||
.adderName(adderName)
|
||||
.authorName(authorName)
|
||||
.authorMemberDisplay(authorMember != null ? MemberDisplay.fromMember(authorMember) : null)
|
||||
.authorUserDisplay(authorUser != null ? UserDisplay.fromUser(authorUser) : UserDisplay.fromServerUser(ServerUser.fromId(serverId, quotedUserId)))
|
||||
.adderMemberDisplay(adderMember != null ? MemberDisplay.fromMember(adderMember) : null)
|
||||
.adderUserDisplay(adderUser != null ? UserDisplay.fromUser(adderUser) : UserDisplay.fromServerUser(ServerUser.fromId(serverId, quoteAdderUserId)))
|
||||
.sourceChannelName(channelName)
|
||||
.build();
|
||||
return templateService.renderEmbedTemplate(QUOTE_RESPONSE_TEMPLATE_KEY, model, serverId);
|
||||
@@ -209,7 +183,7 @@ public class QuoteServiceBean {
|
||||
}
|
||||
|
||||
public Optional<Quote> searchQuote(String query, AServer server) {
|
||||
List<Quote> foundQuotes = quoteRepository.findByTextContainingAndServer(query, server);
|
||||
List<Quote> foundQuotes = quoteManagementService.getQuotesWithTextInServer(query, server);
|
||||
if(foundQuotes.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
@@ -224,7 +198,7 @@ public class QuoteServiceBean {
|
||||
|
||||
public Optional<Quote> searchQuote(String query, AServer server, Member targetMember) {
|
||||
AUserInAServer author = userInServerManagementService.loadOrCreateUser(targetMember);
|
||||
List<Quote> foundQuotes = quoteRepository.findByTextContainingAndServerAndAuthor(query, server, author);
|
||||
List<Quote> foundQuotes = quoteManagementService.getQuotesWithTextInServerFromAuthor(query, server, author);
|
||||
if(foundQuotes.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
@@ -242,8 +216,8 @@ public class QuoteServiceBean {
|
||||
return getQuoteStats(user, member);
|
||||
}
|
||||
public QuoteStatsModel getQuoteStats(AUserInAServer user, Member member) {
|
||||
Long authored = quoteRepository.countByAuthor(user);
|
||||
Long added = quoteRepository.countByAdder(user);
|
||||
Long authored = quoteManagementService.getAmountOfQuotesOfAuthor(user);
|
||||
Long added = quoteManagementService.getAmountOfQuotesOfAdder(user);
|
||||
return QuoteStatsModel
|
||||
.builder()
|
||||
.quoteCount(added)
|
||||
@@ -253,4 +227,21 @@ public class QuoteServiceBean {
|
||||
.serverId(user.getServerReference().getId())
|
||||
.build();
|
||||
}
|
||||
|
||||
public Quote createQuote(ServerUser authorUser, ServerUser adderUser, Message quoteMessage) {
|
||||
AUserInAServer author = userInServerManagementService.loadOrCreateUser(authorUser);
|
||||
AUserInAServer adder = userInServerManagementService.loadOrCreateUser(adderUser);
|
||||
List<Pair<String, Boolean>> attachments = quoteMessage
|
||||
.getAttachments()
|
||||
.stream()
|
||||
.map(attachment -> Pair.of(attachment.getProxyUrl(), attachment.isImage() || attachment.isVideo()))
|
||||
.toList();
|
||||
return quoteManagementService.createQuote(author, adder, quoteMessage.getContentDisplay(), ServerChannelMessage.fromMessage(quoteMessage), attachments);
|
||||
}
|
||||
|
||||
public void deleteByMessageId(Long messageId) {
|
||||
Quote quote = quoteManagementService.findByMessage(messageId).orElseThrow(QuoteNotFoundException::new);
|
||||
log.info("Deleting quote {} in server {}.", quote.getId(), quote.getServer().getId());
|
||||
quoteManagementService.deleteQuote(quote);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
package dev.sheldan.sissi.module.quotes.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.sissi.module.quotes.model.database.Quote;
|
||||
import dev.sheldan.sissi.module.quotes.model.database.QuoteAttachment;
|
||||
import dev.sheldan.sissi.module.quotes.repository.QuoteRepository;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class QuoteManagementService {
|
||||
|
||||
@Autowired
|
||||
private QuoteRepository quoteRepository;
|
||||
|
||||
@Autowired
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
public Quote createQuote(AUserInAServer author, AUserInAServer adder, String messageText, ServerChannelMessage quotedMessage, List<Pair<String, Boolean>> attachments) {
|
||||
AChannel channel = channelManagementService.loadChannel(quotedMessage.getChannelId());
|
||||
|
||||
Quote quote = Quote
|
||||
.builder()
|
||||
.adder(adder)
|
||||
.author(author)
|
||||
.text(messageText)
|
||||
.messageId(quotedMessage.getMessageId())
|
||||
.server(adder.getServerReference())
|
||||
.sourceChannel(channel)
|
||||
.build();
|
||||
List<QuoteAttachment> quoteAttachments = attachments
|
||||
.stream()
|
||||
.map(stringBooleanPair -> QuoteAttachment
|
||||
.builder()
|
||||
.url(stringBooleanPair.getLeft())
|
||||
.quote(quote)
|
||||
.server(adder.getServerReference())
|
||||
.isMedia(stringBooleanPair.getRight())
|
||||
.build())
|
||||
.toList();
|
||||
|
||||
log.info("Creating quote from {} added by {} in server {}.", author.getUserReference().getId(), adder.getUserReference().getId(), author.getServerReference().getId());
|
||||
|
||||
quote.setAttachments(quoteAttachments);
|
||||
|
||||
return quoteRepository.save(quote);
|
||||
}
|
||||
|
||||
public List<Quote> getFromAuthor(AUserInAServer author) {
|
||||
return quoteRepository.findByAuthor(author);
|
||||
}
|
||||
|
||||
public List<Quote> getFromServer(AServer aServer) {
|
||||
return quoteRepository.findByServer(aServer);
|
||||
}
|
||||
|
||||
public void deleteQuote(Quote quote) {
|
||||
quoteRepository.delete(quote);
|
||||
}
|
||||
|
||||
public Optional<Quote> getQuote(Long quoteId) {
|
||||
return quoteRepository.findById(quoteId);
|
||||
}
|
||||
|
||||
public List<Quote> getQuotesWithTextInServer(String text, AServer server) {
|
||||
return quoteRepository.findByTextContainingAndServer(text, server);
|
||||
}
|
||||
|
||||
public List<Quote> getQuotesWithTextInServerFromAuthor(String text, AServer server, AUserInAServer aUserInAServer) {
|
||||
return quoteRepository.findByTextContainingAndServerAndAuthor(text, server, aUserInAServer);
|
||||
}
|
||||
|
||||
public Long getAmountOfQuotesOfAuthor(AUserInAServer aUserInAServer) {
|
||||
return quoteRepository.countByAuthor(aUserInAServer);
|
||||
}
|
||||
|
||||
public Long getAmountOfQuotesOfAdder(AUserInAServer aUserInAServer) {
|
||||
return quoteRepository.countByAdder(aUserInAServer);
|
||||
}
|
||||
|
||||
public Optional<Quote> findByMessage(Long messageId) {
|
||||
return quoteRepository.findByMessageId(messageId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="seedData/data.xml" relativeToChangelogFile="true"/>
|
||||
<include file="tables/tables.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="feature.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<changeSet author="Sheldan" id="starboard_quote_sync_feature-insertion">
|
||||
<insert tableName="feature">
|
||||
<column name="key" value="starboardQuoteSync"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<changeSet author="Sheldan" id="quote-add_tracking_columns">
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS quote_update_trigger ON quote;
|
||||
CREATE TRIGGER quote_update_trigger BEFORE UPDATE ON quote FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
|
||||
</sql>
|
||||
<sql>
|
||||
DROP TRIGGER IF EXISTS quote_insert_trigger ON quote;
|
||||
CREATE TRIGGER quote_insert_trigger BEFORE INSERT ON quote FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="quote.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="tables/tables.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<changeSet author="Sheldan" id="quote_attachment-longer_attachment_url">
|
||||
<modifyDataType columnName="url"
|
||||
newDataType="VARCHAR(4096)"
|
||||
tableName="quote_attachment"/>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="quote_attachment.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="tables/tables.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<changeSet author="Sheldan" id="quote_attachment-rename-media-column">
|
||||
<renameColumn
|
||||
tableName="quote_attachment"
|
||||
newColumnName="is_media"
|
||||
oldColumnName="is_image" />
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="quote_attachment.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -3,4 +3,7 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
|
||||
<include file="1.0.2/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.4.56/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.4.57/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.5.6/collection.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -1,2 +1,5 @@
|
||||
abstracto.featureFlags.quotes.featureName=quotes
|
||||
abstracto.featureFlags.quotes.enabled=false
|
||||
|
||||
abstracto.featureFlags.starboardQuoteSync.featureName=starboardQuoteSync
|
||||
abstracto.featureFlags.starboardQuoteSync.enabled=false
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>sissi-modules</artifactId>
|
||||
<groupId>dev.sheldan.sissi.application</groupId>
|
||||
<version>1.4.52-SNAPSHOT</version>
|
||||
<version>1.5.13-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ 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.SlashCommandPrivilegeLevels;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
@@ -70,6 +71,7 @@ public class CreateNewsCategory extends AbstractConditionableCommand {
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(RssNewsSlashCommandNames.RSS_NEWS)
|
||||
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
|
||||
.groupName("category")
|
||||
.commandName("create")
|
||||
.build();
|
||||
|
||||
@@ -9,6 +9,7 @@ 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.SlashCommandPrivilegeLevels;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.sissi.module.rssnews.config.RssNewsFeatureDefinition;
|
||||
@@ -97,6 +98,7 @@ public class CreateNewsCategoryChannelMapping extends AbstractConditionableComma
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(RssNewsSlashCommandNames.RSS_NEWS)
|
||||
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
|
||||
.groupName("categorychannelmapping")
|
||||
.commandName("create")
|
||||
.build();
|
||||
|
||||
@@ -9,6 +9,7 @@ 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.SlashCommandPrivilegeLevels;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.sissi.module.rssnews.config.RssNewsFeatureDefinition;
|
||||
@@ -127,6 +128,7 @@ public class CreateNewsCategorySubscription extends AbstractConditionableCommand
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(RssNewsSlashCommandNames.RSS_NEWS)
|
||||
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
|
||||
.groupName("categorysubscription")
|
||||
.commandName("create")
|
||||
.build();
|
||||
|
||||
@@ -9,6 +9,7 @@ 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.SlashCommandPrivilegeLevels;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
@@ -70,6 +71,7 @@ public class DeleteNewsCategory extends AbstractConditionableCommand {
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(RssNewsSlashCommandNames.RSS_NEWS)
|
||||
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
|
||||
.groupName("category")
|
||||
.commandName("delete")
|
||||
.build();
|
||||
|
||||
@@ -9,6 +9,7 @@ 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.SlashCommandPrivilegeLevels;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.sissi.module.rssnews.config.RssNewsFeatureDefinition;
|
||||
@@ -96,6 +97,7 @@ public class DeleteNewsCategoryChannelMapping extends AbstractConditionableComma
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(RssNewsSlashCommandNames.RSS_NEWS)
|
||||
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
|
||||
.groupName("categorychannelmapping")
|
||||
.commandName("delete")
|
||||
.build();
|
||||
|
||||
@@ -9,6 +9,7 @@ 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.SlashCommandPrivilegeLevels;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.sissi.module.rssnews.config.RssNewsFeatureDefinition;
|
||||
@@ -127,6 +128,7 @@ public class DeleteNewsCategorySubscription extends AbstractConditionableCommand
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(RssNewsSlashCommandNames.RSS_NEWS)
|
||||
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
|
||||
.groupName("categorysubscription")
|
||||
.commandName("delete")
|
||||
.build();
|
||||
|
||||
@@ -8,6 +8,7 @@ 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.SlashCommandPrivilegeLevels;
|
||||
import dev.sheldan.sissi.module.rssnews.config.RssNewsFeatureDefinition;
|
||||
import dev.sheldan.sissi.module.rssnews.config.RssNewsSlashCommandNames;
|
||||
import dev.sheldan.sissi.module.rssnews.model.template.NewsCategoryInfo;
|
||||
@@ -54,6 +55,7 @@ public class ShowNewsCategories extends AbstractConditionableCommand {
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(RssNewsSlashCommandNames.RSS_NEWS)
|
||||
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
|
||||
.groupName("category")
|
||||
.commandName("show")
|
||||
.build();
|
||||
|
||||
@@ -2,4 +2,4 @@ apiVersion: v2
|
||||
name: sissi
|
||||
description: A Helm chart for Kubernetes
|
||||
type: application
|
||||
version: 1.4.51
|
||||
version: 1.5.12
|
||||
|
||||
@@ -7,4 +7,5 @@ data:
|
||||
youtubeApiKey: {{ $.Values.apiKeys.youtube.apiKey | b64enc }}
|
||||
twitchClientId: {{ $.Values.apiKeys.twitch.clientId | b64enc }}
|
||||
twitchSecret: {{ $.Values.apiKeys.twitch.secret | b64enc }}
|
||||
openWeatherMapApiKey: {{ $.Values.apiKeys.openWeatherMap.apiKey | b64enc }}
|
||||
openWeatherMapApiKey: {{ $.Values.apiKeys.openWeatherMap.apiKey | b64enc }}
|
||||
freeCurrencyApiApiKey: {{ $.Values.apiKeys.freeCurrencyApi.apiKey | b64enc }}
|
||||
@@ -61,6 +61,8 @@ spec:
|
||||
value: {{ .Values.dbCredentials.schema }}
|
||||
- name: DEBRA_DONATION_NOTIFICATION_SERVER_ID
|
||||
value: "297910194841583616"
|
||||
- name: WEEKLY_TEXT_SERVER_ID
|
||||
value: "{{ .Values.bot.config.weeklyTextServerId }}"
|
||||
- name: TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
@@ -76,6 +78,11 @@ spec:
|
||||
secretKeyRef:
|
||||
name: api-keys
|
||||
key: openWeatherMapApiKey
|
||||
- name: FREE_CURRENCY_API_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: api-keys
|
||||
key: freeCurrencyApiApiKey
|
||||
- name: TWITCH_CLIENT_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
|
||||
@@ -3,7 +3,7 @@ bot:
|
||||
repository: harbor.sheldan.dev/sissi
|
||||
pullPolicy: Always
|
||||
image: sissi-bot
|
||||
tag: 1.4.51
|
||||
tag: 1.5.12
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 5
|
||||
@@ -14,13 +14,15 @@ bot:
|
||||
failureThreshold: 3
|
||||
propertyConfig:
|
||||
hikariPoolSize: 10
|
||||
host:
|
||||
host: null
|
||||
config:
|
||||
weeklyTextServerId: null
|
||||
restApi:
|
||||
enabled: true
|
||||
repository: harbor.sheldan.dev/sissi
|
||||
pullPolicy: Always
|
||||
image: sissi-rest-api
|
||||
tag: 1.4.51
|
||||
tag: 1.5.12
|
||||
podAnnotations: {}
|
||||
podSecurityContext: {}
|
||||
securityContext: {}
|
||||
@@ -60,7 +62,7 @@ privateRestApi:
|
||||
repository: harbor.sheldan.dev/sissi
|
||||
pullPolicy: Always
|
||||
image: sissi-private-rest-api
|
||||
tag: 1.4.51
|
||||
tag: 1.5.12
|
||||
podAnnotations: {}
|
||||
podSecurityContext: {}
|
||||
securityContext: {}
|
||||
@@ -91,23 +93,23 @@ templateDeployment:
|
||||
repository: harbor.sheldan.dev/abstracto
|
||||
pullPolicy: Always
|
||||
image: abstracto-template-deployment
|
||||
tag: 1.5.35
|
||||
tag: 1.6.14
|
||||
templateDeploymentData:
|
||||
repository: harbor.sheldan.dev/sissi
|
||||
pullPolicy: Always
|
||||
image: sissi-template-data
|
||||
tag: 1.4.51
|
||||
tag: 1.5.12
|
||||
dbConfigDeployment:
|
||||
enabled: true
|
||||
repository: harbor.sheldan.dev/abstracto
|
||||
pullPolicy: Always
|
||||
image: abstracto-db-deployment
|
||||
tag: 1.5.35
|
||||
tag: 1.6.14
|
||||
dbConfigDeploymentData:
|
||||
repository: harbor.sheldan.dev/sissi
|
||||
pullPolicy: Always
|
||||
image: sissi-db-data
|
||||
tag: 1.4.51
|
||||
tag: 1.5.12
|
||||
dbCredentials:
|
||||
host: null
|
||||
port: null
|
||||
@@ -136,6 +138,8 @@ apiKeys:
|
||||
twitch:
|
||||
secret: null
|
||||
clientId: null
|
||||
freeCurrencyApi:
|
||||
apiKey: null
|
||||
imagePullSecrets: null
|
||||
nameOverride: ''
|
||||
fullnameOverride: ''
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user