![JAR search and dependency download from the Maven repository](/logo.png)
io.github.oliviercailloux.javagrade.utils.SendEmails Maven / Gradle / Ivy
The newest version!
package io.github.oliviercailloux.javagrade.utils;
import static com.google.common.base.Preconditions.checkState;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.math.Quantiles;
import com.google.common.math.Stats;
import io.github.oliviercailloux.email.EmailAddress;
import io.github.oliviercailloux.email.EmailAddressAndPersonal;
import io.github.oliviercailloux.git.github.model.GitHubUsername;
import io.github.oliviercailloux.grade.Exam;
import io.github.oliviercailloux.grade.Grade;
import io.github.oliviercailloux.grade.Mark;
import io.github.oliviercailloux.grade.MarksTree;
import io.github.oliviercailloux.grade.comm.Email;
import io.github.oliviercailloux.grade.comm.Emailer;
import io.github.oliviercailloux.grade.comm.EmailerDauphineHelper;
import io.github.oliviercailloux.grade.comm.GradesInEmails;
import io.github.oliviercailloux.grade.comm.json.JsonStudents;
import io.github.oliviercailloux.grade.format.HtmlGrades;
import io.github.oliviercailloux.grade.format.json.JsonSimpleGrade;
import io.github.oliviercailloux.jaris.collections.CollectionUtils;
import io.github.oliviercailloux.xml.XmlUtils;
import jakarta.mail.Folder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
public class SendEmails {
@SuppressWarnings("unused")
private static final Logger LOGGER = LoggerFactory.getLogger(SendEmails.class);
private static final Path WORK_DIR = Path.of("");
public static void main(String[] args) throws Exception {
// final String prefix = Colors.PREFIX + " second";
// final String prefix = CompCust.PREFIX;
// final String prefix = Strings.PREFIX + " second";
final String prefix = "";
// final String prefix = "Présentation";
final JsonStudents students =
JsonStudents.from(Files.readString(WORK_DIR.resolve("usernames.json")));
// final JsonObject jsonS =
// PrintableJsonObjectFactory.
// wrapRawString(Files.readString(WORK_DIR.resolve("usernames.json"))).asJsonObject();
// final StudentOnGitHubKnown studentsK =
// JsonStudentOnGitHubKnown.asStudentOnGitHubKnown(jsonS);
final Exam exam = JsonSimpleGrade.asExam(Files.readString(
WORK_DIR.resolve("grades" + (prefix.equals("") ? "" : " ") + prefix + ".json")));
final boolean allKnown = students.getInstitutionalStudentsByGitHubUsername().keySet()
.containsAll(exam.getUsernames());
checkState(allKnown, Sets.difference(exam.getUsernames(),
students.getInstitutionalStudentsByGitHubUsername().keySet()));
final ImmutableSet missing =
Sets.difference(students.getInstitutionalStudentsByGitHubUsername().keySet(),
exam.getUsernames()).immutableCopy();
if (!missing.isEmpty()) {
LOGGER.warn("Missing: {}.", missing);
}
final Mark defaultMark = Mark.given(0d, "GitHub repository not found");
final ImmutableMap marksByEmail = exam.getUsernames().stream().collect(ImmutableMap.toImmutableMap(
u -> students.getInstitutionalStudentsByGitHubUsername().get(u).getEmail(),
u -> exam.getUsernames().contains(u) ? exam.getGrade(u).toMarksTree() : defaultMark));
final ImmutableMap gradesByEmail = ImmutableMap
.copyOf(Maps.transformValues(marksByEmail, m -> Grade.given(exam.aggregator(), m)));
final ImmutableList points = gradesByEmail.values().stream().map(Grade::mark)
.map(Mark::getPoints).collect(ImmutableList.toImmutableList());
final Stats stats = Stats.of(points);
final Map quartiles = Quantiles.quartiles().indexes(1, 2, 3).compute(points);
try (GradesInEmails gradesInEmails = GradesInEmails.newInstance()) {
@SuppressWarnings("resource")
final Emailer emailer = gradesInEmails.getEmailer();
EmailerDauphineHelper.connect(emailer);
@SuppressWarnings("resource")
final Folder folder = emailer.getFolderReadWrite("Grades");
gradesInEmails.setFolder(folder);
final ImmutableSet addresses = gradesByEmail.keySet().stream()
.map(EmailAddressAndPersonal::getAddress).collect(ImmutableSet.toImmutableSet());
gradesInEmails.filterRecipients(addresses);
final String prefixOrFinal = prefix.equals("") ? "final" : prefix;
final ImmutableMap lastGrades =
gradesInEmails.getLastGrades(prefixOrFinal);
LOGGER.debug("Searching grades sent to {}, got those sent to {}.", addresses,
lastGrades.keySet());
// checkState(!lastGrades.isEmpty());
for (EmailAddressAndPersonal address : gradesByEmail.keySet()) {
if (!lastGrades.containsKey(address.getAddress())) {
LOGGER.info("Not found {} among {}.", address, lastGrades.keySet());
}
}
final Map gradesDiffering = gradesByEmail.entrySet().stream()
.filter(e -> isDiff(Optional.ofNullable(lastGrades.get(e.getKey().getAddress())),
e.getValue()))
// .filter(e -> !e.getKey().getPersonal().contains("…"))
.collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
for (EmailAddressAndPersonal address : gradesDiffering.keySet()) {
final Grade lastGrade = lastGrades.get(address.getAddress());
if (lastGrade == null) {
continue;
}
final Grade gradeFromJson = gradesByEmail.get(address);
// LOGGER.info("Diff {}: {} (before {}, after {}).", address, getDiff(lastGrade,
// gradeFromJson),
// lastGrade, gradeFromJson);
final double before = lastGrade.mark().getPoints();
final double after = gradeFromJson.mark().getPoints();
LOGGER.info("Diff {} (before {}, after {}).", address, before, after);
if (before > after) {
LOGGER.warn("Losing points.");
}
}
// final String json = JsonSimpleGrade.toJson(gradesByEmail);
final String title = "grades " + prefix + " sent";
// Files.writeString(Path.of(title + ".json"), json);
final ImmutableMap gradesByStr = CollectionUtils.transformKeys(lastGrades,
e -> students.getInstitutionalStudentsByEmail().get(e).getUsername());
final Document doc = HtmlGrades.asHtmlGrades(gradesByStr, title, 20d);
Files.writeString(Path.of(title + ".html"), XmlUtils.asString(doc));
final ImmutableSet emails = gradesDiffering
.entrySet().stream().map(e -> GradesInEmails.asEmail(getDestination(e.getKey()),
prefixOrFinal, e.getValue(), stats, quartiles))
.collect(ImmutableSet.toImmutableSet());
final Optional first = emails.stream().findFirst();
LOGGER.info("Prepared first doc (out of {}): {}, to {}.", emails.size(),
first.map(Email::getDocument).map(XmlUtils::asString), first.map(Email::getTo));
// LOGGER.info("Prepared {}.", effectiveEmails);
emailer.saveInto(folder);
// emailer.send(emails, EmailerDauphineHelper.FROM);
}
}
private static boolean isDiff(Optional lastGrade, Grade current) {
final boolean isSame =
current.toAggregator().equals(lastGrade.map(Grade::toAggregator).orElse(null))
&& current.toMarksTree().equals(lastGrade.map(Grade::toMarksTree).orElse(null));
return !isSame;
// return !DoubleMath.fuzzyEquals(lastGrade.map(IGrade::getPoints).orElse(-1d),
// current.getPoints(), 1e-8d);
}
private static EmailAddressAndPersonal getDestination(EmailAddressAndPersonal e) {
return e;
// return EmailAddressAndPersonal.given(EmailerDauphineHelper.FROM.getAddress().getAddress(),
// e.getPersonal());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy