package gov.nysenate.openleg.service.spotcheck.daybreak; import gov.nysenate.openleg.model.spotcheck.daybreak.*; import gov.nysenate.openleg.service.spotcheck.base.BaseCheckMailService; import gov.nysenate.openleg.service.spotcheck.base.CheckMailService; import org.apache.commons.lang3.exception.ExceptionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import javax.mail.*; import java.io.File; import java.io.IOException; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import java.util.Map; @Service public class DaybreakCheckMailService extends BaseCheckMailService implements CheckMailService { private static final Logger logger = LoggerFactory.getLogger(DaybreakCheckMailService.class); private File daybreakStagingDir; @PostConstruct public void init() { daybreakStagingDir = new File(environment.getStagingDir(), "daybreak"); } /** * Checks an email server for incoming daybreak emails. * If a full set of daybreak emails is detected, the daybreak file attachments are saved as daybreak files * @return int - the number of reports saved */ public int checkMail() { Store store = null; int savedReports = 0; try { logger.info("checking for daybreak emails..."); store = mailUtils.getCheckMailStore(); Folder sourceFolder = mailUtils.navigateToFolder(environment.getEmailReceivingFolder(), store); Folder archiveFolder = mailUtils.navigateToFolder(environment.getEmailProcessedFolder(), store); sourceFolder.open(Folder.READ_WRITE); DaybreakReportSet<DaybreakMessage> reports = getReports(sourceFolder); Map<LocalDate, DaybreakReport<DaybreakMessage>> completeReports = reports.getCompleteReports(); Map<LocalDate, DaybreakReport<DaybreakMessage>> partialReports = reports.getPartialReports(); if (completeReports.size() > 0) { logger.info("{} complete daybreak reports found. Saving...", completeReports.size()); saveCompleteReports(completeReports, sourceFolder, archiveFolder); logger.info("Daybreak files saved."); savedReports = completeReports.size(); } if (partialReports.size() > 0) { logger.info("{} partial daybreak reports found.", partialReports.size()); } if (completeReports.size() == 0 && partialReports.size() == 0) { logger.info("No daybreak reports found"); } } catch (MessagingException | IOException ex) { logger.error("CheckMail Error\n{}", ExceptionUtils.getStackTrace(ex)); } finally { try { if (store != null) { store.close(); } } catch (MessagingException ignored) {} } return savedReports; } /** * --- Internal Methods --- */ /** * Extracts all valid daybreak messages from the given source folder * and places each of them in a report within the report set * * @param sourceFolder * @return * @throws MessagingException */ private DaybreakReportSet<DaybreakMessage> getReports(Folder sourceFolder) throws MessagingException { DaybreakReportSet<DaybreakMessage> reports = new DaybreakReportSet<>(); for (Message message : sourceFolder.getMessages()) { if (DaybreakDocType.getMessageDocType(message.getSubject()) != null) { reports.insertDaybreakDocument(new DaybreakMessage(message)); } } return reports; } private void saveCompleteReports(Map<LocalDate, DaybreakReport<DaybreakMessage>> completeReports, Folder sourceFolder, Folder archiveFolder) throws MessagingException, IOException { List<Message> toArchive = new ArrayList<>(); for (DaybreakReport<DaybreakMessage> report : completeReports.values()) { String prefix = report.getReportDate().format(DateTimeFormatter.ofPattern(DaybreakFile.reportDateMatchPattern)); for (DaybreakMessage daybreakMessage : report.getReportDocs().values()) { String filename = prefix + daybreakMessage.getDaybreakDocType().getLocalFileExt(); Message message = daybreakMessage.getMessage(); saveMessageAttachment(message, new File(daybreakStagingDir, filename)); toArchive.add(message); } } moveToArchive(sourceFolder, archiveFolder, toArchive.toArray(new Message[toArchive.size()])); } }