def Main(args): mailpile.platforms.DetectBinaries() DisableUnbrokeredConnections() # Bootstrap translations until we've loaded everything else mailpile.i18n.ActivateTranslation(None, ConfigManager, None) try: # Create our global config manager and the default (CLI) session config = ConfigManager(rules=mailpile.config.defaults.CONFIG_RULES) session = Session(config) cli_ui = session.ui = UserInteraction(config) session.main = True try: CatchUnixSignals(session) config.clean_tempfile_dir() config.load(session) except IOError: if config.sys.debug: session.ui.error(_('Failed to decrypt configuration, ' 'please log in!')) HealthCheck(session, None, []).run() config.prepare_workers(session) except AccessError, e: session.ui.error('Access denied: %s\n' % e) sys.exit(1)
def Main(args): DisableUnbrokeredConnections() # Bootstrap translations until we've loaded everything else mailpile.i18n.ActivateTranslation(None, ConfigManager, None) try: # Create our global config manager and the default (CLI) session config = ConfigManager(rules=mailpile.config.defaults.CONFIG_RULES) session = Session(config) cli_ui = session.ui = UserInteraction(config) session.main = True try: CatchUnixSignals(session) config.clean_tempfile_dir() config.load(session) except IOError: if config.sys.debug: session.ui.error( _('Failed to decrypt configuration, ' 'please log in!')) HealthCheck(session, None, []).run() config.prepare_workers(session) except AccessError, e: session.ui.error('Access denied: %s\n' % e) sys.exit(1)
def prepare_workers(config, session, daemons=False): # Set globals from config first... mailpile.util.APPEND_FD_CACHE_SIZE = config.sys.fd_cache_size if not config.background: # Create a silent background session config.background = Session(config) config.background.ui = BackgroundInteraction(config) config.background.ui.block() # Start the workers if config.slow_worker == config.dumb_worker: config.slow_worker = Worker('Slow worker', session) config.slow_worker.start() if daemons and not config.cron_worker: config.cron_worker = Cron('Cron worker', session) config.cron_worker.start() # Schedule periodic rescanning, if requested. rescan_interval = config.prefs.rescan_interval if rescan_interval: def rescan(): if 'rescan' not in config._running: rsc = Rescan(session, 'rescan') rsc.serialize = False config.slow_worker.add_task(None, 'Rescan', rsc.run) config.cron_worker.add_task('rescan', rescan_interval, rescan) if daemons and not config.http_worker: # Start the HTTP worker if requested sspec = (config.sys.http_host, config.sys.http_port) if sspec[0].lower() != 'disabled' and sspec[1] >= 0: config.http_worker = HttpWorker(session, sspec) config.http_worker.start()
def Main(args): # Bootstrap translations until we've loaded everything else translation = gettext.translation("mailpile", getLocaleDirectory(), fallback=True) translation.install(unicode=True) try: # Create our global config manager and the default (CLI) session config = ConfigManager(rules=mailpile.defaults.CONFIG_RULES) session = Session(config) cli_ui = session.ui = UserInteraction(config) session.main = True session.config.load(session) except AccessError, e: sys.stderr.write('Access denied: %s\n' % e) sys.exit(1)
def Main(args): try: mailpile.platforms.DetectBinaries(_raise=OSError) except OSError as e: binary = str(e).split()[0] sys.stderr.write(""" Required binary missing or unusable: %s If you know where it is, or would like to skip this test and run Mailpile anyway, you can set one of the following environment variables: MAILPILE_%s="/path/to/binary" or MAILPILE_SKIP_BINARIES="%s" Note that skipping a binary check may cause the app to become unstable or fail in unexpected ways. If it breaks you get to keep both pieces! """ % (e, binary.upper(), binary)) sys.exit(1) # Enable our connection broker, try to prevent badly behaved plugins from # bypassing it. DisableUnbrokeredConnections() # Bootstrap translations until we've loaded everything else mailpile.i18n.ActivateTranslation(None, ConfigManager, None) try: # Create our global config manager and the default (CLI) session config = ConfigManager(rules=mailpile.config.defaults.CONFIG_RULES) session = Session(config) cli_ui = session.ui = UserInteraction(config) session.main = True try: CatchUnixSignals(session) config.clean_tempfile_dir() config.load(session) except IOError: if config.sys.debug: session.ui.error( _('Failed to decrypt configuration, ' 'please log in!')) HealthCheck(session, None, []).run() config.prepare_workers(session) except AccessError, e: session.ui.error('Access denied: %s\n' % e) sys.exit(1)
def Main(args): try: mailpile.platforms.DetectBinaries(_raise=OSError) except OSError as e: binary = str(e).split()[0] sys.stderr.write(""" Required binary missing or unusable: %s If you know where it is, or would like to skip this test and run Mailpile anyway, you can set one of the following environment variables: MAILPILE_%s="/path/to/binary" or MAILPILE_IGNORE_BINARIES="%s" Note that skipping a binary check may cause the app to become unstable or fail in unexpected ways. If it breaks you get to keep both pieces! """ % (e, binary.upper(), binary)) sys.exit(1) # Enable our connection broker, try to prevent badly behaved plugins from # bypassing it. DisableUnbrokeredConnections() # Bootstrap translations until we've loaded everything else mailpile.i18n.ActivateTranslation(None, ConfigManager, None) try: # Create our global config manager and the default (CLI) session config = ConfigManager(rules=mailpile.config.defaults.CONFIG_RULES) session = Session(config) cli_ui = session.ui = UserInteraction(config) session.main = True try: CatchUnixSignals(session) config.clean_tempfile_dir() config.load(session) except IOError: if config.sys.debug: session.ui.error(_('Failed to decrypt configuration, ' 'please log in!')) HealthCheck(session, None, []).run() config.prepare_workers(session) except AccessError, e: session.ui.error('Access denied: %s\n' % e) sys.exit(1)
def Main(args): # Bootstrap translations until we've loaded everything else mailpile.i18n.ActivateTranslation(None, ConfigManager, None) try: # Create our global config manager and the default (CLI) session config = ConfigManager(rules=mailpile.defaults.CONFIG_RULES) session = Session(config) cli_ui = session.ui = UserInteraction(config) session.main = True try: config.load(session) except IOError: session.ui.error(_('Failed to decrypt configuration, ' 'please log in!')) config.prepare_workers(session) except AccessError, e: session.ui.error('Access denied: %s\n' % e) sys.exit(1)
def _check_profiles(self, config): session = Session(config) session.ui = SilentInteraction(config) session.ui.block() data = ListProfiles(session).run().result okay = routes = bad = 0 for rid, ofs in data["rids"].iteritems(): profile = data["profiles"][ofs] if profile.get('email', None): okay += 1 route_id = profile.get('x-mailpile-profile-route', '') if route_id: if route_id in config.routes: routes += 1 else: bad += 1 else: bad += 1 return (routes > 0) and (okay > 0) and (bad == 0)
def Main(args): # Bootstrap translations until we've loaded everything else mailpile.i18n.ActivateTranslation(None, ConfigManager, None) try: # Create our global config manager and the default (CLI) session config = ConfigManager(rules=mailpile.defaults.CONFIG_RULES) session = Session(config) cli_ui = session.ui = UserInteraction(config) session.main = True try: config.load(session) except IOError: session.ui.error( _('Failed to decrypt configuration, ' 'please log in!')) config.prepare_workers(session) except AccessError, e: session.ui.error('Access denied: %s\n' % e) sys.exit(1)
def command(self): config = self.session.config s = Session(config) sid = "%08x" % random.randint(0, 1000000000) sessions[sid] = s return self._success(_('Created a session'), result={ "sid": sid, })
def do_GET(self, post_data={}, suppress_body=False): (scheme, netloc, path, params, query, frag) = urlparse(self.path) query_data = parse_qs(query) cmd = self.parse_pqp(path, query_data, post_data, self.server.session.config) session = Session(self.server.session.config) session.ui = HtmlUI() index = session.config.get_index(session) if cmd: try: for arg in cmd.split(' /'): args = arg.strip().split() Action(session, args[0], ' '.join(args[1:])) body = session.ui.render_html() title = 'The biggest pile of mail EVAR!' except UsageError, e: body = 'Oops: %s' % e title = 'Ouch, too much mail, urgle, *choke*'
def command(self): global SESSIONS config = self.session.config s = Session(config) s.ui.log_parent = self.session.ui s.ui.render_mode = 'text' sid = "%08x" % random.randint(0, 1000000000) SESSIONS[sid] = s return self._success('Created a session', result={"sid": sid})
def cache_result(self, fprint, expires, req, cmd_obj, result_obj): with self.lock: # Make a snapshot of the session, as it provides context snapshot = Session.Snapshot(cmd_obj.session, ui=False) snapshot.ui = cmd_obj.session.ui cmd_obj.session = result_obj.session = snapshot # Note: We cache this even if the requirements are "dirty", # as mere presence in the cache makes this a candidate # for refreshing. self.cache[str(fprint)] = [expires, req, cmd_obj, result_obj] self.debug('Cached %s, req=%s' % (fprint, req))
def Main(args): # Bootstrap translations until we've loaded everything else translation = gettext.translation("mailpile", getLocaleDirectory(), fallback=True) translation.install(unicode=True) try: # Create our global config manager and the default (CLI) session config = ConfigManager(rules=mailpile.defaults.CONFIG_RULES) session = Session(config) cli_ui = session.ui = UserInteraction(config) session.main = True try: config.load(session) except IOError: session.ui.error(_('Failed to decrypt configuration, ' 'please log in!')) config.prepare_workers(session) except AccessError, e: session.ui.error('Access denied: %s\n' % e) sys.exit(1)
def cache_result(self, fprint, expires, req, cmd_obj, result_obj): with self.lock: # Make a snapshot of the session, as it provides context ss = Session.Snapshot(cmd_obj.session, ui=False) ss.ui = BackgroundInteraction(cmd_obj.session.config, log_parent=cmd_obj.session.ui) # Note: We cache this even if the requirements are "dirty", # as mere presence in the cache makes this a candidate # for refreshing. self.cache[str(fprint)] = [expires, req, ss, cmd_obj, result_obj, time.time()] self.debug('Cached %s, req=%s' % (fprint, sorted(list(req))))
def Main(args): try: mailpile.platforms.DetectBinaries(_raise=OSError) except OSError as e: binary = str(e).split()[0] sys.stderr.write(""" Required binary missing or unusable: %s If you know where it is, or would like to skip this test and run Mailpile anyway, you can set one of the following environment variables: MAILPILE_%s="/path/to/binary" or MAILPILE_IGNORE_BINARIES="%s" Note that skipping a binary check may cause the app to become unstable or fail in unexpected ways. If it breaks you get to keep both pieces! """ % (e, binary.upper(), binary)) sys.exit(1) # Enable our connection broker, try to prevent badly behaved plugins from # bypassing it. DisableUnbrokeredConnections() # Bootstrap translations until we've loaded everything else mailpile.i18n.ActivateTranslation(None, ConfigManager, None) try: # Create our global config manager and the default (CLI) session config = ConfigManager(rules=mailpile.config.defaults.CONFIG_RULES) session = Session(config) cli_ui = session.ui = UserInteraction(config) session.main = True try: CatchUnixSignals(session) config.clean_tempfile_dir() config.load(session) except IOError: if config.sys.debug: session.ui.error( _('Failed to decrypt configuration, ' 'please log in!')) HealthCheck(session, None, []).run() config.prepare_workers(session) except AccessError as e: session.ui.error('Access denied: %s\n' % e) sys.exit(1) try: try: if '--login' in args: a1 = args[:args.index('--login') + 1] a2 = args[len(a1):] else: a1, a2 = args, [] allopts = [] for argset in (a1, a2): shorta, longa = '', [] for cls in COMMANDS: shortn, longn, urlpath, arglist = cls.SYNOPSIS[:4] if arglist: if shortn: shortn += ':' if longn: longn += '=' if shortn: shorta += shortn if longn: longa.append(longn.replace(' ', '_')) opts, args = getopt.getopt(argset, shorta, longa) allopts.extend(opts) for opt, arg in opts: session.ui.display_result( Action(session, opt.replace('-', ''), arg.decode('utf-8'))) if args: session.ui.display_result( Action(session, args[0], ' '.join(args[1:]).decode('utf-8'))) except (getopt.GetoptError, UsageError) as e: session.fatal_error(unicode(e)) if (not allopts) and (not a1) and (not a2): InteractCommand(session).run() except KeyboardInterrupt: pass except: traceback.print_exc() finally: write_readline_history(session) # Make everything in the background quit ASAP... mailpile.util.LAST_USER_ACTIVITY = 0 mailpile.util.QUITTING = mailpile.util.QUITTING or True if config.plugins: config.plugins.process_shutdown_hooks() config.stop_workers() if config.index: config.index.save_changes() if config.event_log: config.event_log.close() session.ui.display_result(Action(session, 'cleanup', '')) if session.interactive and config.sys.debug: session.ui.display_result(Action(session, 'ps', '')) # Remove anything that we couldn't remove before safe_remove() # Restart the app if that's what was requested if mailpile.util.QUITTING == 'restart': os.execv(sys.argv[0], sys.argv)
def _real_startup(config): while config.http_worker is None: time.sleep(0.1) try: session_id = config.http_worker.httpd.make_session_id(None) mailpile.auth.SetLoggedIn(None, user='******', session_id=session_id) cookie = config.http_worker.httpd.session_cookie sspec = config.http_worker.httpd.sspec base_url = 'http://%s:%s' % sspec script_dir = os.path.dirname(os.path.realpath(__file__)) script = os.path.join(script_dir, 'gui-o-matic.py') global __GUI__ gui = __GUI__ = Popen( ['python', '-u', script], bufsize=1, # line buffered stdin=PIPE, stderr=PIPE, long_running=True) stderr = [] eater = threading.Thread(target=output_eater, args=[gui.stderr, stderr]) eater.name = 'GUI(stderr)' eater.daemon = True eater.start() ico = lambda s: os.path.join(script_dir, 'icons-%(theme)s', s) gui.stdin.write( json.dumps({ 'app_name': 'Mailpile', 'indicator_icons': { 'startup': ico('startup.png'), 'normal': ico('normal.png'), 'working': ico('working.png'), 'attention': ico('attention.png'), 'shutdown': ico('shutdown.png') }, 'indicator_menu': [{ 'label': _('Starting up ...'), 'item': 'status' }, { 'label': _('Open Mailpile'), 'item': 'open', 'op': 'show_url', 'args': [base_url] }, { 'label': _('Quit'), 'item': 'quit', 'op': 'get_url', 'args': [base_url + '/api/0/quitquitquit/'] }], 'http_cookies': { base_url: [[cookie, session_id]] }, }).strip() + '\nOK GO\n') indicator('set_menu_sensitive', item='quit') indicator('set_menu_sensitive', item='open') # FIXME: This sleep is lame time.sleep(5) if (gui.poll() is not None) or mailpile.util.QUITTING: return except: # If the basic indicator setup fails, we just assume it doesn't # work and go silently dead... return try: # ...however, getting this far means if the indicator dies, then # the user tried to quit the app, so we should cooperate and die # (via the except below). while config.index is None or not config.tags: if mailpile.util.QUITTING: return if gui.poll() is not None: return time.sleep(1) indicator('set_status_normal') # FIXME: We should do more with the indicator... this is a bit lame. while True: if mailpile.util.QUITTING: indicator('set_status_shutdown') indicator('set_menu_sensitive', item='open', sensitive=False) indicator('set_menu_sensitive', item='quit', sensitive=False) indicator('set_menu_label', item='status', label=_('Shutting down...')) time.sleep(300) else: indicator('set_menu_label', item='status', label=_('%d messages') % len(config.index and config.index.INDEX or [])) time.sleep(5) except AttributeError: pass finally: try: if not mailpile.util.QUITTING: Quit(Session(config)).run() except: pass
from mailpile.util import * _plugins = PluginManager(builtin=__file__) # This makes sure mailbox "plugins" get loaded... has to go somewhere? from mailpile.mailboxes import * mailpile.i18n.ActivateTranslation(None, ConfigManager, None) config = ConfigManager(rules=mailpile.config.defaults.CONFIG_RULES) cfg = config with open('/tmp/pass', 'rb') as fort1f3: p1 = fort1f3.read() pass2 = SecurePassphraseStorage(p1) cfg.load_master_key(pass2) session = Session(config) cli_ui = session.ui = UserInteraction(config) session.main = True config.clean_tempfile_dir() config.load(session) session.config = cfg vcard = MailpileVCard() vcard.kind = 'profile' with open('/tmp/mail', 'rb') as fort3f3: mail = fort3f3.read() with open('/tmp/fn', 'rb') as fort2f3: fn = fort2f3.read() mail.replace("\n", "") fn.replace("\n", "") mail = ''.join(mail.splitlines())
# Check our arguments infiles = outfiles = [] try: infiles = sys.argv[1:-1] outpath = sys.argv[-1] except: pass if ((not infiles or not outpath) or (os.path.exists(outpath) and not os.path.isdir(outpath)) or (len(infiles) > 1 and not os.path.isdir(outpath))): sys.stderr.write(__doc__) sys.exit(1) # Basic app bootstrapping config = ConfigManager(rules=CONFIG_RULES) session = Session(config) session.ui = UserInteraction(config) # Get the password, verify it, decrypt config fails = 0 for tries in range(1, 4): try: VerifyAndStorePassphrase(config, passphrase=session.ui.get_password( _('Your password: '******'Incorrect, try again?') fails = tries if fails == tries:
def prepare_workers(config, session=None, daemons=False): # Set globals from config first... import mailpile.util # Make sure we have a silent background session if not config.background: config.background = Session(config) config.background.ui = BackgroundInteraction(config) config.background.ui.block() # Start the workers if daemons: if config.slow_worker == config.dumb_worker: config.slow_worker = Worker('Slow worker', session) config.slow_worker.start() if not config.cron_worker: config.cron_worker = Cron('Cron worker', session) config.cron_worker.start() if not config.http_worker: # Start the HTTP worker if requested sspec = (config.sys.http_host, config.sys.http_port) if sspec[0].lower() != 'disabled' and sspec[1] >= 0: config.http_worker = HttpWorker(session, sspec) config.http_worker.start() if not config.other_workers: import mailpile.plugins for worker in mailpile.plugins.WORKERS: w = worker(session) w.start() config.other_workers.append(w) # Update the cron jobs, if necessary if config.cron_worker: session = session or config.background # Schedule periodic rescanning, if requested. rescan_interval = config.prefs.rescan_interval if rescan_interval: def rescan(): if 'rescan' not in config._running: rsc = Rescan(session, 'rescan') rsc.serialize = False config.slow_worker.add_task(session, 'Rescan', rsc.run) config.cron_worker.add_task('rescan', rescan_interval, rescan) # Schedule plugin jobs import mailpile.plugins def interval(i): if isinstance(i, (str, unicode)): i = config.walk(i) return int(i) for job, (i, f) in mailpile.plugins.FAST_PERIODIC_JOBS.iteritems(): config.cron_worker.add_task(job, interval(i), lambda: f(session)) for job, (i, f) in mailpile.plugins.SLOW_PERIODIC_JOBS.iteritems(): def wrap(): config.slow_worker.add_task(session, job, lambda: f(session)) config.cron_worker.add_task(job, interval(i), wrap)
_plugins = PluginManager(builtin=__file__) # This makes sure mailbox "plugins" get loaded... has to go somewhere? from mailpile.mailboxes import * mailpile.i18n.ActivateTranslation(None, ConfigManager, None) config = ConfigManager(rules=mailpile.config.defaults.CONFIG_RULES) cfg=config with open('/tmp/pass', 'rb') as fort1f3:p1=fort1f3.read() pass2 = SecurePassphraseStorage(p1) cfg.load_master_key(pass2) session = Session(config) cli_ui = session.ui = UserInteraction(config) session.main = True config.clean_tempfile_dir() config.load(session) session.config=cfg vcard = MailpileVCard() vcard.kind='profile' with open('/tmp/mail', 'rb') as fort3f3:mail=fort3f3.read() with open('/tmp/fn', 'rb') as fort2f3:fn=fort2f3.read() mail.replace("\n", "") fn.replace("\n","") mail=''.join(mail.splitlines()) fn=''.join(fn.splitlines()) data= {'name': [fn], 'email': [mail],'route-protocol':['smtp'],'route-host':['::1'],'route-port':['25'],'route-auth_type':['none']}