def main(): parser = argparse.ArgumentParser() parser.add_argument('--smtp-ip', default='127.0.0.1', metavar='IP', help='SMTP ip (default: 127.0.0.1)') parser.add_argument('--smtp-port', default=1025, type=int, metavar='PORT', help='SMTP port (deault: 1025)') parser.add_argument('--http-ip', default='127.0.0.1', metavar='IP', help='HTTP ip (default: 127.0.0.1)') parser.add_argument('--http-port', default=1080, type=int, metavar='PORT', help='HTTP port (deault: 1080)') parser.add_argument('--db', metavar='PATH', help='SQLite database - in-memory if missing') parser.add_argument('--htpasswd', metavar='HTPASSWD', help='Apache-style htpasswd file') parser.add_argument('-v', '--version', help='Display the version and exit', action='store_true') parser.add_argument( '-f', '--foreground', help='Run in the foreground (default if no pid file is specified)', action='store_true') parser.add_argument('-d', '--debug', help='Run the web app in debug mode', action='store_true') parser.add_argument('-a', '--autobuild-assets', help='Automatically rebuild assets if necessary', action='store_true') parser.add_argument( '-n', '--no-quit', help='Do not allow clients to terminate the application', action='store_true') parser.add_argument('-p', '--pidfile', help='Use a PID file') parser.add_argument( '--stop', help='Sends SIGTERM to the running daemon (needs --pidfile)', action='store_true') args = parser.parse_args() if args.version: from maildump.util import get_version print('MailDump {0}'.format(get_version())) sys.exit(0) # Do we just want to stop a runnign daemon? if args.stop: if not args.pidfile or not os.path.exists(args.pidfile): print('PID file not specified or not found') sys.exit(1) try: pid = read_pidfile(args.pidfile) except ValueError as e: print('Could not read PID file: {0}'.format(e)) sys.exit(1) try: os.kill(pid, signal.SIGTERM) except OSError as e: print('Could not send SIGTERM: {0}'.format(e)) sys.exit(1) sys.exit(0) # Default to foreground mode if no pid file is specified if not args.pidfile and not args.foreground: print('No PID file specified; runnning in foreground') args.foreground = True # Warn about relative paths and absolutize them if args.db and not os.path.isabs(args.db): args.db = os.path.abspath(args.db) print('Database path is relative, using {0}'.format(args.db)) if args.htpasswd and not os.path.isabs(args.htpasswd): args.htpasswd = os.path.abspath(args.htpasswd) print('Htpasswd path is relative, using {0}'.format(args.htpasswd)) # Check if the password file is valid if args.htpasswd and not os.path.isfile(args.htpasswd): print('Htpasswd file does not exist') sys.exit(1) # Check if the static folder is writable asset_folder = os.path.join( pkgutil.get_loader('maildump').filename, 'static') if args.autobuild_assets and not os.access(asset_folder, os.W_OK): print('Autobuilding assets requires write access to {0}'.format( asset_folder)) sys.exit(1) daemon_kw = { 'monkey_greenlet_report': False, 'signal_map': { signal.SIGTERM: terminate_server, signal.SIGINT: terminate_server } } if args.foreground: # Do not detach and keep std streams open daemon_kw.update({ 'detach_process': False, 'stdin': sys.stdin, 'stdout': sys.stdout, 'stderr': sys.stderr }) pidfile = None if args.pidfile: pidfile = os.path.abspath( args.pidfile) if not os.path.isabs(args.pidfile) else args.pidfile if os.path.exists(pidfile): pid = read_pidfile(pidfile) if not os.path.exists(os.path.join('/proc', str(pid))): print( 'Deleting obsolete PID file (process {0} does not exist)'. format(pid)) os.unlink(pidfile) daemon_kw['pidfile'] = TimeoutPIDLockFile(pidfile, 5) # Unload threading module to avoid error on exit (it's loaded by lockfile) if 'threading' in sys.modules: del sys.modules['threading'] context = GeventDaemonContext(**daemon_kw) try: context.open() except lockfile.LockTimeout: print('Could not acquire lock on pid file {0}'.format(pidfile)) print('Check if the daemon is already running.') sys.exit(1) except KeyboardInterrupt: print() sys.exit(1) with context: # Imports are here to avoid importing anything before monkeypatching from maildump import app, start from maildump.web import assets assets.debug = app.debug = args.debug assets.auto_build = args.autobuild_assets app.config['MAILDUMP_HTPASSWD'] = HtpasswdFile( args.htpasswd) if args.htpasswd else None app.config['MAILDUMP_NO_QUIT'] = args.no_quit level = logbook.DEBUG if args.debug else logbook.INFO format_string = ( u'[{record.time:%Y-%m-%d %H:%M:%S}] {record.level_name:<8} {record.channel}: {record.message}' ) stderr_handler = ColorizedStderrHandler(level=level, format_string=format_string) with NullHandler().applicationbound(): with stderr_handler.applicationbound(): start(args.http_ip, args.http_port, args.smtp_ip, args.smtp_port, args.db)
if args.pidfile: pidfile = os.path.abspath( args.pidfile) if not os.path.isabs(args.pidfile) else args.pidfile if os.path.exists(pidfile): pid = read_pidfile(pidfile) if not os.path.exists(os.path.join('/proc', str(pid))): print 'Deleting obsolete PID file (process {0} does not exist)'.format( pid) os.unlink(pidfile) daemon_kw['pidfile'] = TimeoutPIDLockFile(pidfile, 5) # Unload threading module to avoid error on exit (it's loaded by lockfile) if 'threading' in sys.modules: del sys.modules['threading'] context = GeventDaemonContext(**daemon_kw) try: context.open() except lockfile.LockTimeout: print 'Could not acquire lock on pid file {0}'.format(pidfile) print 'Check if the daemon is already running.' sys.exit(1) except KeyboardInterrupt: print sys.exit(1) with context: # Imports are here to avoid importing anything before monkeypatching from maildump import app, start from maildump.web import assets
def main(): parser = argparse.ArgumentParser() parser.add_argument('--smtp-ip', default='127.0.0.1', metavar='IP', help='SMTP ip (default: 127.0.0.1)') parser.add_argument('--smtp-port', default=1025, type=int, metavar='PORT', help='SMTP port (deault: 1025)') parser.add_argument('--http-ip', default='127.0.0.1', metavar='IP', help='HTTP ip (default: 127.0.0.1)') parser.add_argument('--http-port', default=1080, type=int, metavar='PORT', help='HTTP port (deault: 1080)') parser.add_argument('--db', metavar='PATH', help='SQLite database - in-memory if missing') parser.add_argument('--htpasswd', metavar='HTPASSWD', help='Apache-style htpasswd file') parser.add_argument('-v', '--version', help='Display the version and exit', action='store_true') parser.add_argument('-f', '--foreground', help='Run in the foreground (default if no pid file is specified)', action='store_true') parser.add_argument('-d', '--debug', help='Run the web app in debug mode', action='store_true') parser.add_argument('-a', '--autobuild-assets', help='Automatically rebuild assets if necessary', action='store_true') parser.add_argument('-n', '--no-quit', help='Do not allow clients to terminate the application', action='store_true') parser.add_argument('-p', '--pidfile', help='Use a PID file') parser.add_argument('--stop', help='Sends SIGTERM to the running daemon (needs --pidfile)', action='store_true') args = parser.parse_args() if args.version: from maildump.util import get_version print('MailDump {0}'.format(get_version())) sys.exit(0) # Do we just want to stop a runnign daemon? if args.stop: if not args.pidfile or not os.path.exists(args.pidfile): print('PID file not specified or not found') sys.exit(1) try: pid = read_pidfile(args.pidfile) except ValueError as e: print('Could not read PID file: {0}'.format(e)) sys.exit(1) try: os.kill(pid, signal.SIGTERM) except OSError as e: print('Could not send SIGTERM: {0}'.format(e)) sys.exit(1) sys.exit(0) # Default to foreground mode if no pid file is specified if not args.pidfile and not args.foreground: print('No PID file specified; runnning in foreground') args.foreground = True # Warn about relative paths and absolutize them if args.db and not os.path.isabs(args.db): args.db = os.path.abspath(args.db) print('Database path is relative, using {0}'.format(args.db)) if args.htpasswd and not os.path.isabs(args.htpasswd): args.htpasswd = os.path.abspath(args.htpasswd) print('Htpasswd path is relative, using {0}'.format(args.htpasswd)) # Check if the password file is valid if args.htpasswd and not os.path.isfile(args.htpasswd): print('Htpasswd file does not exist') sys.exit(1) # Check if the static folder is writable asset_folder = os.path.join(pkgutil.get_loader('maildump').filename, 'static') if args.autobuild_assets and not os.access(asset_folder, os.W_OK): print('Autobuilding assets requires write access to {0}'.format(asset_folder)) sys.exit(1) daemon_kw = {'monkey_greenlet_report': False, 'signal_map': {signal.SIGTERM: terminate_server, signal.SIGINT: terminate_server}} if args.foreground: # Do not detach and keep std streams open daemon_kw.update({'detach_process': False, 'stdin': sys.stdin, 'stdout': sys.stdout, 'stderr': sys.stderr}) pidfile = None if args.pidfile: pidfile = os.path.abspath(args.pidfile) if not os.path.isabs(args.pidfile) else args.pidfile if os.path.exists(pidfile): pid = read_pidfile(pidfile) if not os.path.exists(os.path.join('/proc', str(pid))): print('Deleting obsolete PID file (process {0} does not exist)'.format(pid)) os.unlink(pidfile) daemon_kw['pidfile'] = TimeoutPIDLockFile(pidfile, 5) # Unload threading module to avoid error on exit (it's loaded by lockfile) if 'threading' in sys.modules: del sys.modules['threading'] context = GeventDaemonContext(**daemon_kw) try: context.open() except lockfile.LockTimeout: print('Could not acquire lock on pid file {0}'.format(pidfile)) print('Check if the daemon is already running.') sys.exit(1) except KeyboardInterrupt: print() sys.exit(1) with context: # Imports are here to avoid importing anything before monkeypatching from maildump import app, start from maildump.web import assets assets.debug = app.debug = args.debug assets.auto_build = args.autobuild_assets app.config['MAILDUMP_HTPASSWD'] = HtpasswdFile(args.htpasswd) if args.htpasswd else None app.config['MAILDUMP_NO_QUIT'] = args.no_quit level = logbook.DEBUG if args.debug else logbook.INFO format_string = ( u'[{record.time:%Y-%m-%d %H:%M:%S}] {record.level_name:<8} {record.channel}: {record.message}' ) stderr_handler = ColorizedStderrHandler(level=level, format_string=format_string) with NullHandler().applicationbound(): with stderr_handler.applicationbound(): start(args.http_ip, args.http_port, args.smtp_ip, args.smtp_port, args.db)