#!/usr/bin/env python
from setuptools import setup
setup(
  name = 'cs.pop3',
  author = 'Cameron Simpson',
  author_email = 'cs@cskk.id.au',
  version = '20210407',
  url = 'https://bitbucket.org/cameron_simpson/css/commits/all',
  description =
    ('POP3 stuff, particularly a streaming downloader and a simple command line '    
 'which runs it.'),
  long_description =
    ('POP3 stuff, particularly a streaming downloader and a simple command line '    
 'which runs it.\n'    
 '\n'    
 '*Latest release 20210407*:\n'    
 'Initial PyPI release.\n'    
 '\n'    
 'I spend some time on a geostationary satellite connection,\n'    
 'where round trip ping times are over 600ms when things are good.\n'    
 '\n'    
 'My mail setup involves fetching messages from my inbox\n'    
 'for local storage in my laptop, usually using POP3.\n'    
 'The common standalone tools for this are `fetchmail` and `getmail`.\n'    
 'However, both are very subject to the link latency,\n'    
 'in that they request a message, collect it, issue a delete, then repeat.\n'    
 'On a satellite link that incurs a cost of over a second per message,\n'    
 'making catch up after a period offline a many minutes long exercise in '    
 'tedium.\n'    
 '\n'    
 "This module does something I've been meaning to do for literally years:\n"    
 'a bulk fetch. It issues `RETR`ieves for every message up front as fast as '    
 'possible.\n'    
 'A separate thread collects the messages as they are delivered\n'    
 'and issues `DELE`tes for the saved messages as soon as each is saved.\n'    
 '\n'    
 'This results in a fetch process whihc is orders of magnitude faster.\n'    
 'Even on a low latency link the throughput is much faster;\n'    
 'on the satellite it is gobsmackingly faster.\n'    
 '\n'    
 '## Class `ConnectionSpec(ConnectionSpec,builtins.tuple)`\n'    
 '\n'    
 'A specification for a POP3 connection.\n'    
 '\n'    
 '### Method `ConnectionSpec.connect(self)`\n'    
 '\n'    
 'Connect according to this `ConnectionSpec`, return the `socket`.\n'    
 '\n'    
 '### Method `ConnectionSpec.from_spec(spec)`\n'    
 '\n'    
 'Construct an instance from a connection spec string\n'    
 'of the form '    
 '[`tcp:`|`ssl:`][*user*`@`]*[tcp_host!]server_hostname*[`:`*port*].\n'    
 '\n'    
 'The optional prefixes `tcp:` and `ssl:` indicate that the connection\n'    
 'should be cleartext or SSL/TLS respectively.\n'    
 'The default is SSL/TLS.\n'    
 '\n'    
 '### Property `ConnectionSpec.netrc_entry`\n'    
 '\n'    
 'The default `NetrcEntry` for this `ConnectionSpec`.\n'    
 '\n'    
 '### Property `ConnectionSpec.password`\n'    
 '\n'    
 'The password for this connection, obtained from the `.netrc` file\n'    
 'via the key *user*`@`*host*`:`*port*.\n'    
 '\n'    
 '## Class `NetrcEntry(NetrcEntry,builtins.tuple)`\n'    
 '\n'    
 'A `namedtuple` representation of a `netrc` entry.\n'    
 '\n'    
 '### Method `NetrcEntry.by_account(account_name, netrc_hosts=None)`\n'    
 '\n'    
 'Look up an entry by the `account` field value.\n'    
 '\n'    
 '### Method `NetrcEntry.get(machine, netrc_hosts=None)`\n'    
 '\n'    
 'Look up an entry by the `machine` field value.\n'    
 '\n'    
 '## Class `POP3(cs.resources.MultiOpenMixin)`\n'    
 '\n'    
 'Simple POP3 class with support for streaming use.\n'    
 '\n'    
 '### Method `POP3.client_auth(self, user, password)`\n'    
 '\n'    
 'Perform a client authentication.\n'    
 '\n'    
 '### Method `POP3.client_begin(self)`\n'    
 '\n'    
 'Read the opening server response.\n'    
 '\n'    
 '### Method `POP3.client_bg(self, rq_line, is_multiline=False, notify=None)`\n'    
 '\n'    
 'Dispatch a request `rq_line` in the background.\n'    
 'Return a `Result` to collect the request result.\n'    
 '\n'    
 'Parameters:\n'    
 '* `rq_line`: POP3 request text, without any terminating CRLF\n'    
 '* `is_multiline`: true if a multiline response is expected,\n'    
 '  default `False`\n'    
 '* `notify`: a optional handler for `Result.notify`,\n'    
 '  applied if not `None`\n'    
 '\n'    
 '*Note*: DOES NOT flush the send stream.\n'    
 'Call `self.flush()` when a batch of requests has been submitted,\n'    
 'before trying to collect the `Result`s.\n'    
 '\n'    
 'The `Result` will receive `[etc,lines]` on success\n'    
 'where:\n'    
 '* `etc` is the trailing portion of an ok response line\n'    
 '* `lines` is a list of unstuffed text lines from the response\n'    
 '  if `is_multiline` is true, `None` otherwise\n'    
 'The `Result` gets a list instead of a tuple\n'    
 'so that a handler may clear it in order to release memory.\n'    
 '\n'    
 'Example:\n'    
 '\n'    
 "    R = self.client_bg(f'RETR {msg_n}', is_multiline=True, notify=notify)\n"    
 '\n'    
 '### Method `POP3.client_dele_bg(self, msg_n)`\n'    
 '\n'    
 'Queue a delete request for message `msg_n`,\n'    
 'return ` Result` for collection.\n'    
 '\n'    
 '### Method `POP3.client_quit_bg(self)`\n'    
 '\n'    
 'Queue a QUIT request.\n'    
 'return ` Result` for collection.\n'    
 '\n'    
 '### Method `POP3.client_retr_bg(self, msg_n, notify=None)`\n'    
 '\n'    
 'Queue a retrieve request for message `msg_n`,\n'    
 'return ` Result` for collection.\n'    
 '\n'    
 'If `notify` is not `None`, apply it to the `Result`.\n'    
 '\n'    
 '### Method `POP3.client_uidl(self)`\n'    
 '\n'    
 'Return a mapping of message number to message UID string.\n'    
 '\n'    
 '### Method `POP3.dl_bg(self, msg_n, maildir, deleRs)`\n'    
 '\n'    
 'Download message `msg_n` to Maildir `maildir`.\n'    
 'Return the `Result` for the `RETR` request.\n'    
 '\n'    
 'After a successful save,\n'    
 'queue a `DELE` for the message\n'    
 'and add its `Result` to `deleRs`.\n'    
 '\n'    
 '### Method `POP3.flush(self)`\n'    
 '\n'    
 'FLush the send stream.\n'    
 '\n'    
 '### Method `POP3.get_multiline(self)`\n'    
 '\n'    
 'Generator yielding unstuffed lines from a multiline response.\n'    
 '\n'    
 '### Method `POP3.get_ok(self)`\n'    
 '\n'    
 "Read server response, require it to be `'OK+'`.\n"    
 'Returns the `etc` part.\n'    
 '\n'    
 '### Method `POP3.get_response(self)`\n'    
 '\n'    
 'Read a server response.\n'    
 'Return `(ok,status,etc)`\n'    
 "where `ok` is true if `status` is `'+OK'`, false otherwise;\n"    
 '`status` is the status word\n'    
 'and `etc` is the following text.\n'    
 '\n'    
 '### Method `POP3.readline(self)`\n'    
 '\n'    
 'Read a CRLF terminated line from `self.recvf`.\n'    
 'Return the text preceeding the CRLF.\n'    
 'Return `None` at EOF.\n'    
 '\n'    
 '### Method `POP3.readlines(self)`\n'    
 '\n'    
 'Generator yielding lines from `self.recf`.\n'    
 '\n'    
 '### Method `POP3.sendline(self, line, do_flush=False)`\n'    
 '\n'    
 'Send a line (excluding its terminating CRLF).\n'    
 'If `do_flush` is true (default `False`)\n'    
 'also flush the sending stream.\n'    
 '\n'    
 '### Method `POP3.shutdown(*a, **kw)`\n'    
 '\n'    
 'Quit and disconnect.\n'    
 '\n'    
 '### Method `POP3.startup(*a, **kw)`\n'    
 '\n'    
 'Connect to the server and log in.\n'    
 '\n'    
 '## Class `POP3Command(cs.cmdutils.BaseCommand)`\n'    
 '\n'    
 'Command line usage:\n'    
 '\n'    
 'Usage: pop3 subcommand [...]\n'    
 '  Subcommands:\n'    
 '    dl [{ssl,tcp}:]{netrc_account|[user@]host[!sni_name][:port]} maildir\n'    
 '    help [subcommand-names...]\n'    
 '      Print the help for the named subcommands,\n'    
 '      or for all subcommands if no names are specified.\n'    
 '\n'    
 '### Method `POP3Command.cmd_dl(argv)`\n'    
 '\n'    
 'Collect messages from a POP3 server and deliver to a Maildir.\n'    
 '\n'    
 'Usage: {cmd} [{{ssl,tcp}}:]{{netrc_account|[user@]host[!sni_name][:port]}} '    
 'maildir\n'    
 '\n'    
 '# Release Log\n'    
 '\n'    
 '\n'    
 '\n'    
 '*Release 20210407*:\n'    
 'Initial PyPI release.'),
  classifiers = ['Programming Language :: Python', 'Programming Language :: Python :: 3', 'Environment :: Console', 'Topic :: Communications :: Email :: Post-Office :: POP3', 'Topic :: Internet', 'Topic :: Utilities', 'Development Status :: 4 - Beta', 'Intended Audience :: Developers', 'Operating System :: OS Independent', 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)'],
  install_requires = ['cs.cmdutils>=20210407', 'cs.lex', 'cs.logutils', 'cs.pfx', 'cs.queues', 'cs.resources', 'cs.result>=20210407', 'cs.threads'],
  keywords = ['python3'],
  license = 'GNU General Public License v3 or later (GPLv3+)',
  long_description_content_type = 'text/markdown',
  package_dir = {'': 'lib/python'},
  py_modules = ['cs.pop3'],
)
