-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(core): Added DelayedTaskService and Remindme command (#105)
- Loading branch information
Seb
committed
Jun 7, 2022
1 parent
ca3c646
commit 1bce1a4
Showing
9 changed files
with
492 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package main.java.de.voidtech.gerald.annotations; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
@Target({ElementType.TYPE}) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface Task { | ||
|
||
} |
154 changes: 154 additions & 0 deletions
154
src/main/java/de/voidtech/gerald/commands/utils/RemindMeCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
package main.java.de.voidtech.gerald.commands.utils; | ||
|
||
import java.awt.Color; | ||
import java.time.Instant; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.context.event.ApplicationReadyEvent; | ||
import org.springframework.context.event.EventListener; | ||
|
||
import main.java.de.voidtech.gerald.annotations.Command; | ||
import main.java.de.voidtech.gerald.commands.AbstractCommand; | ||
import main.java.de.voidtech.gerald.commands.CommandCategory; | ||
import main.java.de.voidtech.gerald.commands.CommandContext; | ||
import main.java.de.voidtech.gerald.service.RemindMeService; | ||
import main.java.de.voidtech.gerald.util.ParsingUtils; | ||
import net.dv8tion.jda.api.EmbedBuilder; | ||
import net.dv8tion.jda.api.entities.MessageEmbed; | ||
|
||
@Command | ||
public class RemindMeCommand extends AbstractCommand { | ||
|
||
@Autowired | ||
private RemindMeService remindMeService; | ||
|
||
private static HashMap<String, Integer> TimeMultipliers = new HashMap<String, Integer>(); | ||
|
||
@EventListener(ApplicationReadyEvent.class) | ||
private void populateTimeMultipliers() { | ||
TimeMultipliers.put("w", Integer.valueOf(604800)); | ||
TimeMultipliers.put("d", Integer.valueOf(86400)); | ||
TimeMultipliers.put("h", Integer.valueOf(3600)); | ||
TimeMultipliers.put("m", Integer.valueOf(60)); | ||
TimeMultipliers.put("s", Integer.valueOf(1)); | ||
} | ||
|
||
@Override | ||
public void executeInternal(CommandContext context, List<String> args) { | ||
if (args.isEmpty()) showUserReminders(context); | ||
else { | ||
if (args.get(0).equals("delete")) deleteReminder(context, args); | ||
else createReminder(context, args); | ||
} | ||
} | ||
|
||
private void createReminder(CommandContext context, List<String> args) { | ||
if (args.size() == 1) { | ||
context.reply("**You need to specify a reminder message!**"); | ||
return; | ||
} | ||
|
||
String timeString = args.get(0); | ||
String message = String.join(" ", args.subList(1, args.size())); | ||
String timeMultiplier = timeString.substring(timeString.length() - 1, timeString.length()); | ||
|
||
if (!TimeMultipliers.containsKey(timeMultiplier)) { | ||
context.reply("**You need to enter a valid time multiplier!**"); | ||
return; | ||
} | ||
|
||
String timeOnly = timeString.replaceAll(timeMultiplier, ""); | ||
if (!ParsingUtils.isInteger(timeOnly)) { | ||
context.reply("**You need to enter a valid time quantity! (Must be a number)**"); | ||
return; | ||
} | ||
|
||
long timeValue = Integer.parseInt(timeOnly); | ||
if (timeValue < 1) { | ||
context.reply("**You need to specify a higher time value! (Must be at least 1)**"); | ||
return; | ||
} | ||
|
||
long multiplicationFactor = TimeMultipliers.get(timeMultiplier).longValue(); | ||
long time = (timeValue * multiplicationFactor) + Instant.now().getEpochSecond(); | ||
|
||
remindMeService.addReminder(context, message, time); | ||
context.reply("**Reminder added!**"); | ||
} | ||
|
||
private void deleteReminder(CommandContext context, List<String> args) { | ||
if (args.size() == 1) { | ||
context.reply("**You need to specify a reminder ID to delete! Use the** `reminders` **command to see your reminders!**"); | ||
return; | ||
} | ||
String ID = args.get(1); | ||
if (!ParsingUtils.isInteger(ID)) { | ||
context.reply("**Reminder ID must be a number!**"); | ||
return; | ||
} | ||
boolean taskDeleted = remindMeService.deleteReminder(context.getAuthor().getId(), Long.parseLong(ID)); | ||
context.reply(taskDeleted ? "**Reminder deleted!**" : "**No task with ID** `" + ID + "` **was found!**"); | ||
} | ||
|
||
private void showUserReminders(CommandContext context) { | ||
MessageEmbed remindersEmbed = new EmbedBuilder() | ||
.setColor(Color.ORANGE) | ||
.setTitle(context.getAuthor().getName() + "'s Reminders") | ||
.setDescription(remindMeService.getRemindersList(context)) | ||
.build(); | ||
context.reply(remindersEmbed); | ||
} | ||
|
||
@Override | ||
public String getDescription() { | ||
return "Need a reminder to do something in a little while? Or maybe you want to remind yourself of an event in a few weeks?" | ||
+ " This command is for you! Simply enter the time delay and a reminder message and you're set!\n\n" | ||
+ "Use w, d, h and m (months, weeks, days, hours, minutes) to set your time delay. Examples: 12d, 13m, 4w\n" | ||
+ "Please note that there should be no spaces between the quantity and time multiplier."; | ||
} | ||
|
||
@Override | ||
public String getUsage() { | ||
return "remindme (to see your reminders)\n" | ||
+ "remindme [time delay] [reminder message]\n" | ||
+ "remindme delete [reminder ID]"; | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return "remindme"; | ||
} | ||
|
||
@Override | ||
public CommandCategory getCommandCategory() { | ||
return CommandCategory.UTILS; | ||
} | ||
|
||
@Override | ||
public boolean isDMCapable() { | ||
return false; | ||
} | ||
|
||
@Override | ||
public boolean requiresArguments() { | ||
return false; | ||
} | ||
|
||
@Override | ||
public String[] getCommandAliases() { | ||
return new String[] {"reminder", "reminders"}; | ||
} | ||
|
||
@Override | ||
public boolean canBeDisabled() { | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean isSlashCompatible() { | ||
return true; | ||
} | ||
|
||
} |
74 changes: 74 additions & 0 deletions
74
src/main/java/de/voidtech/gerald/entities/DelayedTask.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package main.java.de.voidtech.gerald.entities; | ||
|
||
import javax.persistence.Column; | ||
import javax.persistence.Entity; | ||
import javax.persistence.GeneratedValue; | ||
import javax.persistence.GenerationType; | ||
import javax.persistence.Id; | ||
import javax.persistence.Table; | ||
|
||
import org.json.JSONObject; | ||
|
||
import main.java.de.voidtech.gerald.tasks.TaskType; | ||
|
||
@Entity | ||
@Table(name = "delayedtask") | ||
|
||
public class DelayedTask { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private long id; | ||
|
||
@Column | ||
private String args; | ||
|
||
@Column | ||
private String type; | ||
|
||
@Column | ||
private long time; | ||
|
||
@Column | ||
private String guildID; | ||
|
||
@Column | ||
private String userID; | ||
|
||
@Deprecated | ||
//ONLY FOR HIBERNATE, DO NOT USE | ||
DelayedTask() { | ||
} | ||
|
||
public DelayedTask(TaskType type, JSONObject args, String guildID, String userID, long time) { | ||
this.args = args.toString(); | ||
this.type = type.getType(); | ||
this.time = time; | ||
this.guildID = guildID; | ||
this.userID = userID; | ||
} | ||
|
||
public String getTaskType() { | ||
return this.type; | ||
} | ||
|
||
public long getExecutionTime() { | ||
return this.time; | ||
} | ||
|
||
public JSONObject getArgs() { | ||
return new JSONObject(this.args); | ||
} | ||
|
||
public long getTaskID() { | ||
return this.id; | ||
} | ||
|
||
public String getGuildID() { | ||
return this.guildID; | ||
} | ||
|
||
public String getUserID() { | ||
return this.userID; | ||
} | ||
} |
122 changes: 122 additions & 0 deletions
122
src/main/java/de/voidtech/gerald/service/DelayedTaskService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
package main.java.de.voidtech.gerald.service; | ||
|
||
import java.time.Instant; | ||
import java.util.List; | ||
import java.util.Timer; | ||
import java.util.TimerTask; | ||
import java.util.logging.Level; | ||
|
||
import org.hibernate.Session; | ||
import org.hibernate.SessionFactory; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.context.event.ApplicationReadyEvent; | ||
import org.springframework.context.annotation.Lazy; | ||
import org.springframework.context.event.EventListener; | ||
import org.springframework.stereotype.Service; | ||
|
||
import main.java.de.voidtech.gerald.entities.DelayedTask; | ||
import main.java.de.voidtech.gerald.entities.GeraldLogger; | ||
import main.java.de.voidtech.gerald.tasks.AbstractTask; | ||
import main.java.de.voidtech.gerald.tasks.TaskType; | ||
import net.dv8tion.jda.api.JDA; | ||
|
||
@Lazy | ||
@Service | ||
public class DelayedTaskService { | ||
|
||
@Autowired | ||
private SessionFactory sessionFactory; | ||
|
||
@Autowired | ||
private List<AbstractTask> abstractTasks; | ||
|
||
@Lazy | ||
@Autowired | ||
private JDA jda; | ||
|
||
//Time in milliseconds | ||
private static final int DELAYED_TASK_TIMER_INTERVAL = 10000; | ||
//Time in seconds | ||
private static final int UPCOMING_TASKS_TIME = 5; | ||
|
||
private static final GeraldLogger LOGGER = LogService.GetLogger(DelayedTaskService.class.getSimpleName()); | ||
|
||
@EventListener(ApplicationReadyEvent.class) | ||
private void startTimer() { | ||
TimerTask requestAllowanceIncrement = new TimerTask() { | ||
public void run() { | ||
Thread.currentThread().setName("Task Timer"); | ||
checkForTasks(); | ||
} | ||
}; | ||
|
||
Timer timer = new Timer(); | ||
timer.schedule(requestAllowanceIncrement, DELAYED_TASK_TIMER_INTERVAL, DELAYED_TASK_TIMER_INTERVAL); | ||
} | ||
|
||
private void checkForTasks() { | ||
long taskTimeThreshold = Instant.now().getEpochSecond() + UPCOMING_TASKS_TIME; | ||
List<DelayedTask> tasks = getUpcomingTasks(taskTimeThreshold); | ||
if (tasks.isEmpty()) return; | ||
for (DelayedTask task : tasks) { | ||
AbstractTask taskExecutor = abstractTasks.stream() | ||
.filter(t -> t.getTaskType().getType().equals(task.getTaskType())) | ||
.findFirst() | ||
.orElse(null); | ||
if (taskExecutor == null) LOGGER.log(Level.SEVERE, "Task with unknown type '" + task.getTaskType() + "' found"); | ||
else taskExecutor.execute(task.getArgs(), jda, task.getUserID(), task.getGuildID()); | ||
|
||
deleteTask(task); | ||
} | ||
} | ||
|
||
public void saveDelayedTask(DelayedTask task) { | ||
try(Session session = sessionFactory.openSession()) | ||
{ | ||
session.getTransaction().begin(); | ||
session.saveOrUpdate(task); | ||
session.getTransaction().commit(); | ||
} | ||
} | ||
|
||
public void deleteTask(DelayedTask task) { | ||
try(Session session = sessionFactory.openSession()) { | ||
session.getTransaction().begin(); | ||
session.createQuery("DELETE FROM DelayedTask WHERE id = :id") | ||
.setParameter("id", task.getTaskID()) | ||
.executeUpdate(); | ||
session.getTransaction().commit(); | ||
} | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
private List<DelayedTask> getUpcomingTasks(long taskTimeThreshold) { | ||
try(Session session = sessionFactory.openSession()) | ||
{ | ||
return session.createQuery("FROM DelayedTask WHERE time < :timeThreshold") | ||
.setParameter("timeThreshold", taskTimeThreshold) | ||
.list(); | ||
} | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
public List<DelayedTask> getUserTasksOfType(String userID, TaskType type) { | ||
try(Session session = sessionFactory.openSession()) | ||
{ | ||
return session.createQuery("FROM DelayedTask WHERE userID = :userID AND type = :type") | ||
.setParameter("userID", userID) | ||
.setParameter("type", type.getType()) | ||
.list(); | ||
} | ||
} | ||
|
||
public DelayedTask getTaskByID(long id) { | ||
try(Session session = sessionFactory.openSession()) | ||
{ | ||
return (DelayedTask) session.createQuery("FROM DelayedTask WHERE id = :id") | ||
.setParameter("id", id) | ||
.uniqueResult(); | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.