diff --git a/pom.xml b/pom.xml index 42e7e37..836b360 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.midgardarmy bifrost - 0.0.1-SNAPSHOT + 1.2.0-SNAPSHOT 1.2.3 @@ -111,7 +111,19 @@ com.cronutils cron-utils - 7.0.0 + 7.0.4 + + + + org.quartz-scheduler + quartz + 2.2.1 + + + + org.quartz-scheduler + quartz-jobs + 2.2.1 diff --git a/src/main/java/net/zerofill/MainRunner.java b/src/main/java/net/zerofill/MainRunner.java index 1faf971..815a9c7 100644 --- a/src/main/java/net/zerofill/MainRunner.java +++ b/src/main/java/net/zerofill/MainRunner.java @@ -1,7 +1,10 @@ package net.zerofill; +import net.zerofill.cronrunner.CronRunner; import net.zerofill.utils.BotUtils; import net.zerofill.utils.ConfigUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import sx.blah.discord.api.IDiscordClient; import net.zerofill.utils.DataUtils; @@ -11,6 +14,8 @@ public class MainRunner { + private static final Logger logger = LoggerFactory.getLogger(MainRunner.class); + public static void main(String[] args){ String token; if(args.length != 1){ @@ -42,6 +47,8 @@ public static void main(String[] args){ }); client.login(); + CronRunner cr = new CronRunner(); + cr.run(); } } \ No newline at end of file diff --git a/src/main/java/net/zerofill/cronrunner/CronRunner.java b/src/main/java/net/zerofill/cronrunner/CronRunner.java new file mode 100644 index 0000000..71eae15 --- /dev/null +++ b/src/main/java/net/zerofill/cronrunner/CronRunner.java @@ -0,0 +1,98 @@ +package net.zerofill.cronrunner; + +import com.cronutils.model.definition.CronDefinitionBuilder; +import com.cronutils.model.time.ExecutionTime; +import com.cronutils.parser.CronParser; + +import net.zerofill.cronrunner.jobs.Reminder; +import net.zerofill.utils.ConfigUtils; +import net.zerofill.utils.DataUtils; +import org.quartz.CronExpression; +import org.quartz.CronScheduleBuilder; +import org.quartz.CronTrigger; +import org.quartz.JobDetail; +import org.quartz.ScheduleBuilder; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.SchedulerFactory; +import org.quartz.Trigger; +import org.quartz.impl.StdSchedulerFactory; +import org.quartz.spi.MutableTrigger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.Duration; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import static com.cronutils.model.CronType.QUARTZ; +import static org.quartz.CronScheduleBuilder.cronSchedule; +import static org.quartz.JobBuilder.newJob; +import static org.quartz.TriggerBuilder.newTrigger; + +public class CronRunner { + + private static final Logger logger = LoggerFactory.getLogger(CronRunner.class); + + private static List> events = DataUtils.getEvents(); + + private static List remindList = ConfigUtils.getList("reminder.ids"); + private static String remindBefore = ConfigUtils.getString("reminder.before"); + + private static CronParser parser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(QUARTZ)); + + public void run() { + try { + SchedulerFactory sf = new StdSchedulerFactory(); + Scheduler scheduler = sf.getScheduler(); + + for (Map event : events) { + if (remindList.contains(event.get("id").toString())) { + + ExecutionTime executionTime = ExecutionTime.forCron(parser.parse(event.get("schedule").toString())); + ZonedDateTime now = ZonedDateTime.now(); + Optional nextTime = executionTime.nextExecution(now); + Date execution = null; + + if (nextTime.isPresent()) { + execution = Date.from(nextTime.get().toInstant()); + } + + JobDetail job = newJob(Reminder.class).withIdentity(event.get("name").toString(), String.format("%s", event.get("id").toString())).build(); + Trigger trigger = newTrigger().withIdentity("trigger", String.format("event%s", event.get("id").toString())) + .startAt(execution).build(); + + Date ft = scheduler.scheduleJob(job, trigger); + logger.info(String.format("%s has been scheduled to run at: %s and repeat based on expression: %s", job.getKey(), ft, trigger.getStartTime())); + } + } + + scheduler.start(); + addShutdownHook(scheduler); + + } catch (SchedulerException se) { + logger.error(se.getLocalizedMessage()); + } + } + + private void addShutdownHook(Scheduler scheduler) { + Thread t = new Thread("Quartz Shutdown-Hook") { + @Override public void run() { + logger.info("Shutting down Quartz..."); + try { + scheduler.shutdown(); + } catch (SchedulerException e) { + logger.info( + "Error shutting down Quartz: " + e.getMessage(), e); + } + } + }; + Runtime.getRuntime().addShutdownHook(t); + } + + public CronRunner() {} +} diff --git a/src/main/java/net/zerofill/cronrunner/jobs/Reminder.java b/src/main/java/net/zerofill/cronrunner/jobs/Reminder.java new file mode 100644 index 0000000..2e1cd28 --- /dev/null +++ b/src/main/java/net/zerofill/cronrunner/jobs/Reminder.java @@ -0,0 +1,18 @@ +package net.zerofill.cronrunner.jobs; + +import net.zerofill.utils.BotUtils; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class Reminder implements Job { + + private static final Logger logger = LoggerFactory.getLogger(Reminder.class); + + public void execute(JobExecutionContext context) { + } + + public Reminder() {} +} diff --git a/src/main/java/net/zerofill/roster/Roster.java b/src/main/java/net/zerofill/roster/Roster.java index f1e48e0..8aee27f 100644 --- a/src/main/java/net/zerofill/roster/Roster.java +++ b/src/main/java/net/zerofill/roster/Roster.java @@ -68,7 +68,6 @@ protected static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT try (InputStreamReader isr = new InputStreamReader(in)) { GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, isr); - // Build flow and trigger user authorization request. flow = new GoogleAuthorizationCodeFlow.Builder( HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES) diff --git a/src/main/java/net/zerofill/utils/ConfigUtils.java b/src/main/java/net/zerofill/utils/ConfigUtils.java index ccf5140..80d1490 100644 --- a/src/main/java/net/zerofill/utils/ConfigUtils.java +++ b/src/main/java/net/zerofill/utils/ConfigUtils.java @@ -2,6 +2,8 @@ import java.io.IOException; import java.io.InputStream; +import java.util.Arrays; +import java.util.List; import java.util.Properties; import org.slf4j.Logger; @@ -43,6 +45,13 @@ public static String getString(String key) { return ConfigUtils.properties.getProperty(key); } + public static List getList(String key) { + if (ConfigUtils.properties.isEmpty()) { + init(); + } + return Arrays.asList(ConfigUtils.properties.getProperty(key).split(",")); + } + public static int getInt(String key) { if (ConfigUtils.properties.isEmpty()) { init(); diff --git a/src/main/java/net/zerofill/utils/DataUtils.java b/src/main/java/net/zerofill/utils/DataUtils.java index cd2304d..a69078d 100644 --- a/src/main/java/net/zerofill/utils/DataUtils.java +++ b/src/main/java/net/zerofill/utils/DataUtils.java @@ -111,14 +111,15 @@ public static Map> getItemsByIDs(List ids) for (int i = 0; i < ids.size(); i++) { selectPreparedStatement.setInt(i + 1, ids.get(i)); } - ResultSet rs = selectPreparedStatement.executeQuery(); - while (rs.next()) { - Map result = new HashMap<>(); - result.put("id", rs.getInt("id")); - result.put("name", rs.getString("name_japanese")); - result.put("aegisName", rs.getString("name_english")); - result.put("slots", rs.getInt("slots")); - results.put(rs.getInt("id"), result); + try (ResultSet rs = selectPreparedStatement.executeQuery()) { + while (rs.next()) { + Map result = new HashMap<>(); + result.put("id", rs.getInt("id")); + result.put("name", rs.getString("name_japanese")); + result.put("aegisName", rs.getString("name_english")); + result.put("slots", rs.getInt("slots")); + results.put(rs.getInt("id"), result); + } } } catch (SQLException e) { if (logger.isDebugEnabled()) { @@ -145,9 +146,10 @@ public static List getMobIDsByName(String name) { selectPreparedStatement.setString(1, String.format("%%%s%%", name.toLowerCase())); selectPreparedStatement.setString(2, String.format("%%%s%%", name.toLowerCase())); - ResultSet rs = selectPreparedStatement.executeQuery(); - while (rs.next()) { - results.add(rs.getInt("ID")); + try (ResultSet rs = selectPreparedStatement.executeQuery()) { + while (rs.next()) { + results.add(rs.getInt("ID")); + } } } catch (SQLException e) { if (logger.isDebugEnabled()) { @@ -171,16 +173,17 @@ public static List> getEvents() { try { selectPreparedStatement = conn.prepareStatement(selectQuery.toString()); - ResultSet rs = selectPreparedStatement.executeQuery(); - while (rs.next()) { - Map result = new HashMap<>(); - result.put("id", rs.getInt("id")); - result.put("name", rs.getString("name")); - result.put("schedule", rs.getString("schedule")); - result.put("start", rs.getTimestamp("start")); - result.put("end", rs.getTimestamp("end")); - result.put("duration", rs.getLong("duration")); - results.add(result); + try (ResultSet rs = selectPreparedStatement.executeQuery()) { + while (rs.next()) { + Map result = new HashMap<>(); + result.put("id", rs.getInt("id")); + result.put("name", rs.getString("name")); + result.put("schedule", rs.getString("schedule")); + result.put("start", rs.getTimestamp("start")); + result.put("end", rs.getTimestamp("end")); + result.put("duration", rs.getLong("duration")); + results.add(result); + } } } catch (SQLException e) { if (logger.isDebugEnabled()) { diff --git a/src/main/resources/application.properties.example b/src/main/resources/application.properties.example index 0f2b365..ec6d6cb 100644 --- a/src/main/resources/application.properties.example +++ b/src/main/resources/application.properties.example @@ -62,4 +62,17 @@ shivtr.pass= # Bifrost Config # ################## bifrost.python= -bifrost.mvpbot.location= \ No newline at end of file +bifrost.mvpbot.location= + +################### +# Reminder Config # +################### +reminder.ids= +reminder.before= + +#################### +# Quartz Scheduler # +#################### +org.quartz.scheduler.instanceName=MyScheduler +org.quartz.threadPool.threadCount=3 +org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore