def parse_args(): parser = argparse.ArgumentParser() parser.add_argument('host_and_port', help='The IMAP4 host name and ' 'port number in the format <host>:<port>. If the :<port> part is ' 'omitted, the default port of 993 is used.') parser.add_argument('user', help='The username to log in with.') parser.add_argument('passwd', nargs='?', help='The password for ' 'login. If omitted, the password is requested via the terminal.') parser.add_argument('--mailbox', default='INBOX', help='Select the name ' 'of the mailbox to read the mails from. Default is INBOX.') parser.add_argument('--sender', help='Only accept emails from the ' 'specified email address. Otherwise, all mails will be accepted.') parser.add_argument('--filter-title', help='IMAP subject filter string.') parser.add_argument('--interval', type=int, default=5, help='The interval ' 'to check for new mail in seconds. Defaults to 5.') parser.add_argument('--list-mailboxes', action='store_true', help='List the mailboxes and exit.') parser.add_argument('--scale-pdf', type=float, default=1.0, help='The anmount by which PDF files should be scaled. Defaults to 1.') args = parser.parse_args() args.host, args.port = args.host_and_port.partition(':')[::2] if args.port: try: args.port = int(args.port) except ValueError: parser.error('invalid port') if args.interval < 1: parser.error('interval must be >= 1') return args
def parse_arguments(): from optparse import OptionParser parser = OptionParser('usage: %prog [options] db-file') parser.add_option("-v", "--verbose", dest="verbose", default=False, help="verbose") (options, args) = parser.parse_args() if len(args) != 1: parser.error('db-file argument is required') return {'file': args[0], 'verbose':options.verbose}
def parse_arguments(): from optparse import OptionParser import getpass parser = OptionParser('usage: %prog [options] gmail-username') parser.add_option("-f", "--file", dest="file", default="emails.sql", help="destination database file [default: %default]") (options, args) = parser.parse_args() if len(args) != 1: parser.error('email argument is required') password = getpass.getpass('Password: '******'email':args[0], 'password':password, 'file':options.file}
def main(argv): parser = OptionParser() parser.add_option("-b", "--base", dest="base_url", help="specify base Fossil URL", metavar="URL") parser.add_option("-R", "--repository", dest="repo", help="Fossil repository to add ticket to", metavar="FILE") global options, args (options, args) = parser.parse_args() if not options.base_url: parser.error("Base URL not given.") elif not options.repo: parser.error("Repository path not given.") if len(argv) < 2: print("Usage: {0} repository".format(argv[0])) return False msg = parse_message(sys.stdin.read()) if not msg: print("Unable to parse message.", file=sys.stderr) return False elif not msg["id"]: print("No Message-Id, ignoring.", file=sys.stderr) return False cache = Cache() if msg["id"] in cache: print("Message {0} already was processed.".format(msg["id"]), file=sys.stderr) return True uuid = handle_message(msg) cache[msg["id"]] = uuid cache.save() return True
def main(args=None): parser = argparse.ArgumentParser() parser.add_argument('-c', '--config-file', default='~/.imapautofiler.yml') parser.add_argument( '--list-mailboxes', default=False, action='store_true', help='instead of processing rules, print a list of mailboxes') args = parser.parse_args() try: cfg = config.get_config(args.config_file) conn = imapclient.IMAPClient( cfg['server']['hostname'], use_uid=True, ssl=True, ) username = cfg['server']['username'] password = cfg['server'].get('password') if not password: password = getpass.getpass('Password for {}:'.format(username)) conn.login(username, password) try: if args.list_mailboxes: list_mailboxes(cfg, args.debug, conn) else: process_rules(cfg, args.debug, conn) finally: try: conn.close() except: pass conn.logout() except Exception as err: if args.debug: raise parser.error(err) return 0
def py_nipubdir(): """ @brief Command line program to perform a NetInf 'publish' operation using http @brief convergence layer. Uses NIproc global instance of NI operations class Run: > nipub.py --help to see usage and options. Exit code is 0 for success, 1 if HTTP returned something except 200, and negative for local errors. """ # Options parsing and verification stuff usage = "%%prog -d <pathname of content directory> -n <FQDN of netinf node> [-a <hash alg>] [-m NN] [-c count]" parser = OptionParser(usage) parser.add_option("-d", "--dir", dest="dir_name", type="string", help="Pathname for directory to be published.") parser.add_option("-a", "--alg", dest="hash_alg", default="sha-256", type="string", help="Hash algorithm to be used for NI URIs. Defaults to sha-256.") parser.add_option("-n", "--node", dest="host", type="string", help="The FQDN where I'll send PUBLISH messages.") parser.add_option("-m", "--multiprocess", dest="mprocs", default=1, type="int", help="The number of client processes to use in a pool (default 1)") parser.add_option("-c", "--count", dest="count", default=0, type="int", help="The number of files to publish (default: all)") (options, args) = parser.parse_args() # Check command line options: # Arguments -h is optional, all others needed # Specifying more than one of -w, -p, -j and -v is inappropriate. if len(args) != 0: parser.error("Unrecognized arguments %s supplied." % str(args)) sys.exit(-1) if options.dir_name == None: parser.error("You must supply a directory name with -d") sys.exit(-1) if options.host == None: parser.error("You must supply a host name with -n") sys.exit(-1) nilog("Starting nipubdir,dir,%s,to,%s,alg,%s,processes,%d,count,%d" % (options.dir_name,options.host,options.hash_alg,options.mprocs,options.count)) # loop over all files below directory and putone() for each we find count,goodlist,badlist=pubdirs(options.dir_name,options.hash_alg,options.host,options.mprocs,options.count) # print goodlist # print badlist nilog("Finished nipubdir,dir,%s,to,%s,alg,%s,processes,%d,count,%d" % (options.dir_name,options.host,options.hash_alg,options.mprocs,count)) sys.exit(0)
def main(args=None): parser = argparse.ArgumentParser() parser.add_argument( '-v', '--verbose', action='store_true', default=False, help='report more details about what is happening', ) parser.add_argument( '--debug', action='store_true', default=False, help='turn on imaplib debugging output', ) parser.add_argument( '-c', '--config-file', default='~/.imapautofiler.yml', ) parser.add_argument( '--list-mailboxes', default=False, action='store_true', help='instead of processing rules, print a list of mailboxes', ) args = parser.parse_args() if args.debug: imaplib.Debug = 4 if args.verbose or args.debug: log_level = logging.DEBUG else: log_level = logging.INFO logging.basicConfig( level=log_level, format='%(name)s: %(message)s', ) logging.debug('starting') try: cfg = config.get_config(args.config_file) conn = imapclient.IMAPClient( cfg['server']['hostname'], use_uid=True, ssl=True, ) conn.login(cfg['server']['username'], cfg['server']['password']) try: if args.list_mailboxes: list_mailboxes(cfg, args.debug, conn) else: process_rules(cfg, args.debug, conn) finally: try: conn.close() except: pass conn.logout() except Exception as err: if args.debug: raise parser.error(err) return 0
def main(): parser = OptionParser() parser.add_option( '-c', '--config', dest='configfile', metavar='FILE', help='JSON configuration file to load') parser.add_option( '-d', '--daemonize', action='store_const', const=True, dest='daemonize', default=None, help='Run mockmail in the background. Overwrites configuration') parser.add_option( '-i', '--interactive', action='store_const', const=True, dest='daemonize', default=None, help='Run mockmail in the foreground. Overwrites configuration') parser.add_option( '--resourcedir', dest='resourcedir', metavar='DIR', help='Load resources and templates from this directrory') parser.add_option( '--pidfile', dest='pidfile', default=None, help='Set pidfile to use. Overwrites configuration') parser.add_option( '--ctl-status', action='store_const', dest='ctl', const='status', default=None, help='Check whether mockmail service is running.') parser.add_option( '--ctl-start', action='store_const', dest='ctl', const='start', default=None, help='Start mockmail service.') parser.add_option( '--ctl-stop', action='store_const', dest='ctl', const='stop', default=None, help='Stop mockmail service.') parser.add_option( '--quiet-ctl', action='store_true', dest='quiet_ctl', default=False, help='Do not print announcement in --ctl-* operations.') parser.add_option( '--dumpconfig', action='store_true', dest='dumpconfig', help='Do not run mockmail, but dump the effective configuration') parser.add_option( '--version', action='store_true', dest='dumpversion', help='Do not run mockmail, but output the version') parser.add_option( '--check-resourcedir', action='store_true', dest='check_resourcedir', help='Do not run mockmail, but check that the resource directory is set correctly') opts, args = parser.parse_args() if len(args) != 0: parser.error('Did not expect any arguments. Use -c to specify a configuration file.') if opts.dumpversion: print(__version__) return config = { 'smtpaddr': '', # IP address to bind the SMTP port on. The default allows anyone to send you emails. 'smtpport': 2525, # SMTP port number. On unixoid systems, you will need superuser privileges to bind to a port < 1024 'httpaddr': '', # IP address to bind the web interface on. The default allows anyone to see your mail. 'httpport': 2580, # Port to bind the web interface on. You may want to configure your webserver on port 80 to proxy the connection. 'chroot': None, # Specify the directory to chroot into. 'chroot_mkdir': False, # Automatically create the chroot directory if it doesn't exist, and chroot is set. 'dropuser': None, # User account (name or uid) to drop to, None to not drop privileges 'dropgroup': None, # User group (name or gid) to drop into. By default, this is the primary group of the user. 'static_dev': False, # Read static files on demand. Good for development (a reload will update the file), but should not be set in production 'daemonize': False, # Whether mockmail should go into the background after having started 'pidfile': None, # File to write the process ID of mockmail to (relative to the chroot) 'resourcedir': None, # Directory to load templates and resources 'workarounds': True, # Work around platform bugs 'static_cache_secs': 0, # Cache duration for static files 'smtp_grace_period': None, # Set to a number to wait that long to open a port } if opts.configfile: with open(opts.configfile, 'r') as cfgf: config.update(json.load(cfgf)) if opts.daemonize is not None: config['daemonize'] = opts.daemonize if opts.pidfile is not None: config['pidfile'] = opts.pidfile if opts.resourcedir is not None: config['resourcedir'] = opts.resourcedir if opts.dumpconfig: json.dump(config, sys.stdout, indent=4) sys.stdout.write('\n') return if config['resourcedir'] is None: config['resourcedir'] = os.path.normpath(os.path.join(os.path.dirname(__file__), '..', 'share', 'mockmail')) if opts.check_resourcedir: print('Loading resources from ' + os.path.abspath(config['resourcedir']) + ' ...') _readIds( _TEMPLATES, lambda fid: os.path.join(config['resourcedir'], 'templates', fid + '.mustache'), mapContent=lambda content: content.decode('UTF-8'), ondemand=False) _readIds( _STATIC_FILES, lambda fid: os.path.join(config['resourcedir'], 'static', fid), ondemand=False) sys.exit(0) ctl_print = (lambda s: 0) if opts.quiet_ctl else sys.stdout.write if opts.ctl == 'status': pid = _getPid(_effectivePidfile(config)) if pid: ctl_print('mockmail is running.\n') sys.exit(0) else: ctl_print('mockmail is NOT running.\n') sys.exit(3) elif opts.ctl == 'start': pid = _getPid(_effectivePidfile(config)) ctl_print('Starting Test MTA: mockmail') if pid: sys.stdout.write(' (pid ' + str(pid) + ') already running.\n') sys.exit(0) else: config['daemonize'] = True mockmail(config) ctl_print('.\n') return elif opts.ctl == 'stop': pidfn = _effectivePidfile(config) pid = _getPid(pidfn) ctl_print('Stopping Test MTA: mockmail ...') if pid: os.kill(pid, signal.SIGTERM) try: os.unlink(pidfn) except OSError: pass ctl_print('.\n') sys.exit(0) if config['pidfile']: pid = _getPid(_effectivePidfile(config)) if pid: raise Exception( 'mockmail is already running (pid %s), read from %s' % (pid, _effectivePidfile(config))) mockmail(config)
def py_niget(): """ @brief Command line program to perform a NetInf 'get' operation using http @brief convergence layer. Uses NIproc global instance of NI operations class Run: > niget.py --help to see usage and options. Exit code is 0 for success, 1 if HTTP returned something except 200, and negative for local errors. """ # Options parsing and verification stuff usage = "%prog [-q] [-l] [-d] [-m|-v] [-f <pathname of content file>] <ni name>\n" + \ "<ni name> must include location (netloc) from which to retrieve object." parser = OptionParser(usage) parser.add_option("-f", "--file", dest="file_name", type="string", help="File to hold retrieved content. Defaults to hash code in current directory if not present") parser.add_option("-q", "--quiet", default=False, action="store_true", dest="quiet", help="Suppress textual output") parser.add_option("-s", "--server", dest="server", type="string", help="hostname:port of server to send the NetInf GET to") parser.add_option("-l", "--lax", default=False, action="store_true", dest="lax", help="Store returned content even if digest doesn't validate") parser.add_option("-m", "--metadata", default=False, action="store_true", dest="metadata", help="Output returned metadata as JSON string") parser.add_option("-v", "--view", default=False, action="store_true", dest="view", help="Pretty print returned metadata.") parser.add_option("-d", "--dump", default=False, action="store_true", dest="dump", help="Dump raw HTTP response to stdout.") (options, args) = parser.parse_args() # Check command line options - -q, -f, -l, -m, -v and -d are optional, <ni name> is mandatory if len(args) != 1: parser.error("URL <ni name> not specified.") sys.exit(-1) verbose = not options.quiet # Create NIname instance for supplied URL and validate it ni_url = NIname(args[0]) # Must be a complete ni: URL with non-empty params field rv = ni_url.validate_ni_url(has_params = True) if (rv != ni_errs.niSUCCESS): if verbose: print("Error: %s is not a complete, valid ni scheme URL: %s" % (ni_url.get_url(), ni_errs_txt[rv])) sys.exit(-2) # Generate file name for output if not specified if (options.file_name == None): options.file_name = ni_url.get_digest() # Generate NetInf form access URL if (options.server != None): server = options.server else: server = ni_url.get_netloc() http_url = "http://%s/netinfproto/get" % server """ if (http_url == None): if verbose: print("Error: Unable to generate http: transformed URL for ni URL %s" % ni_urlparse.get_url()) sys.exit(-3) """ # Set up HTTP form data for get request form_data = urllib.urlencode({ "URI": ni_url.get_url(), "msgid": random.randint(1, 32000), "ext": "" }) # Send POST request to destination server try: http_object = urllib2.urlopen(http_url, form_data) except Exception, e: if verbose: print("Error: Unable to access http URL %s: %s" % (http_url, str(e))) sys.exit(-4)
def py_nigetalt(): """ @brief Command line program to perform a NetInf 'get' operation using http @brief convergence layer. Uses NIproc global instance of NI operations class Run: > nigetalt.py --help to see usage and options. Exit code is 0 for success, 1 if HTTP returned something except 200, and negative for local errors. """ # Options parsing and verification stuff usage = "%prog [-q] [-l] [-d] [-m|-v] [-f <pathname of content file>] [-w <locator>] <ni name>\n" + \ "Either <ni name> must include location (netloc) from which to retrieve object, or\n" + \ "a locator must be given with the -w/--whence option.\n" + \ "The locator may be prefixed with an HTTP ('http://')or DTN ('dtn://') URI scheme identifier.\n" + \ "If no scheme identifier is given then HTTP is assumed. The DTN scheme does not accept ports." parser = OptionParser(usage) parser.add_option("-f", "--file", dest="file_name", type="string", help="File to hold retrieved content. Defaults to hash code in current directory if not present") parser.add_option("-w", "--whence", dest="loc", type="string", default=None, help="Locator to which to send NetInf GET request. May be prefixed with http:// or dtn://") parser.add_option("-q", "--quiet", default=False, action="store_true", dest="quiet", help="Suppress textual output") parser.add_option("-l", "--lax", default=False, action="store_true", dest="lax", help="Store returned content even if digest doesn't validate") parser.add_option("-m", "--metadata", default=False, action="store_true", dest="metadata", help="Output returned metadata as JSON string") parser.add_option("-v", "--view", default=False, action="store_true", dest="view", help="Pretty print returned metadata.") (options, args) = parser.parse_args() # Check command line options - -q, -f, -l, -m, and -v are optional, # <ni name> is mandatory # -w is optional if <ni name> contains a netloc if len(args) != 1: parser.error("URL <ni name> not specified.") sys.exit(-1) verbose = not options.quiet # Create NIname instance for supplied URL and validate it ni_url = NIname(args[0]) # Must be a complete ni: URL with non-empty params field rv = ni_url.validate_ni_url(has_params = True) if (rv != ni_errs.niSUCCESS): if verbose: print("Error: %s is not a complete, valid ni scheme URL: %s" % (ni_url.get_url(), ni_errs_txt[rv])) sys.exit(-2) # Generate file name for output if not specified if (options.file_name == None): options.file_name = ni_url.get_digest() # Decide Convergence Layer to use and locator to access netloc = ni_url.get_netloc() cl = HTTP_SCHEME if netloc == "": # Must have -w option if options.loc is None: if verbose: print("Error: Must provide a locator either in ni URI or via -w/--whence") sys.exit(-3) loc = options.loc.lower() elif options.loc is not None: if verbose: print("Warning: -w/--whence locator option overrides netloc in ni URI") loc = options.loc.lower() else: loc = netloc.lower() # See if URI scheme was specified if loc.startswith(HTTP_SCHEME): loc = loc[len(HTTP_SCHEME):] elif loc.startswith(DTN_SCHEME): loc = loc[len(DTN_SCHEME):] cl = DTN_SCHEME else: ssep = loc.find("://") if ssep != -1: if verbose: print("Error: Convergence Layer for scheme %s is not supported - use dtn or http" % loc[:ssep]) sys.exit(-4) # Default assume HTTP # Action the GET according to CL selected if cl == HTTP_SCHEME: json_report, got_content, faulty = get_via_http(ni_url, loc, options.file_name, verbose, options.lax) else: json_report, got_content, faulty = get_via_dtn(ni_url, loc, options.file_name, verbose, options.lax) if options.view: print("Returned metadata for %s:" % args[0]) print json.dumps(json_report, indent = 4) elif options.metadata: print json.dumps(json_report, separators=(",", ":")) if not got_content: rv = 1 elif faulty: rv = 2 else: rv = 0 if verbose and got_content: if not faulty: print("Content successfully retrieved and placed in file %s." % options.file_name) else: print("Content retrieved and placed in file %s but digest didn't verify." % options.file_name) elif verbose: print("Only metadata retrieved") sys.exit(rv)
def main(): parser = OptionParser() parser.add_option('-c', '--config', dest='configfile', metavar='FILE', help='JSON configuration file to load') parser.add_option( '-d', '--daemonize', action='store_const', const=True, dest='daemonize', default=None, help='Run mockmail in the background. Overwrites configuration') parser.add_option( '-i', '--interactive', action='store_const', const=False, dest='daemonize', default=None, help='Run mockmail in the foreground. Overwrites configuration') parser.add_option('--resourcedir', dest='resourcedir', metavar='DIR', help='Load resources and templates from this directrory') parser.add_option('--pidfile', dest='pidfile', default=None, help='Set pidfile to use. Overwrites configuration') parser.add_option('--ctl-status', action='store_const', dest='ctl', const='status', default=None, help='Check whether mockmail service is running.') parser.add_option('--ctl-start', action='store_const', dest='ctl', const='start', default=None, help='Start mockmail service.') parser.add_option('--ctl-stop', action='store_const', dest='ctl', const='stop', default=None, help='Stop mockmail service.') parser.add_option('--quiet-ctl', action='store_true', dest='quiet_ctl', default=False, help='Do not print announcement in --ctl-* operations.') parser.add_option( '--dumpconfig', action='store_true', dest='dumpconfig', help='Do not run mockmail, but dump the effective configuration') parser.add_option('--version', action='store_true', dest='dumpversion', help='Do not run mockmail, but output the version') parser.add_option( '--check-resourcedir', action='store_true', dest='check_resourcedir', help= 'Do not run mockmail, but check that the resource directory is set correctly' ) opts, args = parser.parse_args() if len(args) != 0: parser.error( 'Did not expect any arguments. Use -c to specify a configuration file.' ) if opts.dumpversion: print(__version__) return config = { 'smtpaddr': '', # IP address to bind the SMTP port on. The default allows anyone to send you emails. 'smtpport': 2525, # SMTP port number. On unixoid systems, you will need superuser privileges to bind to a port < 1024 'httpaddr': '', # IP address to bind the web interface on. The default allows anyone to see your mail. 'httpport': 2580, # Port to bind the web interface on. You may want to configure your webserver on port 80 to proxy the connection. 'chroot': None, # Specify the directory to chroot into. 'chroot_mkdir': False, # Automatically create the chroot directory if it doesn't exist, and chroot is set. 'dropuser': None, # User account (name or uid) to drop to, None to not drop privileges 'dropgroup': None, # User group (name or gid) to drop into. By default, this is the primary group of the user. 'static_dev': False, # Read static files on demand. Good for development (a reload will update the file), but should not be set in production 'daemonize': False, # Whether mockmail should go into the background after having started 'pidfile': None, # File to write the process ID of mockmail to (relative to the chroot) 'resourcedir': None, # Directory to load templates and resources 'workarounds': True, # Work around platform bugs 'static_cache_secs': 0, # Cache duration for static files 'smtp_grace_period': None, # Set to a number to wait that long to open a port } if opts.configfile: with open(opts.configfile, 'r') as cfgf: config.update(json.load(cfgf)) if opts.daemonize is not None: config['daemonize'] = opts.daemonize if opts.pidfile is not None: config['pidfile'] = opts.pidfile if opts.resourcedir is not None: config['resourcedir'] = opts.resourcedir if opts.dumpconfig: json.dump(config, sys.stdout, indent=4) sys.stdout.write('\n') return if config['resourcedir'] is None: config['resourcedir'] = os.path.normpath( os.path.join(os.path.dirname(__file__), '..', 'share', 'mockmail')) if opts.check_resourcedir: print('Loading resources from ' + os.path.abspath(config['resourcedir']) + ' ...') _readIds(_TEMPLATES, lambda fid: os.path.join(config['resourcedir'], 'templates', fid + '.mustache'), mapContent=lambda content: content.decode('UTF-8'), ondemand=False) _readIds( _STATIC_FILES, lambda fid: os.path.join(config['resourcedir'], 'static', fid), ondemand=False) sys.exit(0) ctl_print = (lambda s: 0) if opts.quiet_ctl else sys.stdout.write if opts.ctl == 'status': pid = _getPid(_effectivePidfile(config)) if pid: ctl_print('mockmail is running.\n') sys.exit(0) else: ctl_print('mockmail is NOT running.\n') sys.exit(3) elif opts.ctl == 'start': pid = _getPid(_effectivePidfile(config)) ctl_print('Starting Test MTA: mockmail') if pid: sys.stdout.write(' (pid ' + str(pid) + ') already running.\n') sys.exit(0) else: config['daemonize'] = True mockmail(config) ctl_print('.\n') return elif opts.ctl == 'stop': pidfn = _effectivePidfile(config) pid = _getPid(pidfn) ctl_print('Stopping Test MTA: mockmail ...') if pid: os.kill(pid, signal.SIGTERM) try: os.unlink(pidfn) except OSError: pass ctl_print('.\n') sys.exit(0) if config['pidfile']: pid = _getPid(_effectivePidfile(config)) if pid: raise Exception( 'mockmail is already running (pid %s), read from %s' % (pid, _effectivePidfile(config))) mockmail(config)
def py_nipub(): """ @brief Command line program to perform a NetInf 'publish' operation using http @brief convergence layer. Uses NIproc global instance of NI operations class Run: > nipub.py --help to see usage and options. Exit code is 0 for success, 1 if HTTP returned something except 200, and negative for local errors. """ # Options parsing and verification stuff usage = "%%prog %s\n %%prog %s\n%s\n %%prog %s\n %%prog %s\n%s\n%s" % \ ("[-q] [-e] [-j|-v|-w|-p] -f <pathname of content file> -d <digest alg> [-l <FQDN - locator>]{1,2}", "[-q] [-e] [-j|-v|-w|-p] [-f <pathname of content file>] -n <ni name> [-l <FQDN - locator>]{0,2}", " -- publish file via NI URI over HTTP", "[-q] [-e] [-j|-v|-w|-p] -u <HTTP URI of content file> -d <digest alg> [-l <FQDN - locator>]{1,2}", "[-q] [-e] [-j|-v|-w|-p] [-u <HTTP URI of content file>] -n <ni name> [-l <FQDN - locator>]{0,2}", " -- publish web content via NI URI over HTTP", "Send response as HTML document (-w), plain text (-p), or JSON (-v or -j)\n" "Unless -q is specified, the response is sent to standard output.\n" "For a JSON response, it can either be output as a 'raw' JSON string (-j) or pretty printed (-v).\n" "If none of -j, -v, -w or -p are specified, a raw JSON response will be requested.") parser = OptionParser(usage) parser.add_option("-f", "--file", dest="file_name", type="string", help="Pathname for local file to be published.") parser.add_option("-u", "--uri", dest="http_name", type="string", help="HTTP URL for content to be published.") parser.add_option("-d", "--digest", dest="hash_alg", type="string", help="Digest algorithm to be used to hash content " "and create NI URI. Defaults to sha-256.") parser.add_option("-n", "--name", dest="ni_name", type="string", help="Complete ni name. If specified with a file or " "HTTP URL, the digest generated from the content " "will be checked against th digest in the name.") parser.add_option("-e", "--ext", dest="ext", type="string", help="A JSON encoded object to be sent as the 'ext' " "parameter for the Publish message.") parser.add_option("-l", "--loc", dest="locs", action="append", type="string", help="An FQDN where NI might be retrieved. Maybe be " "zero to two if -n is present and has a non-empty netloc. " "Otherwise must be one or two. HTTP is sent to first " "loc if no authority in -n.") parser.add_option("-q", "--quiet", default=False, action="store_true", dest="quiet", help="Suppress textual output") parser.add_option("-j", "--json", default=False, action="store_true", dest="json_raw", help="Request response as JSON string and output raw JSON " "string returned on stdout.") parser.add_option("-v", "--view", default=False, action="store_true", dest="json_pretty", help="Request response as JSON string and pretty print " "JSON string returned on stdout.") parser.add_option("-w", "--web", default=False, action="store_true", dest="html", help="Request response as HTML document and output HTML " "returned on stdout.") parser.add_option("-p", "--plain", default=False, action="store_true", dest="plain", help="Request response as plain text document and output text " "returned on stdout.") (options, args) = parser.parse_args() # Check command line options: # Arguments -q, -e, -w, -p, -j and -v are optional; there must be one of a -n with an authority in it or at least one -l. # Either -d or -n must be specified. # If -d is specified, there must be either a -f or a -u but not both at once. # If -n is specified, one of -f or -u may be specified. No leftover arguments allowed. # Specifying more than one of -w, -p, -j and -v is inappropriate. if len(args) != 0: parser.error("Unrecognized arguments %s supplied." % str(args)) sys.exit(-1) if ((options.locs is not None) and (len(options.locs) > 2)): parser.error("Initial version only supports two locators (-l/--loc).") sys.exit(-1) if ((options.ni_name == None) and (options.locs == None)): parser.error("Must specify a locator (-l/--loc) or a name (-n/--name) with a netloc component to define where to send the request.") sys.exit(-1) if ((options.hash_alg != None) and (options.ni_name != None)): parser.error("Cannot specify both digest algorithm to be used (-d) and complete ni name with algorithm and digest (-n).") sys.exit(-1) if ((options.hash_alg == None) and (options.ni_name == None)): parser.error("Must specify either digest algorithm to be used (-d) or complete ni name with algorithm and digest (-n).") sys.exit(-1) if ((((options.ni_name == None) and (options.file_name == None) and (options.http_name == None))) or ((options.file_name != None) and (options.http_name != None))): parser.error("Exactly one of -f/--file and -u/--uri must be specified with -d and optionally with -n.") sys.exit(-1) fc = 0 for flag in [options.json_raw, options.json_pretty, options.html, options.plain]: if flag: fc += 1 if fc > 1: parser.error("Should specify at most one response type argument out of -j, -v, -w and -p.") sys.exit(-1) file_name = None # **** -u is not implemented yet if options.http_name != None: target = options.http_name print "Web name as source(-u/--uri option) not yet implemented. Exiting" sys.exit(-2) if options.file_name != None: target = options.file_name file_name = options.file_name full_put = True else: target = None full_put = False debug("full_put: %s" %full_put) verbose = not options.quiet # If we have a full ni name (-n option) given.. if options.ni_name is not None: # Check the validity of the ni name try: ni_name = NIname(options.ni_name) except Exception, e: if verbose: print("Error: value of -n/--name option '%s' is not a valid ni name" % options.ni_name) sys.exit(-3) rv = ni_name.validate_ni_url() if rv != ni_errs.niSUCCESS: if verbose: print("Error: value of -n/--name option '%s' is not a valid ni name" % options.ni_name) sys.exit(-3) # Extract the scheme and hash algorithm from the name scheme = ni_name.get_scheme() hash_alg = ni_name.get_alg_name() # If the ni name has a netloc in it then that is where to send; if not must have a loc nl = ni_name.get_netloc() if ((nl == "") and (options.locs == None)): print("Error: name (-n/--name) mist have a netloc if no locator options given,") sys.exit(-4) if nl != "": destination = nl authority = nl else: destination = options.locs[0] authority = ""
# Create NIdigester for use with form encoder and StreamingHTTP ni_digester = NIdigester() # Install the template URL built from the scheme, the authority and the digest algorithm rv = ni_digester.set_url((scheme, authority, "/%s" % hash_alg)) if rv != ni_errs.niSUCCESS: print("Cannot construct valid ni URL: %s" % ni_errs_txt[rv]) sys.exit(-4) debug(ni_digester.get_url()) # Open the file if possible try: f = open(options.file_name, "rb") except Exception, e : debug("Cannot open file %s: Error: %s" %(options.file_name, str(e))) parser.error("Unable to open file %s: Error: %s" % (options.file_name, str(e))) sys.exit(-5) # Guess the mimetype of the file m = magic.Magic(mime=True) ctype = m.from_file(options.file_name) debug("Content-Type: %s" % ctype) if ctype is None: # Guessing didn't work - default ctype = "application/octet-stream" # Set up HTTP form data for publish request # Make parameter for file with digester octet_param = MultipartParam("octets", fileobj=f, filetype=ctype,
def run(): parser = make_argparser() args = parser.parse_args() logger.addHandler( logging.handlers.RotatingFileHandler(args.log, maxBytes=4000)) logger.setLevel(getattr(logging, args.log_level)) context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) context.load_cert_chain(args.cert, args.key) if args.local: if args.mboxdir is None and args.wmaildir is None: parser.error('--local requires --mboxdir or --wmaildir') elif args.mboxdir: logger.debug('Ensuring mbox path exists') args.mboxdir.mkdir(parents=True, exist_ok=True) handler = LocalMboxHandler( ok_domains=args.delivery_domain, mboxdir=args.mboxdir, ) elif args.wmaildir: handler = LocalWMaildirHandler( ok_domains=args.delivery_domain, wmaildir=args.wmaildir, ) controllers = [] if args.forward: controllers.append( AuthController( ForwardingHandler( ok_domains=args.forward_domain, forward_host=args.forward_host, forward_port=args.forward_port, ), port=args.port, hostname=args.host, starttls_context=context, )) if args.ssl_port: controllers.append( AuthController( ForwardingHandler( ok_domains=args.forward_domain, forward_host=args.forward_host, forward_port=args.forward_port, ), port=args.ssl_port, hostname=args.host, starttls_context=context, ssl_context=context, )) if args.local: controllers.append( AuthController( handler, port=args.forward_port, hostname='0.0.0.0', ssl_context=context, starttls_context=context, )) logger.warn(f'orouboros {__version__} staring with pid {os.getpid()}') for controller in controllers: logger.debug(f'starting controller {controller}') controller.start() if controllers: logger.info('Waiting for SIGINT or SIGQUIT') sig = signal.sigwait([signal.SIGINT, signal.SIGQUIT]) logger.warn(f'{sig} caught, shutting down') else: print( 'Specify at least one of --forward or --local on the command line') for controller in controllers: logger.debug(f'stopping controller {controller}') controller.stop()
def py_nipubalt(): """ @brief Command line program to perform a NetInf 'publish' operation using http @brief convergence layer. Uses NIproc global instance of NI operations class Run: > nipubalt.py --help to see usage and options. Exit code is 0 for success, 1 if HTTP returned something except 200, and negative for local errors. """ # Options parsing and verification stuff usage = "%%prog %s\n %%prog %s\n%s\n%s" % \ ("[-q] [-e] [-j|-v|-w|-p] -f <pathname of content file> -d <digest alg> [-l <FQDN - locator>]{1,2}", "[-q] [-e] [-j|-v|-w|-p] [-f <pathname of content file>] -n <ni name> [-l <FQDN - locator>]{0,2}", " -- publish file via NI URI over HTTP and/or DTN", "At least one locator must be given either as part of the -n option or via a -l option.\n" "Locators given with -l options can optionally be prefixed with the HTTP scheme (http://) or \n" "the DTN scheme (dtn://). If a -l option is given, this is used to determine the initial\n" "publication destination and the convergence layer used will be HTPP unless the -l option\n" "explicitly gives the DTN scheme prefix. If there are no -l options but the -n option has\n" "a netloc compnent (FQDN or IP address with optional port) the this will be used with the\n" "HTTP convergence layer\n" "The response will be sent as HTML document (-w), plain text (-p), or JSON (-v or -j)\n" "Unless -q is specified, the response is sent to standard output.\n" "For a JSON response, it can either be output as a 'raw' JSON string (-j) or pretty printed (-v).\n" "If none of -j, -v, -w or -p are specified, a raw JSON response will be requested.") parser = OptionParser(usage) parser.add_option("-f", "--file", dest="file_name", type="string", help="Pathname for local file to be published.") parser.add_option("-d", "--digest", dest="hash_alg", type="string", help="Digest algorithm to be used to hash content " "and create NI URI. Defaults to sha-256.") parser.add_option("-n", "--name", dest="ni_name", type="string", help="Complete ni name. If specified with a file or " "HTTP URL, the digest generated from the content " "will be checked against th digest in the name.") parser.add_option("-e", "--ext", dest="ext", type="string", help="A JSON encoded object to be sent as the 'ext' " "parameter for the Publish message.") parser.add_option("-l", "--loc", dest="locs", action="append", type="string", help="A locator where NI might be retrieved. Maybe be " "zero to two if -n is present and has a non-empty netloc. " "Otherwise must be one or two. HTTP or DTN is sent to first " "loc if present. Otherwise sent to netloc (authority) in -n." "NOTE: this precedence differs from earlier versions of nipub.") parser.add_option("-q", "--quiet", default=False, action="store_true", dest="quiet", help="Suppress textual output") parser.add_option("-j", "--json", default=False, action="store_true", dest="json_raw", help="Request response as JSON string and output raw JSON " "string returned on stdout.") parser.add_option("-v", "--view", default=False, action="store_true", dest="json_pretty", help="Request response as JSON string and pretty print " "JSON string returned on stdout.") parser.add_option("-w", "--web", default=False, action="store_true", dest="html", help="Request response as HTML document and output HTML " "returned on stdout.") parser.add_option("-p", "--plain", default=False, action="store_true", dest="plain", help="Request response as plain text document and output text " "returned on stdout.") (options, args) = parser.parse_args() # Check command line options: # Arguments -q, -e, -w, -p, -j and -v are optional; there must be one of a -n with an authority in it or at least one -l. # If -n option is specified then there must not be a -d. # If -d is specified, there must be a -f. # If -n is specified, -f may be specified - otherwise only metadata is published. No leftover arguments allowed. # Specifying more than one of -w, -p, -j and -v is inappropriate. if len(args) != 0: parser.error("Unrecognized arguments %s supplied." % str(args)) sys.exit(-1) if ((options.locs is not None) and (len(options.locs) > 2)): parser.error("Initial version only supports two locators (-l/--loc).") sys.exit(-1) if ((options.ni_name == None) and (options.locs == None)): parser.error("Must specify a locator (-l/--loc) or a name (-n/--name) with a netloc component to define where to send the request.") sys.exit(-1) if ((options.hash_alg != None) and (options.ni_name != None)): parser.error("Cannot specify both digest algorithm to be used (-d) and complete ni name with algorithm and digest (-n).") sys.exit(-1) fc = 0 for flag in [options.json_raw, options.json_pretty, options.html, options.plain]: if flag: fc += 1 if fc > 1: parser.error("Should specify at most one response type argument out of -j, -v, -w and -p.") sys.exit(-1) file_name = None if options.file_name != None: file_name = os.path.abspath(options.file_name) # Check the file is readable if not os.access(file_name, os.R_OK): if verbose: print("File to be published %s is not readable" % file_name) sys.exit(1) full_put = True else: full_put = False debug("full_put: %s" %full_put) verbose = not options.quiet if ((options.locs is not None) and (len(options.locs) > 2)): if verbose: print "Warning: only first two -l/--loc locators will be published" # If we have a full ni name (-n option) given.. if options.ni_name is not None: # Check the validity of the ni name try: ni_name = NIname(options.ni_name) except Exception, e: if verbose: print("Error: value of -n/--name option '%s' is not a valid ni name" % options.ni_name) sys.exit(-3) rv = ni_name.validate_ni_url() if rv != ni_errs.niSUCCESS: if verbose: print("Error: value of -n/--name option '%s' is not a valid ni name" % options.ni_name) sys.exit(-3) # Extract the scheme and hash algorithm from the name scheme = ni_name.get_scheme() hash_alg = ni_name.get_alg_name() # If there is a -l option, that is where the request is sent. nl = ni_name.get_netloc() if ((options.locs is None) and (nl == "")) : print("Error: name (-n/--name) must have a netloc if no locator options given,") sys.exit(-4) # NOTE: The following logic ie reversed from earlier versions so that # can force use of DTN convergence layer with a -l option. if nl == "": # Already checked this exists destination = options.locs[0] else: destination = nl authority = nl