Example #1
0
def update_feeds_for_instance(args, instance):
    log.info("Updating feeds for %s", instance)
    root, closer = args.get_root(instance)
    set_current_instance(instance)
    set_subsystem('update_feeds')
    feeds.update_feeds(root, log, args.force)
    transaction.commit()
Example #2
0
File: mailout.py Project: hj91/karl
def main():
    parser = optparse.OptionParser(description=__doc__, usage="%prog [options] queue_path")
    parser.add_option(
        "-C",
        "--config",
        dest="config",
        default=None,
        help="Path to configuration file (defaults to $CWD/etc/karl.ini)",
        metavar="FILE",
    )
    parser.add_option("--daemon", "-D", dest="daemon", action="store_true", default=False, help="Run in daemon mode.")
    parser.add_option(
        "--interval",
        "-i",
        dest="interval",
        type="int",
        default=6 * 3600,
        help="Interval, in seconds, between executions when in " "daemon mode.",
    )
    parser.add_option(
        "--server", "-s", dest="hostname", default="localhost", help="SMTP server host name", metavar="HOST"
    )
    parser.add_option("--port", "-P", dest="port", type="int", default=25, help="Port of SMTP server", metavar="PORT")
    parser.add_option("--username", "-u", dest="username", default=None, help="Username, if authentication is required")
    parser.add_option("--password", "-p", dest="password", default=None, help="Password, if authentication is required")
    parser.add_option(
        "--force-tls", "-f", dest="force_tls", action="store_true", default=False, help="Require that TLS be used."
    )
    parser.add_option(
        "--no-tls", "-n", dest="no_tls", action="store_true", default=False, help="Require that TLS not be used."
    )

    options, args = parser.parse_args()

    if not args:
        parser.error("Please specify queue path.")
    elif len(args) > 1:
        parser.error("Too many arguments.")
    queue_path = args[0]

    config = options.config
    if config is None:
        config = get_default_config()
    app = loadapp("config:%s" % config, "karl")
    set_subsystem("mailout")

    mailer = SMTPMailer(
        hostname=options.hostname,
        port=options.port,
        username=options.username,
        password=options.password,
        no_tls=options.no_tls,
        force_tls=options.force_tls,
    )
    qp = QueueProcessor(mailer, queue_path)

    if options.daemon:
        run_daemon("digest", qp.send_messages, options.interval)
    else:
        qp.send_messages()
Example #3
0
def digest(args, instance):
    root, closer = args.get_root(instance)
    set_current_instance(instance)
    set_subsystem('digest')
    alerts = Alerts()
    alerts.send_digests(root)
    closer()
Example #4
0
def mailin(args, instance):
    log.info("Processing mailin for %s" % instance)
    root, closer = args.get_root(instance)
    set_current_instance(instance)
    set_subsystem('mailin')

    zodb_uri = get_setting(root, 'postoffice.zodb_uri')
    zodb_path = get_setting(root, 'postoffice.zodb_path', '/postoffice')
    queue = get_setting(root, 'postoffice.queue')

    if zodb_uri is None:
        args.parser.error("postoffice.zodb_uri must be set in config file")

    if queue is None:
        args.parser.error("postoffice.queue must be set in config file")

    runner = None
    try:
        runner = MailinRunner2(root, zodb_uri, zodb_path, queue)
        runner()
        transaction.commit()

        p_jar = getattr(root, '_p_jar', None)
        if p_jar is not None:
            # Attempt to fix memory leak
            p_jar.db().cacheMinimize()

    except:
        transaction.abort()
        raise

    finally:
        closer()
        if runner is not None:
            runner.close()
Example #5
0
def main(args):
    queue_path = args.get_setting('mail_queue_path')
    set_subsystem('mailout')

    mailer = SMTPMailer(
        hostname=args.server,
        port=args.port,
        username=args.username,
        password=args.password,
        no_tls=args.no_tls,
        force_tls=args.force_tls
    )
    qp = QueueProcessor(mailer, queue_path)
    qp.send_messages()
