Merge pull request #141 from tikank/accountdialog

MBox and Maildir added to account dialog
This commit is contained in:
Patrick Ulbrich
2017-05-14 16:04:24 +02:00
committed by GitHub
4 changed files with 311 additions and 78 deletions

View File

@@ -47,25 +47,37 @@ CREDENTIAL_KEY = 'Mailnag password for %s://%s@%s'
# Account class
#
class Account:
def __init__(self, enabled = False, name = '', user = '', \
password = '', oauth2string = '', server = '', port = '', ssl = True, imap = True, idle = False, folders = [], mailbox_type = None, **kw):
self.enabled = enabled # bool
def __init__(self, mailbox_type=None, enabled = False, name = '', **kw):
self._backend = None
self.set_config(
mailbox_type=mailbox_type,
name=name,
enabled=enabled,
config=kw)
def set_config(self, mailbox_type, name, enabled, config):
"""Set accounts configuration."""
self.enabled = enabled
if mailbox_type:
self.mailbox_type = mailbox_type
elif 'imap' in config:
self.mailbox_type = 'imap' if config.get('imap', True) else 'pop3'
else:
self.mailbox_type = 'imap' if imap else 'pop3'
self.mailbox_type = ''
self.name = name
self.user = user
self.password = password
self.oauth2string = oauth2string
self.server = server
self.port = port
self.ssl = ssl # bool
self.imap = imap # bool
self.idle = idle # bool
self.folders = folders
self._rest_of_config = kw
self.user = config.get('user', '')
self.password = config.get('password', '')
self.oauth2string = config.get('oauth2string', '')
self.server = config.get('server', '')
self.port = config.get('port', '')
self.ssl = config.get('ssl', True)
self.imap = config.get('imap', True)
self.idle = config.get('idle', False)
self.folders = config.get('folders', [])
self._rest_of_config = config
if self._backend and self._backend.is_open():
self._backend.close()
self._backend = None

View File

