Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds plugin that allows marking IMAP messages as read #215

Merged
merged 2 commits into from
Nov 1, 2020

Conversation

andia89
Copy link
Contributor

@andia89 andia89 commented Oct 2, 2020

I wrote a small plugin that allows marking IMAP messages as read also on the server upon doing it in mailnag. It required some minor changes to the code base of mailnag, but nothing serious (apart from the fact that the folders cannot be readonly anymore). I think that is a nice addition that solves a small annoyance.

I'm not entirely sure overloading a function like that is the idea of plugins for this app, but I didn't want to rewrite the whole dBus implementation

Solves #214

@pulb
Copy link
Owner

pulb commented Oct 5, 2020

Hey andia89,

many thanks for your pull request, this feature is very appreciated! 😃 Though can you please add the feature to the daemon itself instead to a plugin? As you already pointed out, your plugin implementation is a bit hackish as the mark-as-read functionality isn't exposed by the plugin api and hence your plugin accesses/patches daemon internals which can easily change and break the plugin in the future. Besides that I also believe most people want to have their mails marked as read on the imap server by default. If not, we can make this optional in mailnag.cfg.

@andia89
Copy link
Contributor Author

andia89 commented Oct 5, 2020

All done. That was even easier then :) Ive added a section to mailnag.cfg just in case someone doesn't like the change

@pulb
Copy link
Owner

pulb commented Oct 6, 2020 via email

@pulb
Copy link
Owner

pulb commented Oct 31, 2020

Sorry for not merging your PR yet. I reviewed it already but there are a view changes I don't like. I didn't find the time yet to think about a better solution for those changes unfortunatelly. I'll add some comments for the time being.

for response_part in msg_data:
if isinstance(response_part, tuple):
try:
msg = email.message_from_bytes(response_part[1])
except:
logging.debug("Couldn't get IMAP message.")
continue
yield (folder, msg)
yield (folder, msg, num.decode("utf-8"))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The list_messages() method is defined in the base interface and implemented in several backends like in this imap backend. list_messages() of all other backends returns (folder, msg) pairs, wheras imap now returns (folder, msg, num) tuples, which breaks the interface (inconsistency).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, that is of course an issue. Maybe it would be a way to add some kind of dummy number to the other backends? I don't see any other way of letting mailnag know about this imap specific id though

@@ -126,9 +126,22 @@ def shutdown(self):

# 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.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment should not be removed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, of course

@@ -110,7 +110,7 @@ def _convert_mails(self, mails):
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)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is strID exposed by the dbus interface?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that was a mistake on my side, I think I tested that once to let the gnome-shell extension know about the ID (and open the specific mail directly when clicking on it) in the end it didn't really work. I guess it can be removed

@@ -225,8 +225,7 @@ def _select_single_folder(self, conn):
folder = self.folders[0]
else:
folder = "INBOX"

conn.select(f'"{folder}"', readonly = True)
conn.select(f'"{folder}"')
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it really necessary to remove the readonly flag?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The readonly definitely has to go, I mean one could put readonly = False, but that is just a matter of taste

self.account_name = account.name
self.account_id = account.get_id()
self.id = id
self.strID = strID
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the idea of adding an imap specific mail counter (strID) to the generic mail class. I can't come up with a better solution right now, though.

return
backend = mail.account._get_backend()
if type(backend).__name__ == 'IMAPMailboxBackend':
mailid = mail.strID
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The terms mailID and strID are missleading. This is rather a mail counter.

self._memorizer.save()
return
backend = mail.account._get_backend()
if type(backend).__name__ == 'IMAPMailboxBackend':
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding backend specific code here feels hackish. This should be implemented within the backend, which marks the mail as read if it supports it.

@pulb pulb merged commit b59ef66 into pulb:master Nov 1, 2020
@pulb
Copy link
Owner

pulb commented Nov 1, 2020

Thanks again! Will do some refactoring later

@andia89 andia89 deleted the markasread branch November 3, 2020 07:44
@pulb
Copy link
Owner

pulb commented Nov 3, 2020 via email

@pulb
Copy link
Owner

pulb commented Nov 4, 2020

I pushed all fixes in commit a124d14.

@andia89
Copy link
Contributor Author

andia89 commented Nov 6, 2020

Thanks for the refactor. It seems to be not working for me though. Messages are not marked as read on my gmail anymore... I will investigate

@pulb
Copy link
Owner

pulb commented Nov 6, 2020 via email

@andia89
Copy link
Contributor Author

andia89 commented Feb 5, 2021

@pulb Just saw the hanging comment here: Yes it works, but the delay between marking it as read and it eventually being marked on the server side is a bit annoying when trying to clean up my inbox (at least to me). I "fixed" that for me by adding a self.check_for_mails() at the end of mark_mail_as_read in the file mailnagdaemon.py, like that

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.
		self._ensure_not_disposed()
		
		self._memorizer.set_to_seen(mail_id)
		self._memorizer.save() 
                self.check_for_mails()

do you think that is a proper fix or to hackish?

@pulb
Copy link
Owner

pulb commented Feb 5, 2021 via email

@pulb
Copy link
Owner

pulb commented Feb 5, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants