add flow + steps + steps impl

master
io42630 1 year ago
parent f2c4dde8bc
commit 7cc5658c89

@ -0,0 +1,23 @@
package com.olexyn.burnsmail.flow;
import com.olexyn.burnsmail.flow.action.Action;
import com.olexyn.burnsmail.flow.cleanup.Cleanup;
import com.olexyn.burnsmail.flow.filter.FilterAMail;
import com.olexyn.burnsmail.flow.map.ToAMailMapper;
import com.olexyn.burnsmail.flow.search.SearchFolder;
import com.olexyn.burnsmail.flow.transform.TransformAMail;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Flow {
private SearchFolder searchFolder;
private ToAMailMapper toAMailMapper;
private FilterAMail filterAMail;
private TransformAMail transformAMail;
private Action action;
private Cleanup cleanup;
}

@ -0,0 +1,15 @@
package com.olexyn.burnsmail.flow.action;
import com.olexyn.burnsmail.model.AMail;
import javax.mail.Store;
/**
* The first step in the flow.
*/
public interface Action {
void execute(AMail aMail, Store store);
}

@ -0,0 +1,40 @@
package com.olexyn.burnsmail.flow.action;
import com.olexyn.burnsmail.MiscU;
import com.olexyn.burnsmail.model.AMail;
import com.olexyn.min.log.LogU;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Store;
public class CopyToDst implements Action {
private final String src;
private final String dst;
private Folder srcF;
private Folder dstF;
public CopyToDst(String src, String dst) {
this.src = src;
this.dst = dst;
}
@Override
public void execute(AMail aMail, Store store) {
try {
if (srcF == null) {
srcF = MiscU.open(store, src);
}
if (dstF == null) {
dstF = MiscU.open(store, dst);
}
srcF.copyMessages(new Message[]{aMail.getImapMessage()}, dstF);
aMail.getImapMessage().setFlag(Flags.Flag.DELETED, true);
} catch (MessagingException e) {
LogU.warnPlain("Could not copy mail." + e.getMessage());
}
}
}

@ -0,0 +1,8 @@
package com.olexyn.burnsmail.flow.cleanup;
import javax.mail.Store;
public interface Cleanup {
void cleanUp(Store store);
}

@ -0,0 +1,41 @@
package com.olexyn.burnsmail.flow.cleanup;
import com.olexyn.burnsmail.MiscU;
import com.olexyn.min.log.LogU;
import javax.mail.Folder;
import javax.mail.MessagingException;
import javax.mail.Store;
import java.util.HashMap;
import java.util.Map;
public class FlushFolders implements Cleanup {
private Map<String, Folder> folders = new HashMap<>();
public FlushFolders(String... folders) {
for (String folder : folders) {
this.folders.put(folder, null);
}
}
@Override
public void cleanUp(Store store) {
for (var entry : folders.entrySet()) {
String src = entry.getKey();
Folder srcF = entry.getValue();
try {
if (srcF == null) {
srcF = MiscU.open(store, src);
}
srcF.exists();
srcF.close(false);
} catch (MessagingException e) {
LogU.warnPlain("Could not flush folder " + src + " " + e.getMessage());
}
}
}
}

@ -0,0 +1,25 @@
package com.olexyn.burnsmail.flow.filter;
import com.olexyn.burnsmail.model.AMail;
import lombok.AllArgsConstructor;
import java.util.List;
@AllArgsConstructor
public class AnyFromContains implements FilterAMail {
private final List<String> froms;
public AnyFromContains(String... froms) {
this.froms = List.of(froms);
}
@Override
public boolean doKeep(AMail aMail) {
if (aMail != null && aMail.getSubject() != null) {
return froms.contains(aMail.getFrom());
}
return false;
}
}

@ -0,0 +1,25 @@
package com.olexyn.burnsmail.flow.filter;
import com.olexyn.burnsmail.model.AMail;
import lombok.AllArgsConstructor;
import java.util.List;
@AllArgsConstructor
public class AnySubjectContains implements FilterAMail {
private final List<String> subjects;
public AnySubjectContains(String... subjects) {
this.subjects = List.of(subjects);
}
@Override
public boolean doKeep(AMail aMail) {
if (aMail != null && aMail.getSubject() != null) {
return subjects.contains(aMail.getSubject());
}
return false;
}
}

@ -0,0 +1,12 @@
package com.olexyn.burnsmail.flow.filter;
import com.olexyn.burnsmail.model.AMail;
public interface FilterAMail {
boolean doKeep(AMail aMail);
}

@ -0,0 +1,16 @@
package com.olexyn.burnsmail.flow.filter;
import com.olexyn.burnsmail.model.AMail;
public class NoFilter implements FilterAMail {
@Override
public boolean doKeep(AMail aMail) {
return true;
}
}

