-
-
Notifications
You must be signed in to change notification settings - Fork 91
Feature: Cake Day #1042
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Feature: Cake Day #1042
Conversation
60b2118
to
c7bff99
Compare
application/src/main/java/org/togetherjava/tjbot/config/Config.java
Outdated
Show resolved
Hide resolved
application/src/main/java/org/togetherjava/tjbot/features/cakeday/CakeDayService.java
Outdated
Show resolved
Hide resolved
application/src/main/java/org/togetherjava/tjbot/config/CakeDayConfig.java
Outdated
Show resolved
Hide resolved
application/src/main/java/org/togetherjava/tjbot/features/cakeday/CakeDayService.java
Outdated
Show resolved
Hide resolved
application/src/main/java/org/togetherjava/tjbot/features/cakeday/CakeDayService.java
Show resolved
Hide resolved
application/src/main/java/org/togetherjava/tjbot/features/cakeday/CakeDayService.java
Outdated
Show resolved
Hide resolved
application/src/main/java/org/togetherjava/tjbot/features/cakeday/CakeDayService.java
Outdated
Show resolved
Hide resolved
application/src/main/java/org/togetherjava/tjbot/features/cakeday/CakeDayService.java
Outdated
Show resolved
Hide resolved
application/src/main/java/org/togetherjava/tjbot/features/cakeday/CakeDayService.java
Show resolved
Hide resolved
application/src/main/java/org/togetherjava/tjbot/features/cakeday/CakeDayService.java
Show resolved
Hide resolved
It would be nice if one of the @Together-Java/moderators can review some of the critical parts of this feature when you can. |
application/src/main/java/org/togetherjava/tjbot/features/cakeday/CakeDayListener.java
Show resolved
Hide resolved
d8c7206
to
20886ad
Compare
20886ad
to
eab0bdf
Compare
eab0bdf
to
e98eb35
Compare
e98eb35
to
079d68f
Compare
Co-authored-by: TheCodeMr <151576372+TheCodeMr@users.noreply.github.com> Co-authored-by: cab <161495905+cabagbe@users.noreply.github.com> Co-authored-by: Devansh Tiwari <65783463+devloves@users.noreply.github.com>
This commit aims to fix a bug where the CakeDayService#addTodayMembersCakeDayRole() method would add the cake day role to all members who have been at least one year into the server, disregarding the month and date in which they joined. The documentation has also been made more clean and concise, while the CakeDayService#addCakeDayRole() which required a UserSnowflake as one of its inputs has been removed and now the other version of this function is used which only requires a Member instance. Passing the Guild would be unnecessary as it could be easily acquired from the Member instance, and additionally it helps make sure that the right Member and Guild are used to call this method. Finally, this commit adds an extra condition in the select-from query found in CakeDayService#findCakeDaysTodayFromDatabase() which makes sure that we get all the cake days for the right guild, instead of getting them all unconditionally.
079d68f
to
47b17b8
Compare
/** | ||
* Configuration constructor for the Cake Day feature. | ||
*/ | ||
public CakeDayConfig { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment really needed? It would maybe make sense if it links to the corresponding classes. Though even that should be done as some @see
in the records comment instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possible that we require javadoc on this one (public class). But yeah, we can add some details or a @see
.
* @param database the database for storing cake day information | ||
*/ | ||
public CakeDayService(Config config, Database database) { | ||
this.config = config.getCakeDayConfig(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really dont like the naming here. Both CakeDayConfig and Config variables are called config
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
id rename the parameter then though. dunno, i think for the pov of the class and where its being used in the methods it makes sense that config
is the config for this feature. so perhaps the parameter Config
can then be called fullConfig
or something instead here.
return; | ||
} | ||
|
||
refreshMembersCakeDayRoles(cakeDayRole.get(), guild); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could use Optional#ifPresent
here
boolean isAnniversaryDay = hasMemberCakeDayToday(member); | ||
int yearsSinceJoin = OffsetDateTime.now().getYear() - cakeDayRecord.getJoinedYear(); | ||
|
||
if (yearsSinceJoin > 0 && isAnniversaryDay) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm so this is confusing me a bit. hasMemberCakeDayToday
checks if today is the cake day using the Member member
which includes checking if the anniversary year is > 0
. This looks like checking the same thing twice (yearsSinceJoin
calculation uses the db record though). Also is the member query needed for this check? Doesn't the database also store the join date (make sure it is up2date though)? You would only need the member instance fo adding the role later on, so you could move that getMemberById
later in the chain and thus making it more efficient.
return; | ||
} | ||
|
||
guild.addRoleToMember(snowflake, cakeDayRole.get()).complete(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A member
is a UserSnowflake
, so it makes no sense that you get the snowflake from the member.
.where(CAKE_DAYS.JOINED_MONTH_DAY.eq(todayMonthDay)) | ||
.and(CAKE_DAYS.GUILD_ID.eq(guild.getIdLong())) | ||
.fetch()) | ||
.collect(Collectors.toList()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't database.read
already return a list?
.fetch()) | ||
.collect(Collectors.toList()) | ||
.stream() | ||
.findFirst(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You sure the .collect(...).stream().findFirst()
is really needed? Is there no other method to use here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if all u need is the first hit (or any hit, bc there is no sorting), best is to modify the query to only return that result on DB level and not everything. im pretty sure jooq has a method for that and i recall us using it somewhere already
* | ||
* @param cakeDayService an instance of the cake day service | ||
*/ | ||
public CakeDayRoutine(CakeDayService cakeDayService) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment seems pretty useless.
* | ||
* @param cakeDayService the {@link CakeDayService} to be used by this listener | ||
*/ | ||
public CakeDayListener(CakeDayService cakeDayService) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment seems pretty useless.
return; | ||
} | ||
|
||
cakeDayService.insertMemberCakeDayToDatabase(member, guildId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could use Optional#ifPresent
here.
I know that this is not a certain feature to be added, but I still wanted to experiment and see what I could come up with :)
Description
This pull request introduces the addition of the cake day feature to the server, allowing members to commemorate their annual membership anniversary with a unique "Cake day" role, with which they can celebrate within the community.
This feature uses the database and makes a
cake_days
table in order to store each member's joined date, as well the guild in which they joined (in case the bot ever gets to handle multiple guilds). The date stored in the database is split into two columns: the month and the day in one (joined_month_day
), and the year in an other (joined_year
). The reason the join date is split into these two columns is so that an index can be added for thejoined_month_day
column in order to make reading from the database faster. Therefore, it will be easier for the bot to find all cake days by the month and day, a search that would occur daily by this feature's routine.If the bot finds that the
cake_days
table has no records, then it attempts to populate the table from all members of all guilds in a separate thread with batched insert queries in order to optimize the table population task.Configuration changes
cakeDayConfig.rolePattern
role to give to members.
"Cake Day"
Diagram
TODO
0
, assign them the role and whatever cosmetic stuff necessary.Closes #1035.