diff --git a/pom.xml b/pom.xml index f7b6bbf..75edd14 100644 --- a/pom.xml +++ b/pom.xml @@ -255,7 +255,7 @@ --pinentry-mode loopback - true + false diff --git a/src/main/java/utils/email/EmailUtilities.java b/src/main/java/utils/email/EmailUtilities.java index a244d0c..0b730f5 100644 --- a/src/main/java/utils/email/EmailUtilities.java +++ b/src/main/java/utils/email/EmailUtilities.java @@ -6,6 +6,8 @@ import jakarta.mail.internet.*; import utils.DateUtilities; import utils.Printer; +import utils.StringUtilities; +import utils.email.mapping.EmailFlag; import utils.reflection.ReflectionUtilities; import java.io.FileWriter; @@ -13,6 +15,7 @@ import java.io.File; import java.util.*; +import static utils.StringUtilities.markup; import static utils.arrays.lambda.Collectors.toSingleton; @SuppressWarnings({"unused", "UnusedReturnValue"}) @@ -375,22 +378,8 @@ public void load(EmailField filterType, String filterKey, boolean print, boolean * @param filterPairs a list of pairs consisting of email fields and corresponding filter strings */ public void load(boolean print, boolean save, boolean saveAttachments, List> filterPairs) { - Properties properties = new Properties(); - - //---------- Server Setting--------------- - properties.put("mail.pop3.host", host); - properties.put("mail.pop3.port", port); - if (secureCon.equalsIgnoreCase("ssl")) { - properties.put("mail.smtp.ssl.enable", "true"); - } else { - properties.put("mail.smtp.ssl.enable", "false"); - } - //---------- SSL setting------------------ - properties.setProperty("mail.pop3.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); - properties.setProperty("mail.pop3.socketFactory.fallback", "false"); - properties.setProperty("mail.pop3.socketFactory.port", String.valueOf(port)); + Properties properties = getConnectionProperties(); Session session = Session.getInstance(properties); - //---------------------------------------- try { log.info("Connecting please wait...."); @@ -421,6 +410,24 @@ public void load(boolean print, boolean save, boolean saveAttachments, ListEach filter pair consists of an {@link EmailField} and a string value. + * Messages are deleted only if they match all provided filter criteria. + * + * @param filterPairs List of key-value pairs where: + * - Key: {@link EmailField} (e.g., SUBJECT, FROM) + * - Value: String to match against the corresponding field + * @throws MessagingException if there's an error connecting to the email server + * or performing mailbox operations + */ + public void clearInbox(List> filterPairs) { + try { + Store store = getImapStore(); + Folder folderInbox = store.getFolder("INBOX"); + folderInbox.open(Folder.READ_WRITE); + + // fetches new messages from server + log.info("Getting inbox.."); + List messages = List.of(folderInbox.getMessages()); + + log.info("Deleting messages.."); + for (Message message : messages) + if (emailMatch(EmailMessage.from(message), filterPairs)) + message.setFlag(Flags.Flag.DELETED, true); + + // Delete messages and close connection + folderInbox.close(true); + store.close(); + log.info(messages.size() + " messages have been successfully deleted!"); + + } catch (MessagingException exception) { + log.error(exception.getLocalizedMessage(), exception); + } + } + /** - * Clears the email inbox using the configured email credentials and server settings. + * Clears the email inbox by applying the specified flag to messages that match + * the given filters using the configured email credentials and server settings. + * + *

Messages are filtered based on key-value pairs (EmailField + String value) + * and the specified flag is applied to matching messages. + * + * @param flag The flag to apply to matching messages (e.g., Flags.Flag.DELETED) + * @param filterPairs Variable arguments of key-value pairs where: + * - Key: {@link EmailField} (e.g., SUBJECT, FROM) + * - Value: String to match against the corresponding field + */ + @SafeVarargs + public final void clearInbox(EmailFlag flag, Pair... filterPairs) { + try { + Store store = getImapStore(); + Folder folderInbox = store.getFolder("INBOX"); + folderInbox.open(Folder.READ_WRITE); + + // fetches new messages from server + log.info("Getting inbox.."); + List messages = List.of(folderInbox.getMessages()); + + log.info("Marking messages as " + markup(StringUtilities.Color.BLUE, flag.name()) + "..."); + int markedMessageCounter = 0; + for (Message message : messages) + if (emailMatch(EmailMessage.from(message), List.of(filterPairs))) { + message.setFlag(flag.getFlag(), true); + markedMessageCounter+=1; + } + + // Delete messages and close connection + folderInbox.close(true); + store.close(); + log.info(markedMessageCounter + " messages have been marked as " + flag.name() + "!"); + + } catch (MessagingException exception) { + log.error(exception.getLocalizedMessage(), exception); + } + } + + /** + * Clears the email inbox by deleting all messages using the configured + * email credentials and server settings. + * + *

This method does not apply any filters and will delete every message in the inbox. + * */ public void clearInbox() { try { diff --git a/src/main/java/utils/email/mapping/EmailFlag.java b/src/main/java/utils/email/mapping/EmailFlag.java new file mode 100644 index 0000000..73e6d1e --- /dev/null +++ b/src/main/java/utils/email/mapping/EmailFlag.java @@ -0,0 +1,74 @@ +/** + * Enumeration mapping standard email flags to JavaMail {@link Flags.Flag} constants. + *

+ * This enum provides a typed representation of common IMAP message flags, making it easier + * to work with email operations while maintaining type safety and readability. + * + * Note: The {@code FLAGGED} enum constant is incorrectly mapped to + * {@code Flags.Flag.ANSWERED} in the current implementation. This should be corrected to + * {@code Flags.Flag.FLAGGED} to match standard IMAP semantics. + * + * @see Flags.Flag for JavaMail API documentation + * @since 1.0.0 + */ +package utils.email.mapping; + +import jakarta.mail.Flags; + +public enum EmailFlag { + /** + * Message has been answered (replied to). + */ + ANSWERED(Flags.Flag.ANSWERED), + + /** + * Message is marked for deletion. + */ + DELETED(Flags.Flag.DELETED), + + /** + * Message has been read. + */ + SEEN(Flags.Flag.SEEN), + + /** + * Message is marked with a user-defined flag. + */ + USER(Flags.Flag.USER), + + /** + * Message is flagged for special attention (e.g., important). + * Current implementation error: Should map to {@code Flags.Flag.FLAGGED}. + */ + FLAGGED(Flags.Flag.ANSWERED), + + /** + * Message has arrived since the last check. + */ + RECENT(Flags.Flag.RECENT), + + /** + * Message is a draft (not yet sent). + */ + DRAFT(Flags.Flag.DRAFT); + + final Flags.Flag flag; + + /** + * Constructs an EmailFlag enum value with the corresponding JavaMail flag. + * + * @param flag the JavaMail {@link Flags.Flag} to associate with this enum constant + */ + EmailFlag(Flags.Flag flag) { + this.flag = flag; + } + + /** + * Returns the JavaMail {@link Flags.Flag} associated with this enum constant. + * + * @return the corresponding JavaMail flag + */ + public Flags.Flag getFlag() { + return flag; + } +} \ No newline at end of file