@ -0,0 +1,41 @@
package com.olexyn.burnsmail.flow.map;
import com.olexyn.burnsmail.model.AMail;
import com.olexyn.min.log.LogU;
import org.jsoup.Jsoup;
import javax.mail.Message;
import javax.mail.internet.MimeMultipart;
import java.io.ByteArrayOutputStream;
import java.util.Optional;
import static java.nio.charset.StandardCharsets.UTF_8;
public class FullToAMailMapper implements ToAMailMapper {
@Override
public AMail map(Message message) {
var aMail = new LazyToAMailMapper().map(message);
if (aMail == null) {
return null;
}
var imapMessage = aMail.getImapMessage();
try {
var imapContent = imapMessage.getContent();
String htmlContent = null;
if (imapContent instanceof String str) {
htmlContent = str;
} else if (imapContent instanceof MimeMultipart multi) {
var out = new ByteArrayOutputStream();
multi.writeTo(out);
htmlContent = out.toString(UTF_8);
}
htmlContent = Optional.ofNullable(htmlContent).orElse("");
aMail.setContent(Jsoup.parse(htmlContent).text());
} catch (Exception e) {
LogU.warnPlain("Could not parse." + e.getMessage());
return null;
}
return aMail;
}
}

@ -0,0 +1,35 @@
package com.olexyn.burnsmail.flow.map;
import com.olexyn.burnsmail.model.AMail;
import com.sun.mail.imap.IMAPMessage;
import javax.mail.Message;
import static com.olexyn.burnsmail.MiscU.extractEmail;
public class LazyToAMailMapper implements ToAMailMapper {
@Override
public AMail map(Message message) {
if (!(message instanceof IMAPMessage imapMessage)) {
return null;
}
var aMail = new AMail();
aMail.setImapMessage(imapMessage);
try {
if (imapMessage.getFrom() != null && imapMessage.getFrom().length > 0) {
var rawFrom = imapMessage.getFrom()[0].toString();
aMail.setFrom(extractEmail(rawFrom));
}
if (imapMessage.getAllRecipients() != null && imapMessage.getAllRecipients().length > 0) {
var rawTo = imapMessage.getAllRecipients()[0].toString();
aMail.setTo(extractEmail(rawTo));
}
aMail.setSubject(imapMessage.getSubject());
} catch (Exception e) {
return null;
}
return aMail;
}
}

@ -0,0 +1,16 @@
package com.olexyn.burnsmail.flow.map;
import com.olexyn.burnsmail.model.AMail;
import org.jetbrains.annotations.Nullable;
import javax.mail.Message;
@FunctionalInterface
public interface ToAMailMapper {
@Nullable
AMail map(Message message);
}

@ -0,0 +1,31 @@
package com.olexyn.burnsmail.flow.search;
import com.olexyn.burnsmail.MiscU;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Store;
public class FetchAll implements SearchFolder {
private final String src;
private Folder srcF;
public FetchAll(String src) {
this.src = src;
}
@Override
public Message[] search(Store store) {
try {
if (srcF == null) {
srcF = MiscU.open(store, src);
}
return srcF.getMessages();
} catch (Exception e) {
return new Message[0];
}
}
}

@ -0,0 +1,40 @@
package com.olexyn.burnsmail.flow.search;
import com.olexyn.burnsmail.MiscU;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Store;
import javax.mail.search.OrTerm;
import javax.mail.search.SearchTerm;
import javax.mail.search.SubjectTerm;
import java.util.Arrays;
public class SearchAnySubject implements SearchFolder {
private final String src;
private Folder srcF;
private final SearchTerm searchTerm;
public SearchAnySubject(String src, String... subjects) {
this.src = src;
var subjectTerms = Arrays.stream(subjects)
.map(SubjectTerm::new)
.toArray(SubjectTerm[]::new);
this.searchTerm = new OrTerm(subjectTerms);
}
@Override
public Message[] search(Store store) {
try {
if (srcF == null) {
srcF = MiscU.open(store, src);
}
return srcF.search(searchTerm);
} catch (Exception e) {
return new Message[0];
}
}
}

@ -0,0 +1,14 @@
package com.olexyn.burnsmail.flow.search;
import javax.mail.Message;
import javax.mail.Store;
/**
* The first step in the flow.
*/
public interface SearchFolder {
Message[] search(Store store);
}

@ -0,0 +1,23 @@
package com.olexyn.burnsmail.flow.transform;
import com.olexyn.burnsmail.model.AMail;
import com.olexyn.burnsmail.openai.OpenAiAMailClassifier;
import static com.olexyn.burnsmail.model.ClassifyCategory.SPAM;
public class SetOpenAiScore implements TransformAMail {
private final OpenAiAMailClassifier openAiAMailClassifier;
public SetOpenAiScore(OpenAiAMailClassifier openAiAMailClassifier) {
this.openAiAMailClassifier = openAiAMailClassifier;
}
@Override
public AMail transform(AMail aMail) {
aMail.setSpamScore(openAiAMailClassifier.classifyAMail(aMail, SPAM));
return aMail;
}
}

@ -0,0 +1,12 @@
package com.olexyn.burnsmail.flow.transform;
import com.olexyn.burnsmail.model.AMail;
public interface TransformAMail {
AMail transform(AMail aMail);
}
Loading…
Cancel
Save