MissingIdentifier/src/main/java/Modules/Fold.java

252 lines
9.7 KiB
Java

package Modules;
import Controll.GuildController;
import Controll.SuperModule;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.GenericEvent;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Fold extends SuperModule{
private final Logger logger = LoggerFactory.getLogger(Fold.class);
public static final String COMMAND = "fold";
private static final int BYTE_LIMIT = 16 * 1024;
private static final int MAX_MESSAGE_LIMIT = 10;
private static final String teamSummary = "https://apps.foldingathome.org/daily_team_summary.txt",
userSummary = "https://apps.foldingathome.org/daily_user_summary.txt";
private String teamFile = "/home/bots/MissingIdentifier/MissingIdent/team_summary.txt",
userFile = "/home/bots/MissingIdentifier/MissingIdent/user_summary.txt";
public Fold(GuildController guildController){
super(COMMAND, guildController, null);
}
@Override
public String getCommand() {
return Fold.COMMAND;
}
@Override
public String getDescription() {
return "Get statistics for a team that partakes in https://foldingathome.org\n`fold -t TEAMNAME` teamname to be filtered\n`fold -u update` update statistics";
}
@Override
public void execute(GenericEvent genericEvent) {
if (!(genericEvent instanceof GuildMessageReceivedEvent)) return;
GuildMessageReceivedEvent event = (GuildMessageReceivedEvent) genericEvent;
if (!isCommand(event.getMessage()))
return;
logger.debug("Fold command triggered");
//VARS
Pattern teamPattern, userPattern;
Message msg = event.getChannel().sendMessage("Got it!").complete();
String teamInfo = null;
// Update Locale Files if parameter "u" is given
if (getParameter(event.getMessage().getContentRaw(), "u") != null)
msg = update(event, msg);
// Generate Pattern to look for decide if looking for ID or Name of Team fall back is null and will cause an error
if (getParameter(event.getMessage().getContentRaw(), "t") != null) {
String input = getParameter(event.getMessage().getContentRaw(), "t");
logger.info("looking for team: " + input);
teamPattern = Pattern.compile("(?m)^[0-9]+\\t" + input + "\\t[0-9]+\\t[0-9]+$");
} else if (getParameter(event.getMessage().getContentRaw(), "id") != null) {
String input = getParameter(event.getMessage().getContentRaw(), "id");
logger.info("looking for team: " + input);
teamPattern = Pattern.compile("(?m)^" + input + "\\t[^\\t]*\\t[0-9]+\\t[0-9]+$");
} else
return; // TODO error handling
//LOOK for Team
try (BufferedReader teamReader = Files.newBufferedReader(Paths.get(teamFile))) {
teamInfo = teamReader.readLine();
while (teamInfo != null) {
Matcher teamMatcher = teamPattern.matcher(teamInfo);
if (teamMatcher.find()) {
// Send quick info
msg = msg.editMessage(teamMatcher.group()).complete();
break;
}
teamInfo = teamReader.readLine();
}
} catch (IOException e) {
logger.error(e.toString());
}
if (teamInfo == null) {
msg.editMessage("No team with this Identifier found!").queue();
return;
}
// Look for users
try (BufferedReader userReader = Files.newBufferedReader(Paths.get(userFile))) {
// Like skringbuilder only for embeded messages
EmbedBuilder eb = new EmbedBuilder();
// Add Team info
eb.setTitle(teamInfo.split("\t")[1] + " [ " + teamInfo.split("\t")[0] + " ]"); // Team Name
eb.setDescription("Work Units done:\t" + teamInfo.split("\t")[3] + "\n" +
"Total Score:\t\t" + teamInfo.split("\t")[2]); // WUs and Score
eb.setTimestamp(new DateTime().toDate().toInstant());
userPattern = Pattern.compile("(?m)^[0-9a-zA-Z_]+\\t[0-9]+\\t[0-9]+\\t" + teamInfo.split("\t")[0] + "$");
String userInfo = userReader.readLine();
long userPosition = 0;
int messageCount = 0;
msg = msg.editMessage(teamInfo + "\n\nread 0 lines").complete();
while (userInfo != null) {
userPosition++;
Matcher userMatcher = userPattern.matcher(userInfo);
if (userMatcher.find()) {
eb.addField(userInfo.split("\t")[0], "Work Units:\t" + userInfo.split("\t")[2] + "\n" +
"Score:\t\t" + userInfo.split("\t")[1], true);
//msg = msg.editMessage(teamInfo + "\n\nread " + userPosition + " lines").complete();
// IF mesage is to long, rmeove last entry and split output
if (!eb.isValidLength()){
eb.getFields().remove(eb.getFields().size()-1);
msg.getChannel().sendMessage(eb.build()).complete();
eb = new EmbedBuilder();
messageCount++;
if(messageCount > MAX_MESSAGE_LIMIT){
msg.getChannel().sendMessage("To many entries! aborted to prevent spam!").queue();
return;
}
eb.addField(userInfo.split("\t")[0], "Work Units:\t" + userInfo.split("\t")[2] + "\n" +
"Score:\t\t" + userInfo.split("\t")[1], true);
}
}
if (userPosition % 250000 == 0)
msg = msg.editMessage(teamInfo + "\n\nread " + userPosition + " lines").complete();
userInfo = userReader.readLine();
}
//Send final result
msg.getChannel().sendMessage(eb.build()).complete();
msg.delete().queue();
} catch (IOException e) {
logger.error(e.toString());
}
}
private Message update(GuildMessageReceivedEvent event, Message msg) {
if(!checkForAdmin(event.getMember()))
{
// if the user that calls this function is not admin, here should be an interval check that interrupts if the files have recently been updated to mitigate abuse.
// admins should of course be able to call this any time.
// the date of the current files can be read from the first line of each file and needs to be parsed.
return msg; // if it's not done by an admin, just cancel out
}
logger.debug("Get new Statistic from Server");
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
// Activate the new trust manager
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
logger.error(e.toString());
}
byte buffer[] = new byte[BYTE_LIMIT];
int bytesRead;
try(
BufferedOutputStream teamOutput = new BufferedOutputStream(new FileOutputStream(teamFile, false));
BufferedInputStream teamInput = new BufferedInputStream(new URL(teamSummary).openStream())
) {
long i = 0;
while((bytesRead = teamInput.read(buffer, 0, BYTE_LIMIT)) != -1){
teamOutput.write(buffer, 0, bytesRead);
i+=bytesRead;
if (i % 50000 <= 200)
msg = msg.editMessage("Updating Teamstats, processed " + i + " Bytes").complete();
}
teamOutput.flush();
} catch (IOException e) {
logger.error(e.toString());
}
try(
BufferedOutputStream userOutput = new BufferedOutputStream(new FileOutputStream(userFile, false));
BufferedInputStream userInput = new BufferedInputStream(new URL(userSummary).openStream())
){
long i = 0;
while((bytesRead = userInput.read(buffer, 0, BYTE_LIMIT)) != -1){
userOutput.write(buffer, 0, bytesRead);
i+=bytesRead;
if (i % 50000 <= 200)
msg = msg.editMessage("Updating Userstats, processed " + i + " Bytes").complete();
}
userOutput.flush();
} catch (IOException e) {
logger.error(e.toString());
}
return msg.editMessage("done!").complete();
}
@Override
public String showSettings() {
return null;
}
}