Skip to content

Commit

Permalink
Merge pull request #165 from tikank/accountmembers
Browse files Browse the repository at this point in the history
Refactorings related to Account class
  • Loading branch information
pulb committed Jun 1, 2018
2 parents f2ba86a + 88fdde4 commit d576a6b
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 12 deletions.
5 changes: 5 additions & 0 deletions Mailnag/backends/base.py
Expand Up @@ -67,6 +67,11 @@ def request_folders(self):
"""
raise NotImplementedError

def supports_notifications(self):
"""Returns True if mailbox supports notifications."""
# Default implementation
return False

@abstractmethod
def notify_next_change(self, callback=None, timeout=None):
"""Asks mailbox to notify next change.
Expand Down
8 changes: 7 additions & 1 deletion Mailnag/backends/imap.py
Expand Up @@ -40,7 +40,7 @@ class IMAPMailboxBackend(MailboxBackend):
"""Implementation of IMAP mail boxes."""

def __init__(self, name = '', user = '', password = '', oauth2string = '',
server = '', port = '', ssl = True, folders = [], **kw):
server = '', port = '', ssl = True, folders = [], idle=True, **kw):
self.name = name
self.user = user
self.password = password
Expand All @@ -49,6 +49,7 @@ def __init__(self, name = '', user = '', password = '', oauth2string = '',
self.port = port
self.ssl = ssl # bool
self.folders = [encode_mutf7(folder) for folder in folders]
self.idle = idle
self._conn = None


Expand Down Expand Up @@ -130,6 +131,11 @@ def request_folders(self):
return lst


def supports_notifications(self):
"""Returns True if mailbox supports notifications.
IMAP mailbox supports notifications if idle parameter is True"""
return self.idle

def notify_next_change(self, callback=None, timeout=None):
self._ensure_open()

Expand Down
5 changes: 5 additions & 0 deletions Mailnag/common/accounts.py
Expand Up @@ -116,6 +116,11 @@ def list_messages(self):
return self._get_backend().list_messages()


def supports_notifications(self):
"""Returns True if account supports notifications."""
return self._get_backend().supports_notifications()


def notify_next_change(self, callback=None, timeout=None):
"""Asks mailbox to notify next change.
Callback is called when new mail arrives or removed.
Expand Down
4 changes: 2 additions & 2 deletions Mailnag/daemon/idlers.py
Expand Up @@ -4,7 +4,7 @@
# idlers.py
#
# Copyright 2011 - 2016 Patrick Ulbrich <zulu99@gmx.net>
# Copyright 2016 Timo Kankare <timo.kankare@iki.fi>
# Copyright 2016, 2018 Timo Kankare <timo.kankare@iki.fi>
# Copyright 2011 Leighton Earl <leighton.earl@gmx.com>
#
# This program is free software; you can redistribute it and/or modify
Expand Down Expand Up @@ -136,7 +136,7 @@ def __init__(self, accounts, sync_callback, idle_timeout):

def start(self):
for acc in self._accounts:
if acc.imap and acc.idle:
if acc.supports_notifications():
try:
idler = Idler(acc, self._sync_callback, self._idle_timeout)
idler.start()
Expand Down
20 changes: 13 additions & 7 deletions Mailnag/daemon/mailnagdaemon.py
Expand Up @@ -150,8 +150,7 @@ def check_for_mails(self):
# have been closed already.
self._ensure_valid_state()

non_idle_accounts = filter(lambda acc: (not acc.imap) or
(acc.imap and not acc.idle), self._accounts)
non_idle_accounts = self._get_non_idle_accounts(self._accounts)
self._mailchecker.check(non_idle_accounts)


Expand Down Expand Up @@ -180,9 +179,8 @@ def _start(self):
except:
logging.exception('Caught an exception.')

idle_accounts = filter(lambda acc: acc.imap and acc.idle, self._accounts)
non_idle_accounts = filter(lambda acc: (not acc.imap) or
(acc.imap and not acc.idle), self._accounts)
idle_accounts = self._get_idle_accounts(self._accounts)
non_idle_accounts = self._get_non_idle_accounts(self._accounts)

# start polling thread for POP3 accounts and
# IMAP accounts without idle support
Expand Down Expand Up @@ -232,8 +230,16 @@ def _wait_for_inet_connection(self):
# (see timeout in mailnag.cleanup())
# ..but also don't sleep to short in case of a ping connection test.
time.sleep(3)




def _get_idle_accounts(self, accounts):
return [acc for acc in self._accounts if acc.supports_notifications()]


def _get_non_idle_accounts(self, accounts):
return [acc for acc in self._accounts if not acc.supports_notifications()]


def _load_plugins(self, cfg, hookreg, memorizer):
class MailnagController_Impl(MailnagController):
def __init__(self, daemon, memorizer, hookreg, shutdown_request_hdlr):
Expand Down
5 changes: 3 additions & 2 deletions Mailnag/daemon/mails.py
Expand Up @@ -85,8 +85,9 @@ def collect_mail(self, sort = True):
sender, id, acc))
mail_ids[id] = None

# don't close idle connections
if not acc.idle:
# leave account with notifications open, so that it can
# send notifications about new mails
if not acc.supports_notifications():
# disconnect from Email-Server
acc.close()

Expand Down
17 changes: 17 additions & 0 deletions tests/test_account.py
Expand Up @@ -22,6 +22,8 @@

"""Test cases for Account."""

import pytest

from Mailnag.common.accounts import Account


Expand Down Expand Up @@ -128,3 +130,18 @@ def test_account_should_configurable_with_any_parameters():
assert config['weird'] == 'odd'
assert config['odd'] == 'weird'


@pytest.mark.parametrize("config,should_support", [
({'mailbox_type': 'imap', 'idle': True}, True),
({'mailbox_type': 'imap', 'idle': False}, False),
({'mailbox_type': 'pop3'}, False),
({'mailbox_type': 'mbox'}, False),
({'mailbox_type': 'maildir'}, False),
])
def test_account_supports_notifications(config, should_support):
account = Account(**config)
if should_support:
assert account.supports_notifications()
else:
assert not account.supports_notifications()

0 comments on commit d576a6b

Please sign in to comment.