3
3
import net .dv8tion .jda .api .JDA ;
4
4
import net .dv8tion .jda .api .entities .Guild ;
5
5
import net .dv8tion .jda .api .entities .Member ;
6
+ import net .dv8tion .jda .api .entities .Role ;
7
+ import net .dv8tion .jda .api .entities .UserSnowflake ;
6
8
import org .jooq .Query ;
7
9
import org .jooq .impl .DSL ;
8
10
import org .slf4j .Logger ;
21
23
import java .util .Optional ;
22
24
import java .util .concurrent .CompletableFuture ;
23
25
import java .util .concurrent .TimeUnit ;
26
+ import java .util .function .Predicate ;
27
+ import java .util .regex .Pattern ;
24
28
import java .util .stream .Collectors ;
25
29
26
30
import static org .togetherjava .tjbot .db .generated .tables .CakeDays .CAKE_DAYS ;
@@ -31,12 +35,15 @@ public class CakeDayRoutine implements Routine {
31
35
private static final DateTimeFormatter MONTH_DAY_FORMATTER =
32
36
DateTimeFormatter .ofPattern ("MM-dd" );
33
37
private static final int BULK_INSERT_SIZE = 500 ;
38
+ private final Predicate <String > cakeDayRolePredicate ;
34
39
private final CakeDayConfig config ;
35
40
private final Database database ;
36
41
37
42
public CakeDayRoutine (Config config , Database database ) {
38
43
this .config = config .getCakeDayConfig ();
39
44
this .database = database ;
45
+
46
+ this .cakeDayRolePredicate = Pattern .compile (this .config .rolePattern ()).asPredicate ();
40
47
}
41
48
42
49
/**
@@ -75,7 +82,49 @@ public void runRoutine(JDA jda) {
75
82
76
83
return result ;
77
84
});
85
+
86
+ return ;
78
87
}
88
+
89
+ jda .getGuilds ().forEach (this ::reassignCakeDayRole );
90
+ }
91
+
92
+ private void reassignCakeDayRole (Guild guild ) {
93
+ Role cakeDayRole = getCakeDayRoleFromGuild (guild ).orElse (null );
94
+
95
+ if (cakeDayRole == null ) {
96
+ logger .warn ("Cake day role with pattern {} not found for guild: {}" ,
97
+ config .rolePattern (), guild .getName ());
98
+ return ;
99
+ }
100
+
101
+ removeMembersCakeDayRole (cakeDayRole , guild )
102
+ .thenCompose (result -> addTodayMembersCakeDayRole (cakeDayRole , guild ))
103
+ .join ();
104
+ }
105
+
106
+ private CompletableFuture <Void > addTodayMembersCakeDayRole (Role cakeDayRole , Guild guild ) {
107
+ return CompletableFuture
108
+ .runAsync (() -> findCakeDaysTodayFromDatabase ().forEach (cakeDayRecord -> {
109
+ UserSnowflake snowflake = UserSnowflake .fromId (cakeDayRecord .getUserId ());
110
+
111
+ int anniversary = OffsetDateTime .now ().getYear () - cakeDayRecord .getJoinedYear ();
112
+ if (anniversary > 0 ) {
113
+ guild .addRoleToMember (snowflake , cakeDayRole ).complete ();
114
+ }
115
+ }));
116
+ }
117
+
118
+ private CompletableFuture <Void > removeMembersCakeDayRole (Role cakeDayRole , Guild guild ) {
119
+ return CompletableFuture .runAsync (() -> guild .findMembersWithRoles (cakeDayRole )
120
+ .onSuccess (members -> removeRoleFromMembers (guild , cakeDayRole , members )));
121
+ }
122
+
123
+ private void removeRoleFromMembers (Guild guild , Role role , List <Member > members ) {
124
+ members .forEach (member -> {
125
+ UserSnowflake snowflake = UserSnowflake .fromId (member .getIdLong ());
126
+ guild .removeRoleFromMember (snowflake , role ).complete ();
127
+ });
79
128
}
80
129
81
130
private int getCakeDayCount (Database database ) {
@@ -121,6 +170,13 @@ private Optional<Query> createMemberCakeDayQuery(Member member, long guildId) {
121
170
.set (CAKE_DAYS .USER_ID , member .getIdLong ()));
122
171
}
123
172
173
+ private Optional <Role > getCakeDayRoleFromGuild (Guild guild ) {
174
+ return guild .getRoles ()
175
+ .stream ()
176
+ .filter (role -> cakeDayRolePredicate .test (role .getName ()))
177
+ .findFirst ();
178
+ }
179
+
124
180
private List <CakeDaysRecord > findCakeDaysTodayFromDatabase () {
125
181
String todayMonthDay = OffsetDateTime .now ().format (MONTH_DAY_FORMATTER );
126
182
0 commit comments