def dump_senders(args, instance):
    root, closer = args.get_root(instance)
    set_current_instance(instance)
    set_subsystem('dump_senders')

    pc = find_peopledirectory_catalog(root)

    for email in pc['email']._fwd_index.keys():
        if ',' in email:
            for e in email.split(','):
                if not e.isspace() and len(e) != 0:
                    print e.strip() + " permit_auth_destination"
        else:
            if not email.isspace() and len(email) != 0:
                print email.strip() + " permit_auth_destination"
Example #7
0
def usersync(args):
    root, closer = args.get_root(args.inst)
    set_current_instance(args.inst)
    set_subsystem('usersync')
    if args.password and args.password_file:
        args.parser.error('cannot set both --password and --password-file')
    if args.password_file:
        with open(args.password_file) as f:
            password = f.read().strip('\n')
    else:
        password = args.password
    log.info("Syncing users at %s" % args.url)
    sync = UserSync(root)
    sync(args.url, args.username, password)
    transaction.commit()
Example #8
0
 def run(root=root):
     closer = lambda: None  # unit test
     try:
         if root is None:
             root, closer = get_root(app)
         # else: unit test
         set_subsystem("update_feeds")
         update_func(root, config, force=options.force)
     except:
         tx.abort()
         closer()
         raise
     else:
         if options.dryrun:
             tx.abort()
         else:
             tx.commit()
         closer()
Example #9
0
 def run():
     set_subsystem('digest')
     root, closer = get_root(app)
     alerts.send_digests(root, options.frequency)
     closer()
Example #10
0
def make_karl_instance(name, global_config, uri):
    settings = _get_config(global_config, uri)
    connstats_file = global_config.get('connection_stats_filename')
    connstats_threshhold = float(global_config.get( 
                                    'connection_stats_threshhold', 0))

    def root_factory(request, name='site'):
        def finished(request):
            # closing the primary also closes any secondaries opened
            now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            elapsed = time.time() - before
            if elapsed > connstats_threshhold:
                loads_after, stores_after = connection.getTransferCounts()
                loads = loads_after - loads_before
                stores = stores_after - stores_before
                with open(connstats_file, 'a', 0) as f:
                    f.write('"%s", "%s", "%s", %f, %d, %d\n' %
                               (now,
                                request.method,
                                request.path_url,
                                elapsed,
                                loads,
                                stores,
                               )
                           )
                    f.flush()

        if connstats_file is not None:
            request.add_finished_callback(finished)

        # NB: Finished callbacks are executed in the order they've been added
        # to the request.  pyramid_zodbconn's ``get_connection`` registers a
        # finished callback which closes the ZODB database.  Because the
        # finished callback it registers closes the database, we need it to
        # execute after the "finished" function above.  As a result, the above
        # call to ``request.add_finished_callback`` *must* be executed before
        # we call ``get_connection`` below.

        # Rationale: we want the call to getTransferCounts() above to happen
        # before the ZODB database is closed, because closing the ZODB database
        # has the side effect of clearing the transfer counts (the ZODB
        # activity monitor clears the transfer counts when the database is
        # closed).  Having the finished callbacks called in the "wrong" order
        # will result in the transfer counts being cleared before the above
        # "finished" function has a chance to read their per-request values,
        # and they will appear to always be zero.
            
        connection = get_connection(request)
        if connstats_file is not None:
            before = time.time()
            loads_before, stores_before = connection.getTransferCounts()
        folder = connection.root()
        if name not in folder:
            bootstrapper = queryUtility(IBootstrapper, default=populate)
            bootstrapper(folder, name, request)

            # Use pgtextindex
            if 'pgtextindex.dsn' in settings:
                site = folder.get(name)
                index = lookup(KarlPGTextIndex)(get_weighted_textrepr)
                site.catalog['texts'] = index

            transaction.commit()

        return folder[name]

    # Subsystem for logging
    set_subsystem('karl')

    # Make Pyramid app
    #
    # Do the configuration dance. If a 'package' setting is present, then
    # that package is the customization package and should be used to configure
    # the application.  Configuration can be done either by loading ZCML or by
    # calling a function for configuring Karl imperatively.  Imperative
    # configuration is preferred with loading of ZCML as a fallback.

    # Find package and configuration
    pkg_name = settings.get('package', None)
    configure_karl = None
    if pkg_name:
        __import__(pkg_name)
        package = sys.modules[pkg_name]
        configure_karl = get_imperative_config(package)
        if configure_karl is not None:
            filename = None
        else:
            filename = 'configure.zcml'
            # BBB Customization packages may be using ZCML style config but
            # need configuration done imperatively in core Karl.  These
            # customizaton packages have generally been written before the
            # introduction of imperative style config.
            configure_karl = configure_default
    else:
        package = karl.includes
        configure_karl = configure_default
        filename = None

    if 'tm.attempts' not in settings:
        settings['tm.attempts'] = 5

    config = Configurator(package=package, settings=settings,
            root_factory=root_factory, autocommit=True)
    config.begin()
    config.include('pyramid_tm')
    config.include('pyramid_zodbconn')
    if filename is not None:
        if configure_karl is not None: # BBB See above
            configure_karl(config, load_zcml=False)
        config.hook_zca()
        config.include('pyramid_zcml')
        config.load_zcml(filename)
    else:
        configure_karl(config)
    config.end()

    def closer():
        registry = config.registry
        dbs = getattr(registry, '_zodb_databases', None)
        if dbs:
            for db in dbs.values():
                db.close()
            del registry._zodb_databases

    app = config.make_wsgi_app()
    app.config = settings
    app.close = closer

    return app
