diff --git a/Mailnag/backends/imap.py b/Mailnag/backends/imap.py index ddb0a25..deab175 100644 --- a/Mailnag/backends/imap.py +++ b/Mailnag/backends/imap.py @@ -82,9 +82,9 @@ class IMAPMailboxBackend(MailboxBackend): for folder in folder_list: # select IMAP folder - conn.select(f'"{folder}"', readonly = True) + conn.select(f'"{folder}"') try: - status, data = conn.search(None, 'UNSEEN') # ALL or UNSEEN + status, data = conn.uid('SEARCH', None, '(UNSEEN)') # ALL or UNSEEN except: logging.warning('Folder %s does not exist.', folder) continue @@ -93,7 +93,7 @@ class IMAPMailboxBackend(MailboxBackend): logging.debug('Folder %s in status %s | Data: %s', (folder, status, data)) continue # Bugfix LP-735071 for num in data[0].split(): - typ, msg_data = conn.fetch(num, '(BODY.PEEK[HEADER])') # header only (without setting READ flag) + typ, msg_data = conn.uid('FETCH', num, '(BODY.PEEK[HEADER])') # header only (without setting READ flag) for response_part in msg_data: if isinstance(response_part, tuple): try: @@ -101,7 +101,7 @@ class IMAPMailboxBackend(MailboxBackend): except: logging.debug("Couldn't get IMAP message.") continue - yield (folder, msg) + yield (folder, msg, num.decode("utf-8")) def request_folders(self): @@ -225,8 +225,7 @@ class IMAPMailboxBackend(MailboxBackend): folder = self.folders[0] else: folder = "INBOX" - - conn.select(f'"{folder}"', readonly = True) + conn.select(f'"{folder}"') def _ensure_open(self): if not self.is_open(): diff --git a/Mailnag/common/config.py b/Mailnag/common/config.py index fcbdf2d..f638537 100644 --- a/Mailnag/common/config.py +++ b/Mailnag/common/config.py @@ -26,6 +26,7 @@ mailnag_defaults = { 'poll_interval' : '10', 'imap_idle_timeout' : '10', 'autostart' : '1', + 'mark_imap_read' : '1', 'connectivity_test' : 'auto', 'enabled_plugins' : 'dbusplugin, soundplugin, libnotifyplugin' } diff --git a/Mailnag/daemon/dbus.py b/Mailnag/daemon/dbus.py index c8d01ac..e420adb 100644 --- a/Mailnag/daemon/dbus.py +++ b/Mailnag/daemon/dbus.py @@ -110,7 +110,7 @@ class DBusService(dbus.service.Object): d['sender_addr'] = addr # string (s) d['account_name'] = m.account_name # string (s) d['id'] = m.id # string (s) - + d['strID'] = m.strID # string (s) converted_mails.append(d) return converted_mails diff --git a/Mailnag/daemon/mailchecker.py b/Mailnag/daemon/mailchecker.py index 6df9de0..5a2bd0f 100644 --- a/Mailnag/daemon/mailchecker.py +++ b/Mailnag/daemon/mailchecker.py @@ -36,6 +36,7 @@ class MailChecker: self._conntest = conntest self._dbus_service = dbus_service self._count_on_last_check = 0 + self._all_mails = [] def check(self, accounts): @@ -65,7 +66,7 @@ class MailChecker: else: # mail is fetched the first time unseen_mails.append(mail) new_mails.append(mail) - + self._all_mails = all_mails self._memorizer.sync(all_mails) self._memorizer.save() self._firstcheck = False diff --git a/Mailnag/daemon/mailnagdaemon.py b/Mailnag/daemon/mailnagdaemon.py index 07b759a..d452a3b 100644 --- a/Mailnag/daemon/mailnagdaemon.py +++ b/Mailnag/daemon/mailnagdaemon.py @@ -126,9 +126,22 @@ class MailnagDaemon(MailnagController): # Part of MailnagController interface def mark_mail_as_read(self, mail_id): - # Note: ensure_not_disposed() is not really necessary here - # (the memorizer object is available in dispose()), - # but better be consistent with other daemon methods. + mails = self._mailchecker._all_mails + found = False + for mail in mails: + if mail_id == mail.id: + found = True + break + if (not found) or (not bool(int(self._cfg.get('core', 'mark_imap_read')))): + self._ensure_not_disposed() + self._memorizer.set_to_seen(mail_id) + self._memorizer.save() + return + backend = mail.account._get_backend() + if type(backend).__name__ == 'IMAPMailboxBackend': + mailid = mail.strID + conn = backend._conn + status, res = conn.uid("STORE", mailid, "+FLAGS", "(\Seen)") self._ensure_not_disposed() self._memorizer.set_to_seen(mail_id) self._memorizer.save() diff --git a/Mailnag/daemon/mails.py b/Mailnag/daemon/mails.py index 594c01f..c144547 100644 --- a/Mailnag/daemon/mails.py +++ b/Mailnag/daemon/mails.py @@ -35,13 +35,15 @@ from Mailnag.common.config import cfg_folder # Mail class # class Mail: - def __init__(self, datetime, subject, sender, id, account): + def __init__(self, datetime, subject, sender, id, account, strID): self.datetime = datetime self.subject = subject self.sender = sender + self.account = account self.account_name = account.name self.account_id = account.get_id() self.id = id + self.strID = strID # @@ -66,7 +68,7 @@ class MailCollector: logging.error("Failed to open mailbox for account '%s' (%s)." % (acc.name, ex)) continue - for folder, msg in acc.list_messages(): + for folder, msg, num in acc.list_messages(): sender, subject, datetime, msgid = self._get_header(msg) id = self._get_id(msgid, acc, folder, sender, subject, datetime) @@ -78,7 +80,7 @@ class MailCollector: # Also filter duplicates caused by Gmail labels. if id not in mail_ids: mail_list.append(Mail(datetime, subject, \ - sender, id, acc)) + sender, id, acc, num)) mail_ids[id] = None # leave account with notifications open, so that it can @@ -193,7 +195,6 @@ class MailSyncer: # collect mails from given accounts rcv_lst = MailCollector(self._cfg, accounts).collect_mail(sort = False) - # group received mails by account tmp = {} for acc in accounts: