mirror of
https://github.com/pulb/mailnag.git
synced 2026-01-31 09:09:04 +01:00
Moved IMAP and POP3 related code to backends from account module.
Added backend creation to account dialog so that the folder request can be done.
This commit is contained in:
@@ -23,6 +23,94 @@
|
||||
# MA 02110-1301, USA.
|
||||
#
|
||||
|
||||
class ImapBackend:
|
||||
pass
|
||||
import logging
|
||||
import re
|
||||
import Mailnag.common.imaplib2 as imaplib
|
||||
|
||||
class ImapBackend:
|
||||
"""Implementation of IMAP mail boxes."""
|
||||
|
||||
def __init__(self, name = '', user = '', password = '', oauth2string = '',
|
||||
server = '', port = '', ssl = True, folders = []):
|
||||
self.name = name
|
||||
self.user = user
|
||||
self.password = password
|
||||
self.oauth2string = oauth2string
|
||||
self.server = server
|
||||
self.port = port
|
||||
self.ssl = ssl # bool
|
||||
self.folders = folders
|
||||
self._conn = None
|
||||
|
||||
|
||||
def get_connection(self, use_existing):
|
||||
# try to reuse existing connection
|
||||
if use_existing and self.has_connection():
|
||||
return self._conn
|
||||
|
||||
self._conn = conn = None
|
||||
|
||||
try:
|
||||
if self.ssl:
|
||||
if self.port == '':
|
||||
conn = imaplib.IMAP4_SSL(self.server)
|
||||
else:
|
||||
conn = imaplib.IMAP4_SSL(self.server, int(self.port))
|
||||
else:
|
||||
if self.port == '':
|
||||
conn = imaplib.IMAP4(self.server)
|
||||
else:
|
||||
conn = imaplib.IMAP4(self.server, int(self.port))
|
||||
|
||||
if 'STARTTLS' in conn.capabilities:
|
||||
conn.starttls()
|
||||
else:
|
||||
logging.warning("Using unencrypted connection for account '%s'" % self.name)
|
||||
|
||||
if self.oauth2string != '':
|
||||
conn.authenticate('XOAUTH2', lambda x: self.oauth2string)
|
||||
else:
|
||||
conn.login(self.user, self.password)
|
||||
|
||||
self._conn = conn
|
||||
except:
|
||||
try:
|
||||
if conn != None:
|
||||
# conn.close() # allowed in SELECTED state only
|
||||
conn.logout()
|
||||
except: pass
|
||||
raise # re-throw exception
|
||||
|
||||
return self._conn
|
||||
|
||||
|
||||
def has_connection(self):
|
||||
return (self._conn != None) and \
|
||||
(self._conn.state != imaplib.LOGOUT) and \
|
||||
(not self._conn.Terminate)
|
||||
|
||||
|
||||
def request_folders(self):
|
||||
lst = []
|
||||
|
||||
# Always create a new connection as an existing one may
|
||||
# be used for IMAP IDLE.
|
||||
conn = self.get_connection(use_existing = False)
|
||||
|
||||
try:
|
||||
status, data = conn.list('', '*')
|
||||
finally:
|
||||
# conn.close() # allowed in SELECTED state only
|
||||
conn.logout()
|
||||
|
||||
for d in data:
|
||||
match = re.match('.+\s+("."|"?NIL"?)\s+"?([^"]+)"?$', d)
|
||||
|
||||
if match == None:
|
||||
logging.warning("Folder format not supported.")
|
||||
else:
|
||||
folder = match.group(2)
|
||||
lst.append(folder)
|
||||
|
||||
return lst
|
||||
|
||||
|
||||
@@ -23,6 +23,68 @@
|
||||
# MA 02110-1301, USA.
|
||||
#
|
||||
|
||||
class Pop3Backend:
|
||||
pass
|
||||
import logging
|
||||
import poplib
|
||||
|
||||
class Pop3Backend:
|
||||
"""Implementation of POP3 mail boxes."""
|
||||
|
||||
def __init__(self, name = '', user = '', password = '', oauth2string = '',
|
||||
server = '', port = '', ssl = True):
|
||||
self.name = name
|
||||
self.user = user
|
||||
self.password = password
|
||||
self.oauth2string = oauth2string
|
||||
self.server = server
|
||||
self.port = port
|
||||
self.ssl = ssl # bool
|
||||
self._conn = None
|
||||
|
||||
|
||||
def get_connection(self, use_existing):
|
||||
# try to reuse existing connection
|
||||
if use_existing and self.has_connection():
|
||||
return self._conn
|
||||
|
||||
self._conn = conn = None
|
||||
|
||||
try:
|
||||
if self.ssl:
|
||||
if self.port == '':
|
||||
conn = poplib.POP3_SSL(self.server)
|
||||
else:
|
||||
conn = poplib.POP3_SSL(self.server, int(self.port))
|
||||
else:
|
||||
if self.port == '':
|
||||
conn = poplib.POP3(self.server)
|
||||
else:
|
||||
conn = poplib.POP3(self.server, int(self.port))
|
||||
|
||||
# TODO : Use STARTTLS when Mailnag has been migrated to python 3
|
||||
# (analogous to get_connection in imap backend).
|
||||
logging.warning("Using unencrypted connection for account '%s'" % self.name)
|
||||
|
||||
conn.getwelcome()
|
||||
conn.user(self.user)
|
||||
conn.pass_(self.password)
|
||||
|
||||
self._conn = conn
|
||||
except:
|
||||
try:
|
||||
if conn != None:
|
||||
conn.quit()
|
||||
except: pass
|
||||
raise # re-throw exception
|
||||
|
||||
return self._conn
|
||||
|
||||
|
||||
def has_connection(self):
|
||||
return (self._conn != None) and \
|
||||
('sock' in self._conn.__dict__)
|
||||
|
||||
|
||||
def request_folders(self):
|
||||
lst = []
|
||||
return lst
|
||||
|
||||
|
||||
@@ -24,10 +24,8 @@
|
||||
#
|
||||
|
||||
import re
|
||||
import poplib
|
||||
import logging
|
||||
import json
|
||||
import Mailnag.common.imaplib2 as imaplib
|
||||
from Mailnag.backends.imap import ImapBackend
|
||||
from Mailnag.backends.pop3 import Pop3Backend
|
||||
from Mailnag.common.utils import splitstr
|
||||
@@ -95,31 +93,7 @@ class Account:
|
||||
# Relevant for IMAP accounts only.
|
||||
# Returns an empty list when used on POP3 accounts.
|
||||
def request_server_folders(self):
|
||||
lst = []
|
||||
|
||||
if not self.imap:
|
||||
return lst
|
||||
|
||||
# Always create a new connection as an existing one may
|
||||
# be used for IMAP IDLE.
|
||||
conn = self._get_IMAP_connection(use_existing = False)
|
||||
|
||||
try:
|
||||
status, data = conn.list('', '*')
|
||||
finally:
|
||||
# conn.close() # allowed in SELECTED state only
|
||||
conn.logout()
|
||||
|
||||
for d in data:
|
||||
match = re.match('.+\s+("."|"?NIL"?)\s+"?([^"]+)"?$', d)
|
||||
|
||||
if match == None:
|
||||
logging.warning("Folder format not supported.")
|
||||
else:
|
||||
folder = match.group(2)
|
||||
lst.append(folder)
|
||||
|
||||
return lst
|
||||
return self.backend.request_folders()
|
||||
|
||||
|
||||
def get_id(self):
|
||||
@@ -128,92 +102,20 @@ class Account:
|
||||
|
||||
|
||||
def _has_IMAP_connection(self):
|
||||
return (self._conn != None) and \
|
||||
(self._conn.state != imaplib.LOGOUT) and \
|
||||
(not self._conn.Terminate)
|
||||
return self.backend.has_connection()
|
||||
|
||||
|
||||
def _get_IMAP_connection(self, use_existing):
|
||||
# try to reuse existing connection
|
||||
if use_existing and self._has_IMAP_connection():
|
||||
return self._conn
|
||||
|
||||
self._conn = conn = None
|
||||
|
||||
try:
|
||||
if self.ssl:
|
||||
if self.port == '':
|
||||
conn = imaplib.IMAP4_SSL(self.server)
|
||||
else:
|
||||
conn = imaplib.IMAP4_SSL(self.server, int(self.port))
|
||||
else:
|
||||
if self.port == '':
|
||||
conn = imaplib.IMAP4(self.server)
|
||||
else:
|
||||
conn = imaplib.IMAP4(self.server, int(self.port))
|
||||
|
||||
if 'STARTTLS' in conn.capabilities:
|
||||
conn.starttls()
|
||||
else:
|
||||
logging.warning("Using unencrypted connection for account '%s'" % self.name)
|
||||
|
||||
if self.oauth2string != '':
|
||||
conn.authenticate('XOAUTH2', lambda x: self.oauth2string)
|
||||
else:
|
||||
conn.login(self.user, self.password)
|
||||
|
||||
self._conn = conn
|
||||
except:
|
||||
try:
|
||||
if conn != None:
|
||||
# conn.close() # allowed in SELECTED state only
|
||||
conn.logout()
|
||||
except: pass
|
||||
raise # re-throw exception
|
||||
|
||||
self._conn = self.backend.get_connection(use_existing)
|
||||
return self._conn
|
||||
|
||||
|
||||
def _has_POP3_connection(self):
|
||||
return (self._conn != None) and \
|
||||
('sock' in self._conn.__dict__)
|
||||
return self.backend.has_connection()
|
||||
|
||||
|
||||
def _get_POP3_connection(self, use_existing):
|
||||
# try to reuse existing connection
|
||||
if use_existing and self._has_POP3_connection():
|
||||
return self._conn
|
||||
|
||||
self._conn = conn = None
|
||||
|
||||
try:
|
||||
if self.ssl:
|
||||
if self.port == '':
|
||||
conn = poplib.POP3_SSL(self.server)
|
||||
else:
|
||||
conn = poplib.POP3_SSL(self.server, int(self.port))
|
||||
else:
|
||||
if self.port == '':
|
||||
conn = poplib.POP3(self.server)
|
||||
else:
|
||||
conn = poplib.POP3(self.server, int(self.port))
|
||||
|
||||
# TODO : Use STARTTLS when Mailnag has been migrated to python 3
|
||||
# (analogous to get_IMAP_connection).
|
||||
logging.warning("Using unencrypted connection for account '%s'" % self.name)
|
||||
|
||||
conn.getwelcome()
|
||||
conn.user(self.user)
|
||||
conn.pass_(self.password)
|
||||
|
||||
self._conn = conn
|
||||
except:
|
||||
try:
|
||||
if conn != None:
|
||||
conn.quit()
|
||||
except: pass
|
||||
raise # re-throw exception
|
||||
|
||||
self._conn = self.backend.get_connection(use_existing)
|
||||
return self._conn
|
||||
|
||||
|
||||
@@ -291,9 +193,9 @@ class AccountManager:
|
||||
password = self._credentialstore.get(CREDENTIAL_KEY % (protocol, user, server))
|
||||
|
||||
if imap:
|
||||
backend = ImapBackend()
|
||||
backend = ImapBackend(name, user, password, '', server, port, ssl, folders)
|
||||
else:
|
||||
bakcend = Pop3Backend()
|
||||
backend = Pop3Backend(name, user, password, '', server, port, ssl)
|
||||
|
||||
acc = Account(enabled, name, user, password, '', server, port, ssl, imap, idle, folders, backend)
|
||||
self._accounts.append(acc)
|
||||
|
||||
@@ -27,6 +27,8 @@ gi.require_version('GLib', '2.0')
|
||||
|
||||
from gi.repository import GObject, GLib, Gtk
|
||||
from thread import start_new_thread
|
||||
from Mailnag.backends.imap import ImapBackend
|
||||
from Mailnag.backends.pop3 import Pop3Backend
|
||||
from Mailnag.common.dist_cfg import PACKAGE_NAME
|
||||
from Mailnag.common.i18n import _
|
||||
from Mailnag.common.utils import get_data_file, splitstr
|
||||
@@ -165,6 +167,13 @@ class AccountDialog:
|
||||
acc.port = p[2]
|
||||
else:
|
||||
raise Exception('Unknown account type')
|
||||
|
||||
# Create backend
|
||||
# TODO: This is duplicate code with AccountManager.
|
||||
if acc.imap:
|
||||
acc.backend = ImapBackend(acc.name, acc.user, acc.password, '', acc.server, acc.port, acc.ssl, acc.folders)
|
||||
else:
|
||||
acc.backend = Pop3Backend(acc.name, acc.user, acc.password, '', acc.server, acc.port, acc.ssl)
|
||||
|
||||
|
||||
def _get_selected_folders(self):
|
||||
|
||||
Reference in New Issue
Block a user