@@ -39,6 +39,9 @@ IDX_WEB_DE = 2
IDX_YAHOO = 3
IDX_IMAP = 4
IDX_POP3 = 5
IDX_MBOX = 6
IDX_MAILDIR = 7
PROVIDER_CONFIGS = [
[ 'Gmail', 'imap.gmail.com', '993'],
@@ -68,12 +71,18 @@ class AccountDialog:
self._cmb_account_type = builder.get_object("cmb_account_type")
self._label_account_name = builder.get_object("label_account_name")
self._entry_account_name = builder.get_object("entry_account_name")
self._label_account_user = builder.get_object("label_account_user")
self._entry_account_user = builder.get_object("entry_account_user")
self._label_account_password = builder.get_object("label_account_password")
self._entry_account_password = builder.get_object("entry_account_password")
self._label_account_server = builder.get_object("label_account_server")
self._entry_account_server = builder.get_object("entry_account_server")
self._label_account_port = builder.get_object("label_account_port")
self._entry_account_port = builder.get_object("entry_account_port")
self._label_account_file_path = builder.get_object("label_account_file_path")
self._chooser_account_file_path = builder.get_object("chooser_file_path")
self._label_account_directory_path = builder.get_object("label_account_directory_path")
self._chooser_account_directory_path = builder.get_object("chooser_directory_path")
self._expander_folders = builder.get_object("expander_folders")
self._overlay = builder.get_object("overlay")
self._treeview_folders = builder.get_object("treeview_folders")
@@ -118,55 +127,88 @@ class AccountDialog:
def _load_account(self, acc):
config = acc.get_config()
self._entry_account_name.set_text(acc.name)
self._entry_account_user.set_text(acc.user)
self._entry_account_password.set_text(acc.password)
self._entry_account_server.set_text(acc.server)
self._entry_account_port.set_text(acc.port)
self._chk_account_push.set_active(acc.idle)
self._chk_account_push.set_sensitive(len(acc.folders) < 2)
self._chk_account_ssl.set_active(acc.ssl)
if 'user' in config:
self._entry_account_user.set_text(config['user'])
if 'password' in config:
self._entry_account_password.set_text(config['password'])
if 'server' in config:
self._entry_account_server.set_text(config['server'])
if 'port' in config:
self._entry_account_port.set_text(config['port'])
if 'idle' in config:
self._chk_account_push.set_active(config['idle'])
if 'folders' in config:
self._chk_account_push.set_sensitive(len(config['folders']) < 2)
if 'ssl' in config:
self._chk_account_ssl.set_active(config['ssl'])
if 'path' in config:
self._chooser_account_file_path.set_filename(config.get('path'))
if 'path' in config:
self._chooser_account_directory_path.set_filename(config.get('path'))
def _configure_account(self, acc):
config = {}
acctype = self._cmb_account_type.get_active()
if (acctype == IDX_POP3) or (acctype == IDX_IMAP):
acc.name = self._entry_account_name.get_text()
acc.user = self._entry_account_user.get_text()
acc.password = self._entry_account_password.get_text()
acc.server = self._entry_account_server.get_text()
acc.port = self._entry_account_port.get_text()
acc.ssl = self._chk_account_ssl.get_active()
name = self._entry_account_name.get_text()
config['user'] = self._entry_account_user.get_text()
config['password'] = self._entry_account_password.get_text()
config['server'] = self._entry_account_server.get_text()
config['port'] = self._entry_account_port.get_text()
config['ssl'] = self._chk_account_ssl.get_active()
if acctype == IDX_POP3:
acc.imap = False
acc.folders = []
acc.idle = False
mailbox_type = 'pop3'
config['imap'] = False
config['folders'] = []
config['idle'] = False
elif acctype == IDX_IMAP:
acc.imap = True
mailbox_type = 'imap'
config['imap'] = True
if self._folders_received:
acc.folders = self._get_selected_folders()
acc.idle = self._chk_account_push.get_active()
else: # known provider (imap only)
acc.name = self._entry_account_user.get_text()
acc.user = self._entry_account_user.get_text()
acc.password = self._entry_account_password.get_text()
acc.ssl = True
acc.imap = True
config['folders'] = self._get_selected_folders()
config['idle'] = self._chk_account_push.get_active()
elif acctype == IDX_MBOX:
mailbox_type = 'mbox'
name = self._entry_account_name.get_text()
config['path'] = self._chooser_account_file_path.get_filename()
elif acctype == IDX_MAILDIR:
mailbox_type = 'maildir'
name = self._entry_account_name.get_text()
config['path'] = self._chooser_account_directory_path.get_filename()
if self._folders_received:
acc.folders = self._get_selected_folders()
acc.idle = (len(acc.folders) < 2)
config['folders'] = self._get_selected_folders()
else:
config['folders'] = []
else: # known provider (imap only)
mailbox_type = 'imap'
name = self._entry_account_user.get_text()
config['user'] = self._entry_account_user.get_text()
config['password'] = self._entry_account_password.get_text()
config['ssl'] = True
config['imap'] = True
config['folders'] = []
if self._folders_received:
config['folders'] = self._get_selected_folders()
config['idle'] = (len(config['folders']) < 2)
if acctype < len(PROVIDER_CONFIGS):
p = PROVIDER_CONFIGS[acctype]
acc.name += (' (%s)' % p[0])
acc.server = p[1]
acc.port = p[2]
name += (' (%s)' % p[0])
config['server'] = p[1]
config['port'] = p[2]
else:
raise Exception('Unknown account type')
acc.set_config(
mailbox_type=mailbox_type,
name=name,
enabled=acc.enabled,
config=config)
def _get_selected_folders(self):
folders = []
for row in self._liststore_folders:
@@ -181,29 +223,46 @@ class AccountDialog:
self._cmb_account_type.append_text(p[0])
self._cmb_account_type.append_text(_("Other (IMAP)"))
self._cmb_account_type.append_text(_("Other (POP3)"))
self._cmb_account_type.append_text(_("MBox"))
self._cmb_account_type.append_text(_("Maildir"))
config = self._acc.get_config()
# select account type
if len(self._acc.server) == 0:
if self._acc.mailbox_type == '':
# default to Gmail when creating new accounts
self._cmb_account_type.set_active(IDX_GMAIL) # triggers _on_cmb_account_type_changed()
idx = IDX_GMAIL
else:
i = 0
idx = -1
for p in PROVIDER_CONFIGS:
if (('%s (%s)' % (self._acc.user, p[0])) == self._acc.name) and \
p[1] == self._acc.server and \
p[2] == self._acc.port:
idx = i
break
i+=1
if idx >= 0:
self._cmb_account_type.set_active(idx) # triggers _on_cmb_account_type_changed()
else:
self._cmb_account_type.set_active(IDX_IMAP if self._acc.imap else IDX_POP3) # triggers _on_cmb_account_type_changed()
# Don't allow changing the account type if the loaded account has folders.
self._cmb_account_type.set_sensitive(len(self._acc.folders) == 0)
if 'user' in config and 'server' in config and 'port' in config:
user = config['user']
server = config['server']
port = config['port']
for i, p in enumerate(PROVIDER_CONFIGS):
if (('%s (%s)' % (user, p[0])) == self._acc.name) and \
p[1] == server and p[2] == port:
idx = i
break
if idx < 0:
if self._acc.mailbox_type == 'imap':
idx = IDX_IMAP
elif self._acc.mailbox_type == 'pop3':
idx = IDX_POP3
elif self._acc.mailbox_type == 'mbox':
idx = IDX_MBOX
elif self._acc.mailbox_type == 'maildir':
idx = IDX_MAILDIR
else:
# This is actually error case, but recovering to IMAP
idx = IDX_IMAP
self._cmb_account_type.set_active(idx) # triggers _on_cmb_account_type_changed()
# Don't allow changing the account type if the loaded account has folders.
if 'folders' in config:
is_type_change_allowed = len(config['folders']) == 0
else:
is_type_change_allowed = True
self._cmb_account_type.set_sensitive(is_type_change_allowed)
def _on_btn_cancel_clicked(self, widget):
@@ -224,6 +283,12 @@ class AccountDialog:
len(self._entry_account_user.get_text()) > 0 and \
len(self._entry_account_password.get_text()) > 0 and \
len(self._entry_account_server.get_text()) > 0
elif acctype == IDX_MBOX:
ok = len(self._entry_account_name.get_text()) > 0 and \
(self._chooser_account_file_path.get_filename() is not None)
elif acctype == IDX_MAILDIR:
ok = len(self._entry_account_name.get_text()) > 0 and \
(self._chooser_account_directory_path.get_filename() is not None)
else: # known provider
ok = len(self._entry_account_user.get_text()) > 0 and \
len(self._entry_account_password.get_text()) > 0
@@ -326,6 +391,10 @@ class AccountDialog:
if acctype == IDX_POP3:
self._label_account_name.set_visible(True)
self._entry_account_name.set_visible(True)
self._label_account_user.set_visible(True)
self._entry_account_user.set_visible(True)
self._label_account_password.set_visible(True)
self._entry_account_password.set_visible(True)
self._label_account_server.set_visible(True)
self._entry_account_server.set_visible(True)
self._label_account_port.set_visible(True)
@@ -333,9 +402,17 @@ class AccountDialog:
self._expander_folders.set_visible(False)
self._chk_account_push.set_visible(False)
self._chk_account_ssl.set_visible(True)
self._label_account_file_path.set_visible(False)
self._chooser_account_file_path.set_visible(False)
self._label_account_directory_path.set_visible(False)
self._chooser_account_directory_path.set_visible(False)
elif acctype == IDX_IMAP:
self._label_account_name.set_visible(True)
self._entry_account_name.set_visible(True)
self._label_account_user.set_visible(True)
self._entry_account_user.set_visible(True)
self._label_account_password.set_visible(True)
self._entry_account_password.set_visible(True)
self._label_account_server.set_visible(True)
self._entry_account_server.set_visible(True)
self._label_account_port.set_visible(True)
@@ -343,9 +420,35 @@ class AccountDialog:
self._expander_folders.set_visible(True)
self._chk_account_push.set_visible(True)
self._chk_account_ssl.set_visible(True)
else: # known provider (imap only)
self._label_account_name.set_visible(False)
self._entry_account_name.set_visible(False)
self._label_account_file_path.set_visible(False)
self._chooser_account_file_path.set_visible(False)
self._label_account_directory_path.set_visible(False)
self._chooser_account_directory_path.set_visible(False)
elif acctype == IDX_MBOX:
self._label_account_name.set_visible(True)
self._entry_account_name.set_visible(True)
self._label_account_user.set_visible(False)
self._entry_account_user.set_visible(False)
self._label_account_password.set_visible(False)
self._entry_account_password.set_visible(False)
self._label_account_server.set_visible(False)
self._entry_account_server.set_visible(False)
self._label_account_port.set_visible(False)
self._entry_account_port.set_visible(False)
self._expander_folders.set_visible(False)
self._chk_account_push.set_visible(False)
self._chk_account_ssl.set_visible(False)
self._label_account_file_path.set_visible(True)
self._chooser_account_file_path.set_visible(True)
self._label_account_directory_path.set_visible(False)
self._chooser_account_directory_path.set_visible(False)
elif acctype == IDX_MAILDIR:
self._label_account_name.set_visible(True)
self._entry_account_name.set_visible(True)
self._label_account_user.set_visible(False)
self._entry_account_user.set_visible(False)
self._label_account_password.set_visible(False)
self._entry_account_password.set_visible(False)
self._label_account_server.set_visible(False)
self._entry_account_server.set_visible(False)
self._label_account_port.set_visible(False)
@@ -353,6 +456,28 @@ class AccountDialog:
self._expander_folders.set_visible(True)
self._chk_account_push.set_visible(False)
self._chk_account_ssl.set_visible(False)
self._label_account_file_path.set_visible(False)
self._chooser_account_file_path.set_visible(False)
self._label_account_directory_path.set_visible(True)
self._chooser_account_directory_path.set_visible(True)
else: # known provider (imap only)
self._label_account_name.set_visible(False)
self._entry_account_name.set_visible(False)
self._label_account_user.set_visible(True)
self._entry_account_user.set_visible(True)
self._label_account_password.set_visible(True)
self._entry_account_password.set_visible(True)
self._label_account_server.set_visible(False)
self._entry_account_server.set_visible(False)
self._label_account_port.set_visible(False)
self._entry_account_port.set_visible(False)
self._expander_folders.set_visible(True)
self._chk_account_push.set_visible(False)
self._chk_account_ssl.set_visible(False)
self._label_account_file_path.set_visible(False)
self._chooser_account_file_path.set_visible(False)
self._label_account_directory_path.set_visible(False)
self._chooser_account_directory_path.set_visible(False)
self._folders_received = False
self._selected_folder_count = 0

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<!-- Generated with glade 3.20.0 -->
<interface>
<requires lib="gtk+" version="3.6"/>
<object class="GtkListStore" id="liststore_folders">
@@ -151,7 +151,7 @@
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">6</property>
<property name="top_attach">8</property>
<property name="width">2</property>
</packing>
</child>
@@ -177,7 +177,7 @@
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">7</property>
<property name="top_attach">9</property>
<property name="width">2</property>
</packing>
</child>
@@ -294,10 +294,67 @@
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">8</property>
<property name="top_attach">10</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_account_file_path">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">File path:</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">6</property>
</packing>
</child>
<child>
<object class="GtkFileChooserButton" id="chooser_file_path">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="create_folders">False</property>
<property name="preview_widget_active">False</property>
<property name="show_hidden">True</property>
<property name="use_preview_label">False</property>
<property name="title" translatable="yes"/>
<signal name="file-set" handler="entry_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">6</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_account_directory_path">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Directory:</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">7</property>
</packing>
</child>
<child>
<object class="GtkFileChooserButton" id="chooser_directory_path">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action">select-folder</property>
<property name="create_folders">False</property>
<property name="preview_widget_active">False</property>
<property name="show_hidden">True</property>
<property name="use_preview_label">False</property>
<property name="title" translatable="yes"/>
<signal name="file-set" handler="entry_changed" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">7</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>

View File

@@ -45,12 +45,44 @@ def test_account_should_keep_configuration():
'user': 'who',
'password': 'secret',
'oauth2string': 'who knows',
'server': 'example.org',
'server': 'example.org',
'port': '1234',
'ssl': True,
'imap': True,
'idle': True,
'folders': ['a', 'b'],
'imap': True,
'idle': True,
'folders': ['a', 'b'],
'mailbox_type': 'mybox',
}
assert expected_config == config
def test_account_should_store_configuration():
new_config = {
'user': 'who',
'password': 'secret',
'oauth2string': 'who knows',
'server': 'example.org',
'port': '1234',
'ssl': True,
'imap': True,
'idle': True,
'folders': ['a', 'b'],
}
account = Account()
account.set_config(mailbox_type='mybox', name='my name', enabled=True, config=new_config)
config = account.get_config()
expected_config = {
'enabled': True,
'name': 'my name',
'user': 'who',
'password': 'secret',
'oauth2string': 'who knows',
'server': 'example.org',
'port': '1234',
'ssl': True,
'imap': True,
'idle': True,
'folders': ['a', 'b'],
'mailbox_type': 'mybox',
}
assert expected_config == config
@@ -64,6 +96,13 @@ def test_account_config_should_always_contain_certain_values():
assert 'mailbox_type' in config
def test_type_should_be_empty_by_default():
account = Account()
config = account.get_config()
assert account.mailbox_type == ''
assert config['mailbox_type'] == ''
def test_account_should_configurable_with_any_parameters():
account = Account(weird='odd', odd='weird')
config = account.get_config()