Release preparations

This commit is contained in:
ByteDream 2020-11-23 18:16:33 +01:00
parent 83ff5a98ac
commit dd883b71e2
2 changed files with 206 additions and 164 deletions

View File

@ -69,7 +69,7 @@ To set up the database, you have two options to choose from.
##### The short one:
```bash
mysql --user=<user> --password=<password> -e "CREATE DATABASE Untis;" && https://raw.githubusercontent.com/ByteDream/untisbot-discord/master/src/org/bytedream/untisbot/dockerfiles/database.sql | mysql --user=<user> --password=<password> Untis
mysql --user=<user> --password=<password> -e "CREATE DATABASE Untis;" && wget -qO- https://raw.githubusercontent.com/ByteDream/untisbot-discord/master/src/org/bytedream/untisbot/dockerfiles/database.sql | mysql --user=<user> --password=<password> Untis
```
Just copy this and replace `<user>` with the sql user which should manage the database and `<password>` with the user's password.

View File

@ -14,6 +14,7 @@ import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import org.bytedream.untis4j.LoginException;
import org.bytedream.untis4j.Session;
import org.bytedream.untis4j.responseObjects.Klassen;
import org.bytedream.untis4j.responseObjects.Teachers;
import org.bytedream.untis4j.responseObjects.TimeUnits;
import org.bytedream.untis4j.responseObjects.Timetable;
@ -32,10 +33,13 @@ import java.awt.*;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.SQLException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Adapter to handle all events
@ -52,6 +56,8 @@ public class DiscordCommandListener extends ListenerAdapter {
private final HashMap<Long, Timer> allTimetableChecker = new HashMap<>();
private final Logger logger = Main.getLogger();
private final HashMap<Long, LocalDateTime> dataUpdated = new HashMap<>();
/**
* Sets up the adapter
*
@ -79,6 +85,7 @@ public class DiscordCommandListener extends ListenerAdapter {
*/
public void runTimetableChecker(Guild guild) {
long guildId = guild.getIdLong();
String guildName = guild.getName();
Timer timer = new Timer();
Data.Guild data = guildDataConnector.get(guildId);
TimetableChecker timetableChecker;
@ -96,18 +103,18 @@ public class DiscordCommandListener extends ListenerAdapter {
timetableChecker = new TimetableChecker(data.getUsername(), data.getPassword(), data.getServer(), data.getSchool(), data.getKlasseId());
} catch (LoginException e) {
e.printStackTrace();
logger.warn(guild.getName() + " failed to login", e);
logger.warn(guildName + " failed to login", e);
textChannel.sendMessage("Failed to login. Please try to re-set your data").queue();
return;
} catch (IOException e) {
e.printStackTrace();
logger.warn(guild.getName() + " ran into an exception while trying to setup the timetable checker", e);
logger.warn(guildName + " ran into an exception while trying to setup the timetable checker", e);
textChannel.sendMessage("An error occurred while trying to setup the timetable checking process." +
"You should try to re-set your data or trying to contact my author <@650417934073593886> (:3) if the problem won't go away").queue();
return;
}
timer.scheduleAtFixedRate(new TimerTask() {
private int latestImportTime = 0;
private long latestImportTime = 0;
private void main() {
Data.Guild data = guildDataConnector.get(guildId);
@ -124,6 +131,7 @@ public class DiscordCommandListener extends ListenerAdapter {
}
}
boolean changes = false;
boolean error = false;
Data.Stats stats = statsDataConnector.get(guildId);
String setLanguage = data.getLanguage();
@ -147,6 +155,9 @@ public class DiscordCommandListener extends ListenerAdapter {
}
} catch (IOException e) {
e.printStackTrace();
} catch (ArrayIndexOutOfBoundsException e) {
i++;
daysToCheck++;
}
for (; i <= daysToCheck; i++) {
@ -154,6 +165,14 @@ public class DiscordCommandListener extends ListenerAdapter {
try {
CheckCallback checkCallback = timetableChecker.check(localDate);
ArrayList<Timetable.Lesson> cancelledLessons = checkCallback.getCancelled();
ArrayList<Timetable.Lesson[]> movedLessons = checkCallback.getMoved();
ArrayList<Timetable.Lesson> notCancelledLessons = checkCallback.getNotCancelled();
ArrayList<Timetable.Lesson[]> notMovedLessons = checkCallback.getNotMoved();
if (cancelledLessons.size() != 0 || movedLessons.size() != 0 || notCancelledLessons.size() != 0 || notMovedLessons.size() != 0) {
changes = true;
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setColor(Color.CYAN);
embedBuilder.setTitle(Utils.advancedFormat(language.getString("title"), new HashMap<String, Object>() {{
@ -161,11 +180,6 @@ public class DiscordCommandListener extends ListenerAdapter {
put("date", localDate.format(DateTimeFormatter.ofPattern("dd.MM.yyyy")));
}}));
ArrayList<Timetable.Lesson> cancelledLessons = checkCallback.getCancelled();
ArrayList<Timetable.Lesson[]> movedLessons = checkCallback.getMoved();
ArrayList<Timetable.Lesson> notCancelledLessons = checkCallback.getNotCancelled();
ArrayList<Timetable.Lesson[]> notMovedLessons = checkCallback.getNotMoved();
for (Timetable.Lesson lesson : cancelledLessons) {
TimeUnits.TimeUnitObject timeUnitObject = lesson.getTimeUnitObject();
HashMap<String, Object> formatMap = new HashMap<String, Object>() {{
@ -270,8 +284,9 @@ public class DiscordCommandListener extends ListenerAdapter {
if (error) {
error = false;
}
}
} catch (Exception e) {
logger.warn(guild.getName() + " ran into an exception while trying to check the timetable for the " + localDate.format(DateTimeFormatter.ofPattern("dd.MM.yyyy")), e);
logger.warn(guildName + " ran into an exception while trying to check the timetable for the " + localDate.format(DateTimeFormatter.ofPattern("dd.MM.yyyy")), e);
if (!error) {
textChannel.sendMessage("An error occurred while trying to check the timetable." +
"You can try to re-set your data or trying to contact my author <@650417934073593886> (:3) if the problem won't go away").queue();
@ -283,26 +298,40 @@ public class DiscordCommandListener extends ListenerAdapter {
}
}
}
String changesString = "no changes";
if (changes) {
changesString = "changes";
}
logger.info("Checked timetable for " + guildName + " - " + changesString);
}
@Override
public void run() {
Thread.currentThread().setName(guildName + "(" + guildId + ")");
try {
Session session = timetableChecker.getSession();
session.reconnect();
if (latestImportTime < session.getLatestImportTime().getLatestImportTime()) {
latestImportTime = session.getLatestImportTime().getLatestImportTime();
long sessionLatestImportTime = session.getLatestImportTime().getLatestImportTime();
if (latestImportTime < sessionLatestImportTime) {
latestImportTime = sessionLatestImportTime;
main();
} else {
main();
try {
Main.getConnection().createStatement().execute("SELECT * FROM Guilds WHERE GUILDID = 0");
// just execute this so that the connect won't have a timeout
} catch (SQLException ignore) {
}
}
} catch (IOException e) {
logger.info("Running main through IOException (" + e.getCause() + ")");
main();
}
}
}, 0, data.getSleepTime());
allTimetableChecker.put(guildId, timer);
logger.info(guild.getName() + " started timetable listening");
logger.info(guildName + " started timetable listening");
}
@Override
@ -334,7 +363,7 @@ public class DiscordCommandListener extends ListenerAdapter {
@Override
public void onGuildMessageReceived(GuildMessageReceivedEvent event) {
new Thread(() -> {
Thread t = new Thread(() -> {
long guildId = event.getGuild().getIdLong();
Data.Guild data = guildDataConnector.get(guildId);
try {
@ -433,7 +462,13 @@ public class DiscordCommandListener extends ListenerAdapter {
break;
case "data": // `data <username> <password> <server> <school name>` command
if (args.length >= 3 && args.length <= 4) {
if (dataUpdated.getOrDefault(guildId, LocalDateTime.MIN).plusMinutes(1).isAfter(LocalDateTime.now())) {
// this gives the server a little decay time and prevents additional load (because of the untis data encryption) caused by spamming
channel.sendMessage("The data was changed recently, try again in about one minute").queue();
} else {
dataUpdated.put(guildId, LocalDateTime.now());
String schoolName;
String className;
try {
schoolName = new URL(args[2]).getQuery().split("=")[1];
} catch (MalformedURLException | ArrayIndexOutOfBoundsException e) {
@ -448,9 +483,12 @@ public class DiscordCommandListener extends ListenerAdapter {
Session session = Session.login(args[0], args[1], server, schoolName);
if (args.length == 3) {
klasseId = (short) session.getInfos().getKlasseId();
className = session.getKlassen().findById(klasseId).getName();
} else {
try {
klasseId = (short) session.getKlassen().findByName(args[3]).getId();
Klassen.KlasseObject klasse = session.getKlassen().findByName(args[3]);
klasseId = (short) klasse.getId();
className = klasse.getName();
} catch (NullPointerException e) {
channel.sendMessage("❌ Cannot find the given class").queue();
return;
@ -472,16 +510,17 @@ public class DiscordCommandListener extends ListenerAdapter {
if (isCheckActive) {
Timer timer = allTimetableChecker.get(guildId);
allTimetableChecker.remove(guildId);
timer.cancel();
timer.purge();
allTimetableChecker.remove(guildId);
runTimetableChecker(guild);
channel.sendMessage("✅ Updated data and restarted timetable listening").queue();
channel.sendMessage("✅ Updated data and restarted timetable listening for class " + className).queue();
} else {
runTimetableChecker(guild);
channel.sendMessage("✅ Timetable listening has been started").queue();
channel.sendMessage("✅ Timetable listening has been started for class " + className).queue();
}
logger.info(guildName + " set new data");
}
} else {
channel.sendMessage("Wrong number of arguments were given (expected 3 or 4, got " + args.length + "), type `" + data.getPrefix() + "help data` for help").queue();
}
@ -535,12 +574,14 @@ public class DiscordCommandListener extends ListenerAdapter {
}
} catch (NullPointerException ignore) {
}
}).start();
});
t.setName("Guild message handler");
t.start();
}
@Override
public void onMessageReceived(@NotNull MessageReceivedEvent event) { // only for `help` command
new Thread(() -> {
public void onMessageReceived(@NotNull MessageReceivedEvent event) { // only for the `help` command
Thread t = new Thread(() -> {
if (event.getAuthor().isBot()) {
return;
}
@ -636,7 +677,8 @@ public class DiscordCommandListener extends ListenerAdapter {
embedBuilder.setFooter("`<>` = required; `[]` = optional");
channel.sendMessage(embedBuilder.build()).queue();
}
}).start();
});
t.setName("Message handler");
}
@Override