Skip to content

Commit

Permalink
Implement EMAIL stage
Browse files Browse the repository at this point in the history
  • Loading branch information
T0astBread committed Jul 24, 2020
1 parent 946542a commit 6cb7731
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 1 deletion.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ dependencies {
implementation 'net.lingala.zip4j:zip4j:2.6.1'
implementation 'org.junit.jupiter:junit-jupiter-engine:5.6.2'
implementation 'org.junit.platform:junit-platform-launcher:1.2.0'
implementation 'org.simplejavamail:simple-java-mail:6.4.0'
implementation 'com.sparkjava:spark-core:2.9.1' // web server for GUI
implementation 'org.slf4j:slf4j-simple:1.7.21' // logging for Spark
testCompile group: 'junit', name: 'junit', version: '4.12'
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/automark/io/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ public class Config {
public static final String MOODLE_TEACHERS = "moodleTeachers";
public static final String MOODLE_USERNAME = "moodleUsername";
public static final String SOURCE_FILES = "sourceFiles";
public static final String EMAIL_STAGE_ENABLED = "emailStageEnabled";
public static final String SMTP_HOST = "smtpHost";
public static final String SMTP_PORT = "smtpPort";
public static final String SMTP_USERNAME = "smtpUsername";
public static final String SMTP_PASSWORD = "smtpPassword";
public static final String SMTP_PROTOCOL = "smtpProtocol";
public static final String SMTP_FROM_NAME = "smtpFromName";
public static final String SMTP_FROM_ADDRESS = "smtpFromAddress";


public static Properties loadConfig(File workingDir) throws UserFriendlyException {
Expand Down Expand Up @@ -63,4 +71,12 @@ public static List<String> asList(String configProp) {
public static File asFile(String configProp) {
return new File(configProp);
}

public static int asInt(String configProp) {
return Integer.parseInt(configProp);
}

public static boolean asBoolean(String configProp) {
return Boolean.parseBoolean(configProp);
}
}
10 changes: 9 additions & 1 deletion src/main/java/automark/models/Stage.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
package automark.models;

public enum Stage {
DOWNLOAD, UNZIP, EXTRACT, JPLAG, PREPARE_COMPILE, COMPILE, TEST, SUMMARY;
DOWNLOAD,
UNZIP,
EXTRACT,
JPLAG,
PREPARE_COMPILE,
COMPILE,
TEST,
SUMMARY,
EMAIL,
}
87 changes: 87 additions & 0 deletions src/main/java/automark/stages/EmailStage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package automark.stages;

import automark.*;
import automark.io.*;
import automark.models.*;
import org.simplejavamail.api.email.*;
import org.simplejavamail.api.mailer.*;
import org.simplejavamail.api.mailer.config.*;
import org.simplejavamail.email.*;
import org.simplejavamail.mailer.*;

import java.io.*;
import java.util.*;

public class EmailStage {
public static List<Submission> run(File workingDir, Properties config, List<Submission> submissions, boolean enableInsecureDebugMechanisms) throws UserFriendlyException {

if (!"true".equalsIgnoreCase(config.getProperty(Config.EMAIL_STAGE_ENABLED))) {
System.out.println(Config.EMAIL_STAGE_ENABLED + " not set to \"true\" - not executing EMAIL stage");
return submissions;
}

// Set up SMTP parameters
final String smtpHost = config.getProperty(Config.SMTP_HOST);
if (smtpHost == null)
throw new UserFriendlyException(Config.SMTP_HOST + " config property must be set for EMAIL stage");

final String _smtpPort = config.getProperty(Config.SMTP_PORT);
final int smtpPort = _smtpPort == null ? 465 : Config.asInt(_smtpPort);

final String _smtpProtocol = config.getProperty(Config.SMTP_PROTOCOL);
final TransportStrategy transportStrategy = _smtpProtocol == null ? TransportStrategy.SMTPS : TransportStrategy.valueOf(_smtpProtocol);

String smtpUsername = config.getProperty(Config.SMTP_USERNAME);
if (smtpUsername == null)
smtpUsername = UI.prompt("SMTP username: ", false);

String smtpPassword = config.getProperty(Config.SMTP_PASSWORD);
if (smtpPassword == null)
smtpPassword = UI.prompt("SMTP password: ", true);

final String smtpFromAddress = config.getProperty(Config.SMTP_FROM_ADDRESS);
if (smtpFromAddress == null)
throw new UserFriendlyException(Config.SMTP_FROM_ADDRESS + " config property must be set for EMAIL stage");

final String smtpFromName = config.getProperty(Config.SMTP_FROM_NAME);
if (smtpFromName == null)
throw new UserFriendlyException(Config.SMTP_FROM_NAME + " config property must be set for EMAIL stage");

Mailer mailer = MailerBuilder
.withSMTPServer(smtpHost, smtpPort, smtpUsername, smtpPassword)
.withTransportStrategy(transportStrategy)
.verifyingServerIdentity(!enableInsecureDebugMechanisms)
.buildMailer();

File summaryDir = new File(Metadata.getDataDir(workingDir), "summary");
for (Submission submission : submissions) {
File submissionSummaryFile = new File(summaryDir, submission.getSlug() + ".txt");
try (BufferedReader reader = new BufferedReader(new FileReader(submissionSummaryFile))) {
String subject = reader.readLine().substring("Subject: ".length());
reader.readLine();

StringBuilder body = new StringBuilder();
while (true) {
String line = reader.readLine();
if (line == null) break;
body.append(line).append("\n");
}

Email email = EmailBuilder.startingBlank()
.from(smtpFromName, smtpFromAddress)
.to(submission.getStudentName(), submission.getStudentEmail())
.withSubject(subject)
.withPlainText(body.toString())
.buildEmail();

System.out.println("Sending mail to " + submission.getStudentEmail() + "...");
mailer.sendMail(email);
} catch (Exception e) {
submission.setDisqualified(true);
submission.addProblem(Problem.createException(Stage.EMAIL, e));
}
}

return submissions;
}
}
2 changes: 2 additions & 0 deletions src/main/java/automark/subcommands/Run.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ private static List<Submission> runStage(
return TestStage.run(workingDir, config, submissions);
case SUMMARY:
return SummaryStage.run(workingDir, config, submissions);
case EMAIL:
return EmailStage.run(workingDir, config, submissions, enableInsecureDebugMechanisms);
default:
throw new UserFriendlyException("Invalid state: Tried to execute a stage that isn't implemented: " + stage.name());
}
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/automark/gui/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const STAGES = [
{name: "COMPILE", niceName: "Compile"},
{name: "TEST", niceName: "Test"},
{name: "SUMMARY", niceName: "Summary"},
{name: "EMAIL", niceName: "Email"},
]

const STAGES_REVERSE = [...STAGES].reverse()
Expand Down

0 comments on commit 6cb7731

Please sign in to comment.