"Fossies" - the Fresh Open Source Software Archive

Member "getmail-5.16/getmailcore/retrievers.py" (31 Oct 2021, 23086 Bytes) of package /linux/misc/getmail-5.16.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "retrievers.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 5.15_vs_5.16.

    1 #!/usr/bin/env python2
    2 '''Classes implementing retrievers (message sources getmail can retrieve mail
    3 from).
    4 
    5 Currently implemented:
    6 
    7   SimplePOP3Retriever
    8   SimplePOP3SSLRetriever
    9   BrokenUIDLPOP3Retriever
   10   BrokenUIDLPOP3SSLRetriever
   11   MultidropPOP3Retriever
   12   MultidropPOP3SSLRetriever
   13   MultidropSDPSRetriever
   14   SimpleIMAPRetriever -- IMAP, as a protocol, is a FPOS, and it shows.
   15     The Python standard library module imaplib leaves much up to
   16     the user because of this.
   17   SimpleIMAPSSLRetriever - the above, for IMAP-over-SSL.
   18   MultidropIMAPRetriever
   19   MultidropIMAPSSLRetriever
   20 '''
   21 
   22 __all__ = [
   23     'SimplePOP3Retriever',
   24     'SimplePOP3SSLRetriever',
   25     'BrokenUIDLPOP3Retriever',
   26     'BrokenUIDLPOP3SSLRetriever',
   27     'MultidropPOP3Retriever',
   28     'MultidropPOP3SSLRetriever',
   29     'MultidropSDPSRetriever',
   30     'SimpleIMAPRetriever',
   31     'SimpleIMAPSSLRetriever',
   32     'MultidropIMAPRetriever',
   33     'MultidropIMAPSSLRetriever',
   34 ]
   35 
   36 import os
   37 import poplib
   38 import imaplib
   39 import types
   40 
   41 from getmailcore.exceptions import *
   42 from getmailcore.constants import *
   43 from getmailcore.utilities import *
   44 from getmailcore.baseclasses import *
   45 from getmailcore._retrieverbases import *
   46 
   47 
   48 #
   49 # Functional classes
   50 #
   51 
   52 #######################################
   53 class SimplePOP3Retriever(POP3RetrieverBase, POP3initMixIn):
   54     '''Retriever class for single-user POP3 mailboxes.
   55     '''
   56     _confitems = (
   57         ConfInstance(name='configparser', required=False),
   58         ConfDirectory(name='getmaildir', required=False, default='~/.getmail/'),
   59 
   60         ConfInt(name='timeout', required=False, default=180),
   61         ConfString(name='server'),
   62         ConfInt(name='port', required=False, default=110),
   63         ConfString(name='username'),
   64         ConfPassword(name='password', required=False, default=None),
   65         ConfTupleOfStrings(name='password_command', required=False, default=()),
   66         ConfBool(name='use_apop', required=False, default=False),
   67         ConfBool(name='delete_dup_msgids', required=False, default=False),
   68     )
   69     received_from = None
   70     received_with = 'POP3'
   71     received_by = localhostname()
   72 
   73     def __str__(self):
   74         self.log.trace()
   75         return 'SimplePOP3Retriever:%s@%s:%s' % (
   76             self.conf.get('username', 'username'),
   77             self.conf.get('server', 'server'),
   78             self.conf.get('port', 'port')
   79         )
   80 
   81     def showconf(self):
   82         self.log.trace()
   83         self.log.info('SimplePOP3Retriever(%s)' % self._confstring()
   84                       + os.linesep)
   85 
   86 #######################################
   87 class SimplePOP3SSLRetriever(POP3RetrieverBase, POP3SSLinitMixIn):
   88     '''Retriever class for single-user POP3-over-SSL mailboxes.
   89     '''
   90     _confitems = (
   91         ConfInstance(name='configparser', required=False),
   92         ConfDirectory(name='getmaildir', required=False, default='~/.getmail/'),
   93 
   94         ConfInt(name='timeout', required=False, default=180),
   95         ConfString(name='server'),
   96         ConfInt(name='port', required=False, default=POP3_ssl_port),
   97         ConfString(name='username'),
   98         ConfPassword(name='password', required=False, default=None),
   99         ConfTupleOfStrings(name='password_command', required=False, default=()),
  100         ConfBool(name='use_apop', required=False, default=False),
  101         ConfBool(name='delete_dup_msgids', required=False, default=False),
  102         ConfFile(name='keyfile', required=False, default=None),
  103         ConfFile(name='certfile', required=False, default=None),
  104         ConfFile(name='ca_certs', required=False, default=None),
  105         ConfTupleOfStrings(name='ssl_fingerprints', required=False, default=()),
  106         ConfString(name='ssl_version', required=False, default=None),
  107         ConfString(name='ssl_ciphers', required=False, default=None),
  108         ConfString(name='ssl_cert_hostname', required=False, default=None),
  109     )
  110     received_from = None
  111     received_with = 'POP3-SSL'
  112     received_by = localhostname()
  113 
  114     def __str__(self):
  115         self.log.trace()
  116         return 'SimplePOP3SSLRetriever:%s@%s:%s' % (
  117             self.conf.get('username', 'username'),
  118             self.conf.get('server', 'server'),
  119             self.conf.get('port', 'port')
  120         )
  121 
  122     def showconf(self):
  123         self.log.trace()
  124         self.log.info('SimplePOP3SSLRetriever(%s)' % self._confstring()
  125                       + os.linesep)
  126 
  127 #######################################
  128 class BrokenUIDLPOP3RetrieverBase(POP3RetrieverBase):
  129     '''Retriever base class for single-user POP3 mailboxes on servers that do
  130     not properly assign unique IDs to messages.  Since with these broken servers
  131     we cannot rely on UIDL, we have to use message numbers, which are unique
  132     within a POP3 session, but which change across sessions.  This class
  133     therefore can not be used to leave old mail on the server and download only
  134     new mail.
  135     '''
  136     received_from = None
  137     received_by = localhostname()
  138 
  139     def _read_oldmailfile(self):
  140         '''Force list of old messages to be empty by making this a no-op, so
  141         duplicated IDs are always treated as new messages.'''
  142         self.log.trace()
  143 
  144     def write_oldmailfile(self, unused, **kwargs):
  145         '''Short-circuit writing the oldmail file.'''
  146         self.log.trace()
  147 
  148     def _getmsglist(self):
  149         '''Don't rely on UIDL; instead, use just the message number.'''
  150         self.log.trace()
  151         try:
  152             (response, msglist, octets) = self.conn.list()
  153             for line in msglist:
  154                 msgnum = int(line.split()[0])
  155                 msgsize = int(line.split()[1])
  156                 self.msgnum_by_msgid[msgnum] = msgnum
  157                 self.msgid_by_msgnum[msgnum] = msgnum
  158                 self.msgsizes[msgnum] = msgsize
  159             self.sorted_msgnum_msgid = sorted(self.msgid_by_msgnum.items())
  160         except poplib.error_proto, o:
  161             raise getmailOperationError('POP error (%s)' % o)
  162         self.gotmsglist = True
  163 
  164 #######################################
  165 class BrokenUIDLPOP3Retriever(BrokenUIDLPOP3RetrieverBase, POP3initMixIn):
  166     '''For broken POP3 servers without SSL.
  167     '''
  168     _confitems = (
  169         ConfInstance(name='configparser', required=False),
  170         ConfDirectory(name='getmaildir', required=False, default='~/.getmail/'),
  171 
  172         ConfInt(name='timeout', required=False, default=180),
  173         ConfString(name='server'),
  174         ConfInt(name='port', required=False, default=110),
  175         ConfString(name='username'),
  176         ConfPassword(name='password', required=False, default=None),
  177         ConfTupleOfStrings(name='password_command', required=False, default=()),
  178         ConfBool(name='use_apop', required=False, default=False),
  179     )
  180     received_with = 'POP3'
  181 
  182     def __str__(self):
  183         self.log.trace()
  184         return 'BrokenUIDLPOP3Retriever:%s@%s:%s' % (
  185             self.conf.get('username', 'username'),
  186             self.conf.get('server', 'server'),
  187             self.conf.get('port', 'port')
  188         )
  189 
  190     def showconf(self):
  191         self.log.trace()
  192         self.log.info('BrokenUIDLPOP3Retriever(%s)' % self._confstring()
  193                       + os.linesep)
  194 
  195 #######################################
  196 class BrokenUIDLPOP3SSLRetriever(BrokenUIDLPOP3RetrieverBase, POP3SSLinitMixIn):
  197     '''For broken POP3 servers with SSL.
  198     '''
  199     _confitems = (
  200         ConfInstance(name='configparser', required=False),
  201         ConfDirectory(name='getmaildir', required=False, default='~/.getmail/'),
  202 
  203         ConfInt(name='timeout', required=False, default=180),
  204         ConfString(name='server'),
  205         ConfInt(name='port', required=False, default=POP3_ssl_port),
  206         ConfString(name='username'),
  207         ConfPassword(name='password', required=False, default=None),
  208         ConfTupleOfStrings(name='password_command', required=False, default=()),
  209         ConfBool(name='use_apop', required=False, default=False),
  210         ConfFile(name='keyfile', required=False, default=None),
  211         ConfFile(name='certfile', required=False, default=None),
  212         ConfFile(name='ca_certs', required=False, default=None),
  213         ConfTupleOfStrings(name='ssl_fingerprints', required=False, default=()),
  214         ConfString(name='ssl_version', required=False, default=None),
  215         ConfString(name='ssl_ciphers', required=False, default=None),
  216         ConfString(name='ssl_cert_hostname', required=False, default=None),
  217     )
  218     received_with = 'POP3-SSL'
  219 
  220     def __str__(self):
  221         self.log.trace()
  222         return 'BrokenUIDLPOP3SSLRetriever:%s@%s:%s' % (
  223             self.conf.get('username', 'username'),
  224             self.conf.get('server', 'server'),
  225             self.conf.get('port', 'port')
  226         )
  227 
  228     def showconf(self):
  229         self.log.trace()
  230         self.log.info('BrokenUIDLPOP3SSLRetriever(%s)' % self._confstring()
  231                       + os.linesep)
  232 
  233 #######################################
  234 class MultidropPOP3Retriever(MultidropPOP3RetrieverBase, POP3initMixIn):
  235     '''Retriever class for multi-drop POP3 mailboxes.
  236     '''
  237     _confitems = (
  238         ConfInstance(name='configparser', required=False),
  239         ConfDirectory(name='getmaildir', required=False, default='~/.getmail/'),
  240 
  241         ConfInt(name='timeout', required=False, default=180),
  242         ConfString(name='server'),
  243         ConfInt(name='port', required=False, default=110),
  244         ConfString(name='username'),
  245         ConfPassword(name='password', required=False, default=None),
  246         ConfTupleOfStrings(name='password_command', required=False, default=()),
  247         ConfBool(name='use_apop', required=False, default=False),
  248         ConfString(name='envelope_recipient'),
  249     )
  250     received_from = None
  251     received_with = 'POP3'
  252     received_by = localhostname()
  253 
  254     def __str__(self):
  255         self.log.trace()
  256         return 'MultidropPOP3Retriever:%s@%s:%s' % (
  257             self.conf.get('username', 'username'),
  258             self.conf.get('server', 'server'),
  259             self.conf.get('port', 'port')
  260         )
  261 
  262     def showconf(self):
  263         self.log.trace()
  264         self.log.info('MultidropPOP3Retriever(%s)' % self._confstring()
  265                       + os.linesep)
  266 
  267 #######################################
  268 class MultidropPOP3SSLRetriever(MultidropPOP3RetrieverBase, POP3SSLinitMixIn):
  269     '''Retriever class for multi-drop POP3-over-SSL mailboxes.
  270     '''
  271     _confitems = (
  272         ConfInstance(name='configparser', required=False),
  273         ConfDirectory(name='getmaildir', required=False, default='~/.getmail/'),
  274 
  275         ConfInt(name='timeout', required=False, default=180),
  276         ConfString(name='server'),
  277         ConfInt(name='port', required=False, default=POP3_ssl_port),
  278         ConfString(name='username'),
  279         ConfPassword(name='password', required=False, default=None),
  280         ConfTupleOfStrings(name='password_command', required=False, default=()),
  281         ConfBool(name='use_apop', required=False, default=False),
  282         ConfString(name='envelope_recipient'),
  283         ConfFile(name='keyfile', required=False, default=None),
  284         ConfFile(name='certfile', required=False, default=None),
  285         ConfFile(name='ca_certs', required=False, default=None),
  286         ConfTupleOfStrings(name='ssl_fingerprints', required=False, default=()),
  287         ConfString(name='ssl_version', required=False, default=None),
  288         ConfString(name='ssl_ciphers', required=False, default=None),
  289         ConfString(name='ssl_cert_hostname', required=False, default=None),
  290     )
  291     received_from = None
  292     received_with = 'POP3-SSL'
  293     received_by = localhostname()
  294 
  295     def __str__(self):
  296         self.log.trace()
  297         return 'MultidropPOP3SSLRetriever:%s@%s:%s' % (
  298             self.conf.get('username', 'username'),
  299             self.conf.get('server', 'server'),
  300             self.conf.get('port', 'port')
  301         )
  302 
  303     def showconf(self):
  304         self.log.trace()
  305         self.log.info('MultidropPOP3SSLRetriever(%s)' % self._confstring()
  306                       + os.linesep)
  307 
  308 #######################################
  309 class MultidropSDPSRetriever(SimplePOP3Retriever, POP3initMixIn):
  310     '''Retriever class for multi-drop SDPS (demon.co.uk) mailboxes.
  311 
  312     Extend POP3 class to include support for Demon's protocol extensions, known
  313     as SDPS.  A non-standard command (*ENV) is used to retrieve the message
  314     envelope.  See http://www.demon.net/helpdesk/products/mail/sdps-tech.shtml
  315     for details.
  316 
  317     Support originally requested by Paul Clifford for getmail v.2/3.
  318     '''
  319     _confitems = (
  320         ConfInstance(name='configparser', required=False),
  321         ConfDirectory(name='getmaildir', required=False, default='~/.getmail/'),
  322 
  323         ConfInt(name='timeout', required=False, default=180),
  324         ConfString(name='server'),
  325         ConfInt(name='port', required=False, default=110),
  326         ConfString(name='username'),
  327         ConfPassword(name='password', required=False, default=None),
  328         ConfTupleOfStrings(name='password_command', required=False, default=()),
  329         # Demon apparently doesn't support APOP
  330         ConfBool(name='use_apop', required=False, default=False),
  331     )
  332 
  333     received_from = None
  334     received_with = 'SDPS'
  335     received_by = localhostname()
  336 
  337     def __str__(self):
  338         self.log.trace()
  339         return 'MultidropSDPSRetriever:%s@%s:%s' % (
  340             self.conf.get('username', 'username'),
  341             self.conf.get('server', 'server'),
  342             self.conf.get('port', 'port')
  343         )
  344 
  345     def showconf(self):
  346         self.log.trace()
  347         self.log.info('MultidropSDPSRetriever(%s)' % self._confstring()
  348                       + os.linesep)
  349 
  350     def _getmsgbyid(self, msgid):
  351         self.log.trace()
  352         msg = SimplePOP3Retriever._getmsgbyid(self, msgid)
  353 
  354         # The magic of SDPS is the "*ENV" command.  Implement it:
  355         try:
  356             msgnum = self._getmsgnumbyid(msgid)
  357             resp, lines, octets = self.conn._longcmd('*ENV %i' % msgnum)
  358         except poplib.error_proto, o:
  359             raise getmailConfigurationError(
  360                 'server does not support *ENV (%s)' % o
  361             )
  362         if len(lines) < 4:
  363             raise getmailOperationError('short *ENV response (%s)' % lines)
  364         msg.sender = lines[2]
  365         msg.recipient = lines[3]
  366         return msg
  367 
  368 #######################################
  369 class SimpleIMAPRetriever(IMAPRetrieverBase, IMAPinitMixIn):
  370     '''Retriever class for single-user IMAPv4 mailboxes.
  371     '''
  372     _confitems = (
  373         ConfInstance(name='configparser', required=False),
  374         ConfDirectory(name='getmaildir', required=False, default='~/.getmail/'),
  375 
  376         ConfInt(name='timeout', required=False, default=180),
  377         ConfString(name='server'),
  378         ConfInt(name='port', required=False, default=imaplib.IMAP4_PORT),
  379         ConfString(name='username'),
  380         ConfPassword(name='password', required=False, default=None),
  381         ConfTupleOfStrings(name='password_command', required=False, default=()),
  382         ConfTupleOfUnicode(name='mailboxes', required=False,
  383                            default="('INBOX', )", allow_specials=('ALL',)),
  384         ConfBool(name='use_peek', required=False, default=True),
  385         ConfString(name='move_on_delete', required=False, default=None),
  386         ConfBool(name='record_mailbox', required=False, default=True),
  387         # imaplib.IMAP4.login_cram_md5() requires the (unimplemented)
  388         # .authenticate(), so we can't do this yet (?).
  389         ConfBool(name='use_cram_md5', required=False, default=False),
  390         ConfBool(name='use_kerberos', required=False, default=False),
  391         ConfBool(name='use_xoauth2', required=False, default=False),
  392     )
  393     received_from = None
  394     received_with = 'IMAP4'
  395     received_by = localhostname()
  396 
  397     def __str__(self):
  398         self.log.trace()
  399         return 'SimpleIMAPRetriever:%s@%s:%s' % (
  400             self.conf.get('username', 'username'),
  401             self.conf.get('server', 'server'),
  402             self.conf.get('port', 'port')
  403         )
  404 
  405     def showconf(self):
  406         self.log.trace()
  407         self.log.info('SimpleIMAPRetriever(%s)' % self._confstring()
  408                       + os.linesep)
  409 
  410 #######################################
  411 class SimpleIMAPSSLRetriever(IMAPRetrieverBase, IMAPSSLinitMixIn):
  412     '''Retriever class for single-user IMAPv4-over-SSL mailboxes.
  413     '''
  414     _confitems = (
  415         ConfInstance(name='configparser', required=False),
  416         ConfDirectory(name='getmaildir', required=False, default='~/.getmail/'),
  417 
  418         # socket.ssl() and socket timeouts were incompatible in Python 2.3;
  419         # if you have problems, comment this line out
  420         ConfInt(name='timeout', required=False, default=180),
  421         ConfString(name='server'),
  422         ConfInt(name='port', required=False, default=imaplib.IMAP4_SSL_PORT),
  423         ConfString(name='username'),
  424         ConfPassword(name='password', required=False, default=None),
  425         ConfTupleOfStrings(name='password_command', required=False, default=()),
  426         ConfTupleOfUnicode(name='mailboxes', required=False,
  427                            default="('INBOX', )", allow_specials=('ALL',)),
  428         ConfBool(name='use_peek', required=False, default=True),
  429         ConfString(name='move_on_delete', required=False, default=None),
  430         ConfBool(name='record_mailbox', required=False, default=True),
  431         ConfFile(name='keyfile', required=False, default=None),
  432         ConfFile(name='certfile', required=False, default=None),
  433         ConfFile(name='ca_certs', required=False, default=None),
  434         ConfTupleOfStrings(name='ssl_fingerprints', required=False, default=()),
  435         ConfString(name='ssl_version', required=False, default=None),
  436         ConfString(name='ssl_ciphers', required=False, default=None),
  437         # imaplib.IMAP4.login_cram_md5() requires the (unimplemented)
  438         # .authenticate(), so we can't do this yet (?).
  439         ConfBool(name='use_cram_md5', required=False, default=False),
  440         ConfBool(name='use_kerberos', required=False, default=False),
  441         ConfBool(name='use_xoauth2', required=False, default=False),
  442         ConfString(name='ssl_cert_hostname', required=False, default=None),
  443     )
  444     received_from = None
  445     received_with = 'IMAP4-SSL'
  446     received_by = localhostname()
  447 
  448     def __str__(self):
  449         self.log.trace()
  450         return 'SimpleIMAPSSLRetriever:%s@%s:%s' % (
  451             self.conf.get('username', 'username'),
  452             self.conf.get('server', 'server'),
  453             self.conf.get('port', 'port')
  454         )
  455 
  456     def showconf(self):
  457         self.log.trace()
  458         self.log.info('SimpleIMAPSSLRetriever(%s)' % self._confstring()
  459                       + os.linesep)
  460 
  461 #######################################
  462 class MultidropIMAPRetriever(MultidropIMAPRetrieverBase, IMAPinitMixIn):
  463     '''Retriever class for multi-drop IMAPv4 mailboxes.
  464     '''
  465     _confitems = (
  466         ConfInstance(name='configparser', required=False),
  467         ConfDirectory(name='getmaildir', required=False, default='~/.getmail/'),
  468 
  469         ConfInt(name='timeout', required=False, default=180),
  470         ConfString(name='server'),
  471         ConfInt(name='port', required=False, default=imaplib.IMAP4_PORT),
  472         ConfString(name='username'),
  473         ConfPassword(name='password', required=False, default=None),
  474         ConfTupleOfStrings(name='password_command', required=False, default=()),
  475         ConfTupleOfUnicode(name='mailboxes', required=False,
  476                            default="('INBOX', )", allow_specials=('ALL',)),
  477         ConfBool(name='use_peek', required=False, default=True),
  478         ConfString(name='move_on_delete', required=False, default=None),
  479         ConfBool(name='record_mailbox', required=False, default=True),
  480         # imaplib.IMAP4.login_cram_md5() requires the (unimplemented)
  481         # .authenticate(), so we can't do this yet (?).
  482         ConfBool(name='use_cram_md5', required=False, default=False),
  483         ConfBool(name='use_kerberos', required=False, default=False),
  484         ConfBool(name='use_xoauth2', required=False, default=False),
  485         ConfString(name='envelope_recipient'),
  486     )
  487     received_from = None
  488     received_with = 'IMAP4'
  489     received_by = localhostname()
  490 
  491     def __str__(self):
  492         self.log.trace()
  493         return 'MultidropIMAPRetriever:%s@%s:%s' % (
  494             self.conf.get('username', 'username'),
  495             self.conf.get('server', 'server'),
  496             self.conf.get('port', 'port')
  497         )
  498 
  499     def showconf(self):
  500         self.log.trace()
  501         self.log.info('MultidropIMAPRetriever(%s)' % self._confstring()
  502                       + os.linesep)
  503 
  504 #######################################
  505 class MultidropIMAPSSLRetriever(MultidropIMAPRetrieverBase, IMAPSSLinitMixIn):
  506     '''Retriever class for multi-drop IMAPv4-over-SSL mailboxes.
  507     '''
  508     _confitems = (
  509         ConfInstance(name='configparser', required=False),
  510         ConfDirectory(name='getmaildir', required=False, default='~/.getmail/'),
  511 
  512         # socket.ssl() and socket timeouts were incompatible in Python 2.3;
  513         # if you have problems, comment this line out
  514         ConfInt(name='timeout', required=False, default=180),
  515         ConfString(name='server'),
  516         ConfInt(name='port', required=False, default=imaplib.IMAP4_SSL_PORT),
  517         ConfString(name='username'),
  518         ConfPassword(name='password', required=False, default=None),
  519         ConfTupleOfStrings(name='password_command', required=False, default=()),
  520         ConfTupleOfUnicode(name='mailboxes', required=False,
  521                            default="('INBOX', )", allow_specials=('ALL',)),
  522         ConfBool(name='use_peek', required=False, default=True),
  523         ConfString(name='move_on_delete', required=False, default=None),
  524         ConfBool(name='record_mailbox', required=False, default=True),
  525         ConfFile(name='keyfile', required=False, default=None),
  526         ConfFile(name='certfile', required=False, default=None),
  527         ConfFile(name='ca_certs', required=False, default=None),
  528         ConfTupleOfStrings(name='ssl_fingerprints', required=False, default=()),
  529         ConfString(name='ssl_version', required=False, default=None),
  530         ConfString(name='ssl_ciphers', required=False, default=None),
  531         # imaplib.IMAP4.login_cram_md5() requires the (unimplemented)
  532         # .authenticate(), so we can't do this yet (?).
  533         ConfBool(name='use_cram_md5', required=False, default=False),
  534         ConfBool(name='use_kerberos', required=False, default=False),
  535         ConfBool(name='use_xoauth2', required=False, default=False),
  536         ConfString(name='envelope_recipient'),
  537         ConfString(name='ssl_cert_hostname', required=False, default=None),
  538     )
  539     received_from = None
  540     received_with = 'IMAP4-SSL'
  541     received_by = localhostname()
  542 
  543     def __str__(self):
  544         self.log.trace()
  545         return 'MultidropIMAPSSLRetriever:%s@%s:%s' % (
  546             self.conf.get('username', 'username'),
  547             self.conf.get('server', 'server'),
  548             self.conf.get('port', 'port')
  549         )
  550 
  551     def showconf(self):
  552         self.log.trace()
  553         self.log.info('MultidropIMAPSSLRetriever(%s)' % self._confstring()
  554                       + os.linesep)
  555