Example #11
0
def make_karl_instance(name, global_config, uri):
    settings = _get_config(global_config, uri)

    def appmaker(folder, name='site'):
        if name not in folder:
            bootstrapper = queryUtility(IBootstrapper, default=populate)
            bootstrapper(folder, name)

            # Use pgtextindex
            if 'pgtextindex.dsn' in settings:
                site = folder.get(name)
                index = lookup(KarlPGTextIndex)(get_weighted_textrepr)
                site.catalog['texts'] = index

            transaction.commit()

        return folder[name]

    # paster app settings callback
    finder = PersistentApplicationFinder(uri, appmaker)
    def get_root(request):
        return finder(request.environ)
    def closer():
        db = finder.db
        if db is not None:
            db.close()
            finder.db = None

    # Subsystem for logging
    set_subsystem('karl')

    # Make Pyramid app
    #
    # Do the configuration dance. If a 'package' setting is present, then
    # that package is the customization package and should be used to configure
    # the application.  Configuration can be done either by loading ZCML or by
    # calling a function for configuring Karl imperatively.  Imperative
    # configuration is preferred with loading of ZCML as a fallback.

    # Find package and configuration
    pkg_name = settings.get('package', None)
    configure_karl = None
    if pkg_name:
        __import__(pkg_name)
        package = sys.modules[pkg_name]
        configure_karl = get_imperative_config(package)
        if configure_karl is not None:
            filename = None
        else:
            filename = 'configure.zcml'
            # BBB Customization packages may be using ZCML style config but
            # need configuration done imperatively in core Karl.  These
            # customizaton packages have generally been written before the
            # introduction of imperative style config.
            configure_karl = configure_default
    else:
        package = karl.includes
        configure_karl = configure_default
        filename = None

    config = Configurator(package=package, settings=settings,
            root_factory=get_root, autocommit=True)
    config.begin()
    if filename is not None:
        if configure_karl is not None: # BBB See above
            configure_karl(config, load_zcml=False)
        config.hook_zca()
        config.include('pyramid_zcml')
        config.load_zcml(filename)
    else:
        configure_karl(config)
    config.end()

    app = config.make_wsgi_app()
    app.config = settings
    app.uri = uri
    app.close = closer

    return app
Example #12
0
File: digest.py Project: zagy/karl
 def run():
     set_subsystem('digest')
     root, closer = get_root(app)
     alerts.send_digests(root)
     closer()