Timers are started now and all commands should work fine now

Signed-off-by: Louis Vallat <louis@louis-vallat.xyz>
This commit is contained in:
Louis Vallat 2020-11-26 22:45:12 +01:00
parent 187c46e1f2
commit 167fa6a0eb
9 changed files with 172 additions and 26 deletions

View File

@ -20,10 +20,12 @@ public class App {
DBManager.initializeDatabase();
DiscordManager.login();
TimerManager.startAutoReimportTimer();
TimerManager.startAllTimersForStudents();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
logger.info("Received shut down signal. Bye!");
DiscordManager.logout();
TimerManager.stopAllTimersForStudents();
}));
DiscordManager.onDisconnect();

View File

@ -15,10 +15,13 @@ public class Desinscription extends Command {
public Mono<Void> execute(MessageCreateEvent event) {
return event.getMessage().getChannel().flatMap(channel -> {
if (event.getMessage().getAuthor().isEmpty() ||
!StudentManager.deleteFromSnowflake(event.getMessage().getAuthor().get().getId().asString()))
StudentManager.getStudentFromSnowflake(event.getMessage().getAuthor().get().getId().asString()) == null)
return channel.createMessage("On dirait que je ne t'ai pas dans ma base de données !");
if (!StudentManager.deleteFromSnowflake(event.getMessage().getAuthor().get().getId().asString()))
return channel.createMessage("Une erreur est survenue pendant la suppression de ton " +
"identifiant dans ma base... Réessaie plus tard !");
TimerManager.cancelStudentTimer(event.getMessage().getAuthor().get().getId().asString());
return channel.createMessage("C'est bon, tu n'es plus dans ma base de données ! :thumbs_up:");
return channel.createMessage("C'est bon, tu n'es plus dans ma base de données !");
}).then().onErrorResume(t -> fatalError(event, t));
}
}

View File

@ -11,6 +11,7 @@ import xyz.vallat.louis.managers.calendar.CalendarManager;
import xyz.vallat.louis.managers.database.EventManager;
import xyz.vallat.louis.managers.database.StudentManager;
import xyz.vallat.louis.managers.database.dao.Student;
import xyz.vallat.louis.timer.TimerManager;
import java.util.HashMap;
import java.util.List;
@ -33,18 +34,21 @@ public class Inscription extends Command {
Student studentFromDatabase = StudentManager.getStudentFromDatabase(Integer.parseInt(args[1]));
if (studentFromDatabase != null) return alreadyImported(event, studentFromDatabase);
return event.getMessage().getChannel().flatMap(messageChannel -> {
Snowflake snowflake = event.getMessage().getAuthor().isEmpty() ? null :
event.getMessage().getAuthor().get().getId();
Student student = new Student(snowflake == null ? null : snowflake.asString(), Integer.parseInt(args[1]));
if (event.getMessage().getAuthor().isEmpty())
return messageChannel.createMessage("Je ne peux pas t'importer, on dirait que tu n'existes pas!");
Snowflake snowflake = event.getMessage().getAuthor().get().getId();
Student student = new Student(snowflake.asString(), Integer.parseInt(args[1]));
List<VEvent> events = CalendarManager.getEventsFromResource(Integer.parseInt(args[1]));
Map<Student, List<VEvent>> studentListMap = new HashMap<>();
studentListMap.put(student, events);
int importedEvents = EventManager.importEvents(studentListMap);
if (importedEvents == 0) return messageChannel.createMessage(
"On dirait qu'il y a eu une erreur lors de l'importation. Es-tu sûr que c'est bien ton identifiant ADE ?");
else return messageChannel.createMessage("Hey, " +
(student.getSnowflake() == null ? "" : "<@!" + student.getSnowflake() + ">, ")
+ "tout est bon pour moi ! Je surveille maintenant tes " + importedEvents + " prochains évènements !");
Map<Student, List<VEvent>> studentListMap = new HashMap<>();
studentListMap.put(student, events);
int importedEvents = EventManager.importEvents(studentListMap);
if (importedEvents == 0) return messageChannel.createMessage(
"On dirait qu'il y a eu une erreur lors de l'importation. Es-tu sûr que c'est bien ton identifiant ADE ?");
else {
TimerManager.startEvents(snowflake.asString(), EventManager.getNextEventsFromStudent(student));
return messageChannel.createMessage("Hey <@!" + student.getSnowflake() + "> !"
+ " Tout est bon pour moi ! Je surveille maintenant tes " + importedEvents + " prochains évènements !");
}
}).then().onErrorResume(throwable -> fatalError(event, throwable));
}

