Skip to content

Commit

Permalink
docs: add JavaDocs
Browse files Browse the repository at this point in the history
  • Loading branch information
christolis committed Mar 3, 2024
1 parent 8d73932 commit 60b2118
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import com.fasterxml.jackson.annotation.JsonProperty;

/**
* Configuration record for the Cake Day feature.
*/
public record CakeDayConfig(
@JsonProperty(value = "rolePattern", required = true) String rolePattern) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,11 @@ public String getSelectRolesChannelPattern() {
return selectRolesChannelPattern;
}

// TODO: Add JavaDoc
/**
* Retrieves the Cake Day configuration.
*
* @return the cake-day feature configuration
*/
public CakeDayConfig getCakeDayConfig() {
return cakeDayConfig;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@

import static org.togetherjava.tjbot.db.generated.tables.CakeDays.CAKE_DAYS;

/**
* Represents a routine for managing cake day celebrations.
* <p>
* This routine handles the assignment and removal of a designated cake day role to guild members
* based on their anniversary of joining the guild.
*/
public class CakeDayRoutine implements Routine {

private static final Logger logger = LoggerFactory.getLogger(CakeDayRoutine.class);
Expand All @@ -39,31 +45,24 @@ public class CakeDayRoutine implements Routine {
private final CakeDayConfig config;
private final Database database;

/**
* Constructs a new {@link CakeDayRoutine} instance.
*
* @param config the configuration for cake day routines
* @param database the database for accessing cake day data
*/
public CakeDayRoutine(Config config, Database database) {
this.config = config.getCakeDayConfig();
this.database = database;

this.cakeDayRolePredicate = Pattern.compile(this.config.rolePattern()).asPredicate();
}

/**
* Retrieves the schedule of this routine. Called by the core system once during the startup in
* order to execute the routine accordingly.
* <p>
* Changes on the schedule returned by this method afterwards will not be picked up.
*
* @return the schedule of this routine
*/
@Override
public Schedule createSchedule() {
return new Schedule(ScheduleMode.FIXED_RATE, 0, 1, TimeUnit.DAYS);
}

/**
* Triggered by the core system on the schedule defined by {@link #createSchedule()}.
*
* @param jda the JDA instance the bot is operating with
*/
@Override
public void runRoutine(JDA jda) {
if (getCakeDayCount(this.database) == 0) {
Expand All @@ -89,6 +88,14 @@ public void runRoutine(JDA jda) {
jda.getGuilds().forEach(this::reassignCakeDayRole);
}

/**
* Reassigns the cake day role for all members of the given guild.
* <p>
* If the cake day role is not found based on the configured pattern, a warning message is
* logged, and no action is taken.
*
* @param guild the guild for which to reassign the cake day role
*/
private void reassignCakeDayRole(Guild guild) {
Role cakeDayRole = getCakeDayRoleFromGuild(guild).orElse(null);

Expand All @@ -103,6 +110,16 @@ private void reassignCakeDayRole(Guild guild) {
.join();
}

/**
* Asynchronously adds the specified cake day role to guild members who are celebrating their
* cake day today.
* <p>
* The cake day role is added to members who have been in the guild for at least one year.
*
* @param cakeDayRole the cake day role to add to qualifying members
* @param guild the guild in which to add the cake day role to members
* @return a {@link CompletableFuture} representing the asynchronous operation
*/
private CompletableFuture<Void> addTodayMembersCakeDayRole(Role cakeDayRole, Guild guild) {
return CompletableFuture
.runAsync(() -> findCakeDaysTodayFromDatabase().forEach(cakeDayRecord -> {
Expand All @@ -115,26 +132,67 @@ private CompletableFuture<Void> addTodayMembersCakeDayRole(Role cakeDayRole, Gui
}));
}

/**
* Removes the specified cake day role from all members who possess it in the given guild
* asynchronously.
*
* @param cakeDayRole The cake day role to be removed from members.
* @param guild The guild from which to remove the cake day role.
* @return A CompletableFuture representing the asynchronous operation.
*/
private CompletableFuture<Void> removeMembersCakeDayRole(Role cakeDayRole, Guild guild) {
return CompletableFuture.runAsync(() -> guild.findMembersWithRoles(cakeDayRole)
.onSuccess(members -> removeRoleFromMembers(guild, cakeDayRole, members)));
}


/**
* Removes a specified role from a list of members in a guild.
*
* @param guild the guild from which to remove the role from members
* @param role the role to be removed from the members
* @param members the list of members from which the role will be removed
*/
private void removeRoleFromMembers(Guild guild, Role role, List<Member> members) {
members.forEach(member -> {
UserSnowflake snowflake = UserSnowflake.fromId(member.getIdLong());
guild.removeRoleFromMember(snowflake, role).complete();
});
}

/**
* Retrieves the count of cake days from the provided database.
* <p>
* This uses the table <b>cake_days</b> to find the answer.
*
* @param database the database from which to retrieve the count of cake days
* @return the count of cake days stored in the database
*/
private int getCakeDayCount(Database database) {
return database.read(context -> context.fetchCount(CAKE_DAYS));
}

/**
* Populates cake days for all guilds in the provided JDA instance.
* <p>
* This method iterates through all guilds in the provided JDA instance and populates cake days
* for each guild. It is primarily used for batch populating the <b>cake_days</b> table once it
* is found to be empty.
*
* @param jda the JDA instance containing the guilds to populate cake days for
*/
private void populateAllGuildCakeDays(JDA jda) {
jda.getGuilds().forEach(this::batchPopulateGuildCakeDays);
}

/**
* Batch populates guild cake days for the given guild.
* <p>
* Uses a buffer for all the queries it makes and its size is determined by the
* {@code BULK_INSERT_SIZE} option.
*
* @param guild the guild for which to populate cake days
*/
private void batchPopulateGuildCakeDays(Guild guild) {
final List<Query> queriesBuffer = new ArrayList<>();

Expand All @@ -155,6 +213,18 @@ private void batchPopulateGuildCakeDays(Guild guild) {
}
}

/**
* Creates a query to insert a member's cake day information into the database.
* <p>
* Primarily used for manually constructing queries for members' cake days which are called from
* {@link CakeDayRoutine#batchPopulateGuildCakeDays(Guild)} and added in a batch to be sent to
* the database.
*
* @param member the member whose cake day information is to be inserted
* @param guildId the ID of the guild to which the member belongs
* @return an Optional containing the query to insert cake day information if the member has a
* join time; empty Optional otherwise
*/
private Optional<Query> createMemberCakeDayQuery(Member member, long guildId) {
if (!member.hasTimeJoined()) {
return Optional.empty();
Expand All @@ -170,13 +240,24 @@ private Optional<Query> createMemberCakeDayQuery(Member member, long guildId) {
.set(CAKE_DAYS.USER_ID, member.getIdLong()));
}

/**
* Retrieves the cake day {@link Role} from the specified guild.
*
* @param guild the guild from which to retrieve the cake day role
* @return an optional containing the cake day role if found, otherwise empty
*/
private Optional<Role> getCakeDayRoleFromGuild(Guild guild) {
return guild.getRoles()
.stream()
.filter(role -> cakeDayRolePredicate.test(role.getName()))
.findFirst();
}

/**
* Finds cake days records for today from the database.
*
* @return a list of {@link CakeDaysRecord} objects representing cake days for today
*/
private List<CakeDaysRecord> findCakeDaysTodayFromDatabase() {
String todayMonthDay = OffsetDateTime.now().format(MONTH_DAY_FORMATTER);

Expand Down

0 comments on commit 60b2118

Please sign in to comment.