def test_hostnames(self): """ CompleteHostnames produces zsh shell-code that completes hostnames. """ c = usage.CompleteHostnames() out = c._shellCode('some-option', usage._ZSH) self.assertEqual(out, ':some-option:_hosts') c = usage.CompleteHostnames(descr='some action', repeat=True) out = c._shellCode('some-option', usage._ZSH) self.assertEqual(out, '*:some action:_hosts')
class Options(usage.Options): synopsis = "[options]" longdesc = "Port Forwarder." optParameters = [ ["port", "p", "6666", "Set the port number."], ["host", "h", "localhost", "Set the host."], ["dest_port", "d", 6665, "Set the destination port."], ] compData = usage.Completions(optActions={"host": usage.CompleteHostnames()})
class MyOptions(usage.Options): optParameters = [("user", "u", "guest", "username"), ("password", "w", "guest"), ("service", "s", "twisted.manhole", "PB Service"), ("host", "h", "localhost"), ("port", "p", str(pbportno)), ("perspective", "P", "", "PB Perspective to ask for " "(if different than username)")] compData = usage.Completions(optActions={ "host": usage.CompleteHostnames(), "user": usage.CompleteUsernames() })
class Options(usage.Options): synopsis = "[options]" longdesc = 'Fix Client.' optParameters = [ ["hostname", "h", "localhost", "Set the host to connect to."], ["port", "p", 8443, "Set the destination port."], ['spec', 's', None, 'Fix xml spec file'], ['heartbeat_int', 'H', 30, 'Heartbeat Interval'], ['target_comp_id', 'T', None, 'TargetCompId'], ['sender_comp_id', 'S', None, 'SenderCompID'], ['password', 'P', None, 'Password'], ['instrument_id', 'i', None, 'Instrument/security id'], ['market_depth', 'd', 1, 'Market depth'], ['metrics_interval', 'm', 5, 'Interval to record metrics (sec)'], ['statsdir', 'o', os.getcwd(), 'irectory to stora stats output'], ] compData = usage.Completions( optActions={"hostname": usage.CompleteHostnames()})
class Options(usage.Options): synopsis = "[options]" groups = None servers = None subscriptions = None optParameters = [["port", "p", "119", "Listen port"], ["interface", "i", "", "Interface to which to bind"], ["datadir", "d", "news.db", "Root data storage path"], [ "mailhost", "m", "localhost", "Host of SMTP server to use" ]] compData = usage.Completions( optActions={ "datadir": usage.CompleteDirs(), "mailhost": usage.CompleteHostnames(), "interface": usage.CompleteNetInterfaces() }) def __init__(self): usage.Options.__init__(self) self.groups = [] self.servers = [] self.subscriptions = [] def opt_group(self, group): """The name of a newsgroup to carry.""" self.groups.append([group, None]) def opt_moderator(self, moderator): """The email of the moderator for the most recently passed group.""" self.groups[-1][1] = moderator def opt_subscription(self, group): """A newsgroup to list as a recommended subscription.""" self.subscriptions.append(group) def opt_server(self, server): """The address of a Usenet server to pass messages to and receive messages from.""" self.servers.append(server)
class Options(usage.Options, strcred.AuthOptionMixin): """ An options list parser for twistd mail. @type synopsis: L{bytes} @ivar synopsis: A description of options for use in the usage message. @type optParameters: L{list} of L{list} of (0) L{bytes}, (1) L{bytes}, (2) L{object}, (3) L{bytes}, (4) L{None} or callable which takes L{bytes} and returns L{object} @ivar optParameters: Information about supported parameters. See L{Options <twisted.python.usage.Options>} for details. @type optFlags: L{list} of L{list} of (0) L{bytes}, (1) L{bytes} or L{None}, (2) L{bytes} @ivar optFlags: Information about supported flags. See L{Options <twisted.python.usage.Options>} for details. @type _protoDefaults: L{dict} mapping L{bytes} to L{int} @ivar _protoDefaults: A mapping of default service to port. @type compData: L{Completions <usage.Completions>} @ivar compData: Metadata for the shell tab completion system. @type longdesc: L{bytes} @ivar longdesc: A long description of the plugin for use in the usage message. @type service: L{MailService} @ivar service: The email service. @type last_domain: L{IDomain} provider or L{None} @ivar last_domain: The most recently specified domain. """ synopsis = "[options]" optParameters = [ [ "relay", "R", None, "Relay messages according to their envelope 'To', using " "the given path as a queue directory." ], [ "hostname", "H", None, "The hostname by which to identify this server." ], ] optFlags = [ ["esmtp", "E", "Use RFC 1425/1869 SMTP extensions"], [ "disable-anonymous", None, "Disallow non-authenticated SMTP connections" ], ["no-pop3", None, "Disable the default POP3 server."], ["no-smtp", None, "Disable the default SMTP server."], ] _protoDefaults = { "pop3": 8110, "smtp": 8025, } compData = usage.Completions( optActions={"hostname": usage.CompleteHostnames()}) longdesc = """ An SMTP / POP3 email server plugin for twistd. Examples: 1. SMTP and POP server twistd mail --maildirdbmdomain=example.com=/tmp/example.com --user=joe=password Starts an SMTP server that only accepts emails to [email protected] and saves them to /tmp/example.com. Also starts a POP mail server which will allow a client to log in using username: [email protected] and password: password and collect any email that has been saved in /tmp/example.com. 2. SMTP relay twistd mail --relay=/tmp/mail_queue Starts an SMTP server that accepts emails to any email address and relays them to an appropriate remote SMTP server. Queued emails will be temporarily stored in /tmp/mail_queue. """ def __init__(self): """ Parse options and create a mail service. """ usage.Options.__init__(self) self.service = mail.MailService() self.last_domain = None for service in self._protoDefaults: self[service] = [] def addEndpoint(self, service, description): """ Add an endpoint to a service. @type service: L{bytes} @param service: A service, either C{b'smtp'} or C{b'pop3'}. @type description: L{bytes} @param description: An endpoint description string or a TCP port number. """ from twisted.internet import reactor self[service].append(endpoints.serverFromString(reactor, description)) def opt_pop3(self, description): """ Add a POP3 port listener on the specified endpoint. You can listen on multiple ports by specifying multiple --pop3 options. """ self.addEndpoint('pop3', description) opt_p = opt_pop3 def opt_smtp(self, description): """ Add an SMTP port listener on the specified endpoint. You can listen on multiple ports by specifying multiple --smtp options. """ self.addEndpoint('smtp', description) opt_s = opt_smtp def opt_default(self): """ Make the most recently specified domain the default domain. """ if self.last_domain: self.service.addDomain('', self.last_domain) else: raise usage.UsageError( "Specify a domain before specifying using --default") opt_D = opt_default def opt_maildirdbmdomain(self, domain): """ Generate an SMTP/POP3 virtual domain. This option requires an argument of the form 'NAME=PATH' where NAME is the DNS domain name for which email will be accepted and where PATH is a the filesystem path to a Maildir folder. [Example: 'example.com=/tmp/example.com'] """ try: name, path = domain.split('=') except ValueError: raise usage.UsageError( "Argument to --maildirdbmdomain must be of the form 'name=path'" ) self.last_domain = maildir.MaildirDirdbmDomain(self.service, os.path.abspath(path)) self.service.addDomain(name, self.last_domain) opt_d = opt_maildirdbmdomain def opt_user(self, user_pass): """ Add a user and password to the last specified domain. """ try: user, password = user_pass.split('=', 1) except ValueError: raise usage.UsageError( "Argument to --user must be of the form 'user=password'") if self.last_domain: self.last_domain.addUser(user, password) else: raise usage.UsageError("Specify a domain before specifying users") opt_u = opt_user def opt_bounce_to_postmaster(self): """ Send undeliverable messages to the postmaster. """ self.last_domain.postmaster = 1 opt_b = opt_bounce_to_postmaster def opt_aliases(self, filename): """ Specify an aliases(5) file to use for the last specified domain. """ if self.last_domain is not None: if mail.IAliasableDomain.providedBy(self.last_domain): aliases = alias.loadAliasFile(self.service.domains, filename) self.last_domain.setAliasGroup(aliases) self.service.monitor.monitorFile( filename, AliasUpdater(self.service.domains, self.last_domain)) else: raise usage.UsageError("%s does not support alias files" % (self.last_domain.__class__.__name__, )) else: raise usage.UsageError( "Specify a domain before specifying aliases") opt_A = opt_aliases def _getEndpoints(self, reactor, service): """ Return a list of endpoints for the specified service, constructing defaults if necessary. If no endpoints were configured for the service and the protocol was not explicitly disabled with a I{--no-*} option, a default endpoint for the service is created. @type reactor: L{IReactorTCP <twisted.internet.interfaces.IReactorTCP>} provider @param reactor: If any endpoints are created, the reactor with which they are created. @type service: L{bytes} @param service: The type of service for which to retrieve endpoints, either C{b'pop3'} or C{b'smtp'}. @rtype: L{list} of L{IStreamServerEndpoint <twisted.internet.interfaces.IStreamServerEndpoint>} provider @return: The endpoints for the specified service as configured by the command line parameters. """ if self[service]: # If there are any services set up, just return those. return self[service] elif self['no-' + service]: # If there are no services, but the service was explicitly disabled, # return nothing. return [] else: # Otherwise, return the old default service. return [ endpoints.TCP4ServerEndpoint(reactor, self._protoDefaults[service]) ] def postOptions(self): """ Check the validity of the specified set of options and configure authentication. @raise UsageError: When the set of options is invalid. """ from twisted.internet import reactor if self['esmtp'] and self['hostname'] is None: raise usage.UsageError("--esmtp requires --hostname") # If the --auth option was passed, this will be present -- otherwise, # it won't be, which is also a perfectly valid state. if 'credCheckers' in self: for ch in self['credCheckers']: self.service.smtpPortal.registerChecker(ch) if not self['disable-anonymous']: self.service.smtpPortal.registerChecker( checkers.AllowAnonymousAccess()) anything = False for service in self._protoDefaults: self[service] = self._getEndpoints(reactor, service) if self[service]: anything = True if not anything: raise usage.UsageError("You cannot disable all protocols")
class Options(usage.Options, strcred.AuthOptionMixin): synopsis = "[options]" optParameters = [ [ "pop3s", "S", 0, "Port to start the POP3-over-SSL server on (0 to disable). " "DEPRECATED: use " "'--pop3 ssl:port:privateKey=pkey.pem:certKey=cert.pem'" ], [ "certificate", "c", None, "Certificate file to use for SSL connections. " "DEPRECATED: use " "'--pop3 ssl:port:privateKey=pkey.pem:certKey=cert.pem'" ], [ "relay", "R", None, "Relay messages according to their envelope 'To', using " "the given path as a queue directory." ], [ "hostname", "H", None, "The hostname by which to identify this server." ], ] optFlags = [ ["esmtp", "E", "Use RFC 1425/1869 SMTP extensions"], [ "disable-anonymous", None, "Disallow non-authenticated SMTP connections" ], ["no-pop3", None, "Disable the default POP3 server."], ["no-smtp", None, "Disable the default SMTP server."], ] _protoDefaults = { "pop3": 8110, "smtp": 8025, } compData = usage.Completions( optActions={ "hostname": usage.CompleteHostnames(), "certificate": usage.CompleteFiles("*.pem") }) longdesc = "This creates a mail.tap file that can be used by twistd." def __init__(self): usage.Options.__init__(self) self.service = mail.MailService() self.last_domain = None for service in self._protoDefaults: self[service] = [] def addEndpoint(self, service, description, certificate=None): """ Given a 'service' (pop3 or smtp), add an endpoint. """ self[service].append(_toEndpoint(description, certificate=certificate)) def opt_pop3(self, description): """ Add a pop3 port listener on the specified endpoint. You can listen on multiple ports by specifying multiple --pop3 options. For backwards compatibility, a bare TCP port number can be specified, but this is deprecated. [SSL Example: ssl:8995:privateKey=mycert.pem] [default: tcp:8110] """ self.addEndpoint('pop3', description) opt_p = opt_pop3 def opt_smtp(self, description): """ Add an smtp port listener on the specified endpoint. You can listen on multiple ports by specifying multiple --smtp options For backwards compatibility, a bare TCP port number can be specified, but this is deprecated. [SSL Example: ssl:8465:privateKey=mycert.pem] [default: tcp:8025] """ self.addEndpoint('smtp', description) opt_s = opt_smtp def opt_passwordfile(self, filename): """ Specify a file containing username:password login info for authenticated ESMTP connections. (DEPRECATED; see --help-auth instead) """ ch = checkers.OnDiskUsernamePasswordDatabase(filename) self.service.smtpPortal.registerChecker(ch) msg = deprecate.getDeprecationWarningString( self.opt_passwordfile, versions.Version('twisted.mail', 11, 0, 0)) warnings.warn(msg, category=DeprecationWarning, stacklevel=2) opt_P = opt_passwordfile def opt_default(self): """Make the most recently specified domain the default domain.""" if self.last_domain: self.service.addDomain('', self.last_domain) else: raise usage.UsageError( "Specify a domain before specifying using --default") opt_D = opt_default def opt_maildirdbmdomain(self, domain): """generate an SMTP/POP3 virtual domain which saves to \"path\" """ try: name, path = domain.split('=') except ValueError: raise usage.UsageError( "Argument to --maildirdbmdomain must be of the form 'name=path'" ) self.last_domain = maildir.MaildirDirdbmDomain(self.service, os.path.abspath(path)) self.service.addDomain(name, self.last_domain) opt_d = opt_maildirdbmdomain def opt_user(self, user_pass): """add a user/password to the last specified domains """ try: user, password = user_pass.split('=', 1) except ValueError: raise usage.UsageError( "Argument to --user must be of the form 'user=password'") if self.last_domain: self.last_domain.addUser(user, password) else: raise usage.UsageError("Specify a domain before specifying users") opt_u = opt_user def opt_bounce_to_postmaster(self): """undelivered mails are sent to the postmaster """ self.last_domain.postmaster = 1 opt_b = opt_bounce_to_postmaster def opt_aliases(self, filename): """Specify an aliases(5) file to use for this domain""" if self.last_domain is not None: if mail.IAliasableDomain.providedBy(self.last_domain): aliases = alias.loadAliasFile(self.service.domains, filename) self.last_domain.setAliasGroup(aliases) self.service.monitor.monitorFile( filename, AliasUpdater(self.service.domains, self.last_domain)) else: raise usage.UsageError("%s does not support alias files" % (self.last_domain.__class__.__name__, )) else: raise usage.UsageError( "Specify a domain before specifying aliases") opt_A = opt_aliases def _getEndpoints(self, reactor, service): """ Return a list of endpoints for the specified service, constructing defaults if necessary. @param reactor: If any endpoints are created, this is the reactor with which they are created. @param service: A key into self indicating the type of service to retrieve endpoints for. This is either C{"pop3"} or C{"smtp"}. @return: A C{list} of C{IServerStreamEndpoint} providers corresponding to the command line parameters that were specified for C{service}. If none were and the protocol was not explicitly disabled with a I{--no-*} option, a default endpoint for the service is created using C{self._protoDefaults}. """ if service == 'pop3' and self['pop3s'] and len(self[service]) == 1: # The single endpoint here is the POP3S service we added in # postOptions. Include the default endpoint alongside it. return self[service] + [ endpoints.TCP4ServerEndpoint(reactor, self._protoDefaults[service]) ] elif self[service]: # For any non-POP3S case, if there are any services set up, just # return those. return self[service] elif self['no-' + service]: # If there are no services, but the service was explicitly disabled, # return nothing. return [] else: # Otherwise, return the old default service. return [ endpoints.TCP4ServerEndpoint(reactor, self._protoDefaults[service]) ] def postOptions(self): from twisted.internet import reactor if self['pop3s']: if not self['certificate']: raise usage.UsageError("Cannot specify --pop3s without " "--certificate") elif not os.path.exists(self['certificate']): raise usage.UsageError("Certificate file %r does not exist." % self['certificate']) else: self.addEndpoint('pop3', self['pop3s'], certificate=self['certificate']) if self['esmtp'] and self['hostname'] is None: raise usage.UsageError("--esmtp requires --hostname") # If the --auth option was passed, this will be present -- otherwise, # it won't be, which is also a perfectly valid state. if 'credCheckers' in self: for ch in self['credCheckers']: self.service.smtpPortal.registerChecker(ch) if not self['disable-anonymous']: self.service.smtpPortal.registerChecker( checkers.AllowAnonymousAccess()) anything = False for service in self._protoDefaults: self[service] = self._getEndpoints(reactor, service) if self[service]: anything = True if not anything: raise usage.UsageError("You cannot disable all protocols")