View File

@ -20,7 +20,7 @@ public final class CalendarManager {
private static final Logger logger = LoggerFactory.getLogger(CalendarManager.class.getCanonicalName());
public static final Calendar TZ_UTC = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
public static final Calendar TZ = Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris"));
public static final Calendar TZ = Calendar.getInstance(TimeZone.getDefault());
private CalendarManager() {
}

View File

@ -4,10 +4,13 @@ import biweekly.component.VEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import xyz.vallat.louis.managers.calendar.CalendarManager;
import xyz.vallat.louis.managers.database.dao.Event;
import xyz.vallat.louis.managers.database.dao.Student;
import xyz.vallat.louis.timer.TimerManager;
import java.sql.*;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -21,6 +24,7 @@ public final class EventManager {
public static int reimportAllEvents() {
int importedEvents;
TimerManager.stopAllTimersForStudents();
try (Connection connection = DBManager.getConnection()) {
connection.setAutoCommit(false);
flushEvents(connection);
@ -32,6 +36,7 @@ public final class EventManager {
logger.error("No events were re-imported. Rolling back.");
connection.rollback();
} else {
logger.debug("'{}' events reimported, commiting.", importedEvents);
try {
connection.commit();
} catch (SQLException e) {
@ -39,9 +44,10 @@ public final class EventManager {
}
}
} catch (SQLException e) {
logger.error("SQLError:", e);
logger.error("SQLError while reimporting all events:", e);
return 0;
}
TimerManager.startAllTimersForStudents();
return importedEvents;
}
@ -76,6 +82,38 @@ public final class EventManager {
return importedEvents;
}
public static List<Event> getNextEventsFromStudent(Student s) {
logger.debug("Getting events from student '{}'.", s.getSnowflake());
String sql = "SELECT id, summary, start_event, end_event" +
" FROM events WHERE students_id = ? AND start_event >= NOW();";
List<Event> events = new ArrayList<>();
try (Connection connection = DBManager.getConnection()) {
try (PreparedStatement stmt = connection.prepareStatement(sql)) {
stmt.setInt(1, s.getId());
stmt.execute();
ResultSet rs = stmt.getResultSet();
while (rs.next())
events.add(new Event(rs.getString("summary"),
rs.getTimestamp("start_event", CalendarManager.TZ).toLocalDateTime(),
rs.getTimestamp("end_event", CalendarManager.TZ).toLocalDateTime())
.setId(rs.getInt("id")));
logger.debug("Student '{}' has {} events.", s.getSnowflake(), events.size());
}
} catch (SQLException e) {
logger.error("An SQLError happened:", e);
return new ArrayList<>();
}
return events;
}
public static Map<Student, List<Event>> getStudentEvents() {
logger.debug("Getting students events.");
Map<Student, List<Event>> studentsEvents = new HashMap<>();
for (Student s : StudentManager.getStudentsFromDatabase())
studentsEvents.put(s, getNextEventsFromStudent(s));
return studentsEvents;
}
private static int importEvent(Student student, VEvent event, Connection connection) throws SQLException {
String sql = "INSERT INTO events(students_id, summary, start_event, end_event) VALUES (?, ?, ?, ?);";
try (PreparedStatement stmt = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {

View File

@ -83,6 +83,25 @@ public final class StudentManager {
return studentList;
}
public static Student getStudentFromSnowflake(String snowflake) {
logger.debug("Getting student from snowflake '{}'.", snowflake);
try (Connection connection = DBManager.getConnection()) {
String sql = "SELECT id, snowflake, ade_resource FROM students WHERE snowflake = ?;";
try (PreparedStatement stmt = connection.prepareStatement(sql)) {
stmt.setString(1, snowflake);
stmt.execute();
if (stmt.getResultSet().next()) {
return new Student(stmt.getResultSet().getString("snowflake"),
stmt.getResultSet().getInt("ade_resource"))
.setId(stmt.getResultSet().getInt("id"));
}
}
} catch (SQLException e) {
logger.error("An SQLError happened while getting a student:", e);
}
return null;
}
public static boolean deleteFromSnowflake(String snowflake) {
logger.debug("Deleting student {}.", snowflake);
try (Connection connection = DBManager.getConnection()) {

View File

@ -0,0 +1,38 @@
package xyz.vallat.louis.managers.database.dao;
import java.time.LocalDateTime;
public class Event {
private final String summary;
private final LocalDateTime startEvent;
private final LocalDateTime endEvent;
private int id = 0;
public Event(String summary, LocalDateTime startEvent, LocalDateTime endEvent) {
this.summary = summary;
this.startEvent = startEvent;
this.endEvent = endEvent;
}
public int getId() {
return id;
}
public Event setId(int id) {
this.id = id;
return this;
}
public String getSummary() {
return summary;
}
public LocalDateTime getStartEvent() {
return startEvent;
}
public LocalDateTime getEndEvent() {
return endEvent;
}
}

View File

@ -1,12 +1,10 @@
package xyz.vallat.louis.managers.database.dao;
import discord4j.common.util.Snowflake;
public class Student {
private int id;
private final String snowflake;
private final int ade;
private int id;
public Student(String snowflake, int ade) {
this.snowflake = snowflake;

View File

@ -2,13 +2,21 @@ package xyz.vallat.louis.timer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import xyz.vallat.louis.managers.database.EventManager;
import xyz.vallat.louis.managers.database.dao.Event;
import xyz.vallat.louis.managers.database.dao.Student;
import xyz.vallat.louis.timer.tasks.AutoReimport;
import xyz.vallat.louis.timer.tasks.MessagePresence;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
public final class TimerManager {
private static final int[] months = {Calendar.JANUARY, Calendar.FEBRUARY, Calendar.MARCH, Calendar.APRIL,
Calendar.MAY, Calendar.JUNE, Calendar.JULY, Calendar.AUGUST, Calendar.SEPTEMBER, Calendar.OCTOBER,
Calendar.NOVEMBER, Calendar.DECEMBER};
private static final Logger logger = LoggerFactory.getLogger(TimerManager.class.getCanonicalName());
private static final Map<String, List<Timer>> studentsTimers = new HashMap<>();
@ -16,17 +24,12 @@ public final class TimerManager {
}
public static void cancelStudentTimer(String snowflake) {
List<Timer> timers = studentsTimers.remove(snowflake);
for (Timer t : timers) {
try {
t.cancel();
} catch (Exception e) {
logger.warn("Got exception while cancelling student's timer:", e);
}
}
logger.debug("Cancelling all events for student '{}'.", snowflake);
if (studentsTimers.containsKey(snowflake)) studentsTimers.remove(snowflake).forEach(Timer::cancel);
}
public static void startAutoReimportTimer() {
logger.debug("Setting up auto reimport timer.");
Calendar midday = Calendar.getInstance();
midday.set(Calendar.HOUR, 12);
midday.set(Calendar.MINUTE, 30);
@ -35,5 +38,46 @@ public final class TimerManager {
Timer reimportCron = new Timer();
reimportCron.schedule(new AutoReimport(), midday.getTime(),
TimeUnit.MILLISECONDS.convert(12, TimeUnit.HOURS));
String date = midday.getTime().toString();
logger.debug("Auto reimport timer set to run first on {}.", date);
}
public static void stopAllTimersForStudents() {
logger.debug("Stopping all timers for all students.");
for (Map.Entry<String, List<Timer>> entry : studentsTimers.entrySet()) {
logger.debug("Stopping all {} timers for student '{}'.", entry.getValue().size(), entry.getKey());
for (Timer t : entry.getValue()) t.cancel();
}
logger.debug("Done stopping all timers.");
}
public static int startEvents(String studentSnowflake, List<Event> events) {
int eventsStarted = 0;
for (Event e : events) {
LocalDateTime startTime = e.getStartEvent();
Calendar cal = Calendar.getInstance();
cal.set(startTime.getYear(), months[startTime.getMonthValue() - 1],
startTime.getDayOfMonth(), startTime.getHour(), startTime.getMinute());
cal.add(Calendar.MINUTE, 5);
Timer t = new Timer();
t.schedule(new MessagePresence(e.getSummary(), studentSnowflake), cal.getTime());
List<Timer> eventList = studentsTimers.getOrDefault(studentSnowflake, new ArrayList<>());
eventList.add(t);
studentsTimers.put(studentSnowflake, eventList);
eventsStarted++;
logger.debug("Starting event '{}' for student '{}' on {}.", e.getSummary(), studentSnowflake, startTime);
}
return eventsStarted;
}
public static void startAllTimersForStudents() {
studentsTimers.clear();
logger.debug("Starting all timers for students.");
int timerStarted = 0;
for (Map.Entry<Student, List<Event>> entry : EventManager.getStudentEvents().entrySet()) {
logger.debug("Starting events for student '{}'.", entry.getKey().getSnowflake());
timerStarted += startEvents(entry.getKey().getSnowflake(), entry.getValue());
}
logger.debug("All {} timers have been started.", timerStarted);
}
}