text:
"""Invoke tasks. To run a task, run ``$ invoke <COMMAND>``. To see a list of
commands, run ``$ invoke --list``.
"""
import os
import sys
import code
import json
import platform
import subprocess
import logging
from time import sleep

import invoke
from invoke import Collection

from website import settings
from utils import pip_install, bin_prefix

logging.getLogger('invoke').setLevel(logging.CRITICAL)

# gets the root path for all the scripts that rely on it
HERE = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
WHEELHOUSE_PATH = os.environ.get('WHEELHOUSE')
CONSTRAINTS_PATH = os.path.join(HERE, 'requirements', 'constraints.txt')

try:
    __import__('rednose')
except ImportError:
    TEST_CMD = 'nosetests'
else:
    TEST_CMD = 'nosetests --rednose'

ns = Collection()

try:
    from admin import tasks as admin_tasks
    ns.add_collection(Collection.from_module(admin_tasks), name='admin')
except ImportError:
    pass

def task(*args, **kwargs):
    """Behaves the same way as invoke.task. Adds the task
    to the root namespace.
    """
    if len(args) == 1 and callable(args[0]):
        new_task = invoke.task(args[0])
        ns.add_task(new_task)
        return new_task
    def decorator(f):
        new_task = invoke.task(f, *args, **kwargs)
        ns.add_task(new_task)
        return new_task
    return decorator

def _monkey_patch_werkzeug_reloader_for_docker():
    from werkzeug import _reloader
    from werkzeug._reloader import _find_observable_paths

    def _find_common_roots(paths):
        """Out of some paths it finds the common roots that need monitoring."""
        # rv = orig_docker_find_common_roots(paths)
        rv = set()
        root = os.getcwd()
        rv.add(root)
        for path in paths:
            if path.startswith(root):
                rv.add(path)
        return rv
    _reloader._find_common_roots = _find_common_roots

    def run(self):
        watches = {}
        observer = self.observer_class()
        observer.start()

        while not self.should_reload:
            to_delete = set(watches)
            paths = _find_observable_paths(self.extra_files)
            for path in paths:
                if path not in watches:
                    try:
                        watches[path] = observer.schedule(
                            self.event_handler, path, recursive=False)  # FIX: docker-compose performance issue
                    except OSError:
                        # "Path is not a directory". We could filter out
                        # those paths beforehand, but that would cause
                        # additional stat calls.
                        watches[path] = None
                to_delete.discard(path)
            for path in to_delete:
                watch = watches.pop(path, None)
                if watch is not None:
                    observer.unschedule(watch)
            self.observable_paths = paths
            self._sleep(self.interval)

        sys.exit(3)
    _reloader.WatchdogReloaderLoop.run = run

@task
def server(ctx, host=None, port=5000, debug=True, gitlogs=False):
    """Run the app server."""
    if os.environ.get('WERKZEUG_RUN_MAIN') == 'true' or not debug:
        if os.environ.get('WEB_REMOTE_DEBUG', None):
            import pydevd
            _monkey_patch_werkzeug_reloader_for_docker()
            # e.g. '127.0.0.1:5678'
            remote_parts = os.environ.get('WEB_REMOTE_DEBUG').split(':')
            pydevd.settrace(remote_parts[0], port=int(remote_parts[1]), suspend=False, stdoutToServer=True, stderrToServer=True)

        if gitlogs:
            git_logs(ctx)
        from website.app import init_app
        os.environ['DJANGO_SETTINGS_MODULE'] = 'api.base.settings'
        app = init_app(set_backends=True, routes=True)
        settings.API_SERVER_PORT = port
    else:
        from framework.flask import app

    context = None
    if settings.SECURE_MODE:
        context = (settings.OSF_SERVER_CERT, settings.OSF_SERVER_KEY)
    app.run(host=host, port=port, debug=debug, threaded=debug, extra_files=[settings.ASSET_HASH_PATH], ssl_context=context)

@task
def git_logs(ctx, branch=None):
    from scripts.meta import gatherer
    gatherer.main(branch=branch)

@task
def apiserver(ctx, port=8000, wait=True, autoreload=True, host='127.0.0.1', pty=True):
    """Run the API server."""
    env = os.environ.copy()
    cmd = 'DJANGO_SETTINGS_MODULE=api.base.settings {} manage.py runserver {}:{} --nothreading'\
        .format(sys.executable, host, port)
    if not autoreload:
        cmd += ' --noreload'
    if settings.SECURE_MODE:
        cmd = cmd.replace('runserver', 'runsslserver')
        cmd += ' --certificate {} --key {}'.format(settings.OSF_SERVER_CERT, settings.OSF_SERVER_KEY)

    if wait:
        return ctx.run(cmd, echo=True, pty=pty)
    from subprocess import Popen

    return Popen(cmd, shell=True, env=env)

@task
def adminserver(ctx, port=8001, host='127.0.0.1', pty=True):
    """Run the Admin server."""
    env = 'DJANGO_SETTINGS_MODULE="admin.base.settings"'
    cmd = '{} python manage.py runserver {}:{} --nothreading'.format(env, host, port)
    if settings.SECURE_MODE:
        cmd = cmd.replace('runserver', 'runsslserver')
        cmd += ' --certificate {} --key {}'.format(settings.OSF_SERVER_CERT, settings.OSF_SERVER_KEY)
    ctx.run(cmd, echo=True, pty=pty)

SHELL_BANNER = """
{version}

+--------------------------------------------------+
|cccccccccccccccccccccccccccccccccccccccccccccccccc|
|ccccccccccccccccccccccOOOOOOOccccccccccccccccccccc|
|ccccccccccccccccccccOOOOOOOOOOcccccccccccccccccccc|
|cccccccccccccccccccOOOOOOOOOOOOccccccccccccccccccc|
|cccccccccOOOOOOOcccOOOOOOOOOOOOcccOOOOOOOccccccccc|
|cccccccOOOOOOOOOOccOOOOOsssOOOOcOOOOOOOOOOOccccccc|
|ccccccOOOOOOOOOOOOccOOssssssOOccOOOOOOOOOOOccccccc|
|ccccccOOOOOOOOOOOOOcOssssssssOcOOOOOOOOOOOOOcccccc|
|ccccccOOOOOOOOOOOOsOcOssssssOOOOOOOOOOOOOOOccccccc|
|cccccccOOOOOOOOOOOssccOOOOOOcOssOOOOOOOOOOcccccccc|
|cccccccccOOOOOOOsssOccccccccccOssOOOOOOOcccccccccc|
|cccccOOOccccOOssssOccccccccccccOssssOccccOOOcccccc|
|ccOOOOOOOOOOOOOccccccccccccccccccccOOOOOOOOOOOOccc|
|cOOOOOOOOssssssOcccccccccccccccccOOssssssOOOOOOOOc|
|cOOOOOOOssssssssOccccccccccccccccOsssssssOOOOOOOOc|
|cOOOOOOOOsssssssOccccccccccccccccOsssssssOOOOOOOOc|
|cOOOOOOOOOssssOOccccccccccccccccccOsssssOOOOOOOOcc|
|cccOOOOOOOOOOOOOOOccccccccccccccOOOOOOOOOOOOOOOccc|
|ccccccccccccOOssssOOccccccccccOssssOOOcccccccccccc|
|ccccccccOOOOOOOOOssOccccOOcccOsssOOOOOOOOccccccccc|
|cccccccOOOOOOOOOOOsOcOOssssOcOssOOOOOOOOOOOccccccc|
|ccccccOOOOOOOOOOOOOOOsssssssOcOOOOOOOOOOOOOOcccccc|
|ccccccOOOOOOOOOOOOOcOssssssssOcOOOOOOOOOOOOOcccccc|
|ccccccOOOOOOOOOOOOcccOssssssOcccOOOOOOOOOOOccccccc|
|ccccccccOOOOOOOOOcccOOOOOOOOOOcccOOOOOOOOOcccccccc|
|ccccccccccOOOOcccccOOOOOOOOOOOcccccOOOOccccccccccc|
|ccccccccccccccccccccOOOOOOOOOOcccccccccccccccccccc|
|cccccccccccccccccccccOOOOOOOOOcccccccccccccccccccc|
|cccccccccccccccccccccccOOOOccccccccccccccccccccccc|
|cccccccccccccccccccccccccccccccccccccccccccccccccc|
+--------------------------------------------------+

Welcome to the OSF Python Shell. Happy hacking!

{transaction}
Available variables:

{context}
"""

TRANSACTION_WARNING = """
*** TRANSACTION AUTOMATICALLY STARTED ***

To persist changes run 'commit()'.
Keep in mind that changing documents will lock them.

This feature can be disabled with the '--no-transaction' flag.

"""

def make_shell_context(auto_transact=True):
    from modularodm import Q
    from framework.auth import User, Auth
    from framework.mongo import database
    from website.app import init_app
    from website.project.model import Node
    from website import models  # all models
    from website import settings
    import requests
    from framework.transactions import commands
    from framework.transactions import context as tcontext
    app = init_app()

    def commit():
        commands.commit()
        print('Transaction committed.')
        if auto_transact:
            commands.begin()
            print('New transaction opened.')

    def rollback():
        commands.rollback()
        print('Transaction rolled back.')
        if auto_transact:
            commands.begin()
            print('New transaction opened.')

    context = {
        'transaction': tcontext.TokuTransaction,
        'start_transaction': commands.begin,
        'commit': commit,
        'rollback': rollback,
        'app': app,
        'db': database,
        'User': User,
        'Auth': Auth,
        'Node': Node,
        'Q': Q,
        'models': models,
        'run_tests': test,
        'rget': requests.get,
        'rpost': requests.post,
        'rdelete': requests.delete,
        'rput': requests.put,
        'settings': settings,
    }
    try:  # Add a fake factory for generating fake names, emails, etc.
        from faker import Factory
        fake = Factory.create()
        context['fake'] = fake
    except ImportError:
        pass
    if auto_transact:
        commands.begin()
    return context

def format_context(context):
    lines = []
    for name, obj in context.items():
        line = '{name}: {obj!r}'.format(**locals())
        lines.append(line)
    return '\n'.join(lines)

# Shell command adapted from Flask-Script. See NOTICE for license info.
@task
def shell(ctx, transaction=True):
    context = make_shell_context(auto_transact=transaction)
    banner = SHELL_BANNER.format(version=sys.version,
        context=format_context(context),
        transaction=TRANSACTION_WARNING if transaction else ''
    )
    try:
        try:
            # 0.10.x
            from IPython.Shell import IPShellEmbed
            ipshell = IPShellEmbed(banner=banner)
            ipshell(global_ns={}, local_ns=context)
        except ImportError:
            # 0.12+
            from IPython import embed
            embed(banner1=banner, user_ns=context)
        return
    except ImportError:
        pass
    # fallback to basic python shell
    code.interact(banner, local=context)
    return

@task(aliases=['mongo'])
def mongoserver(ctx, daemon=False, config=None):
    """Run the mongod process.
    """
    if not config:
        platform_configs = {
            'darwin': '/usr/local/etc/tokumx.conf',  # default for homebrew install
            'linux': '/etc/tokumx.conf',
        }
        platform = str(sys.platform).lower()
        config = platform_configs.get(platform)
    port = settings.DB_PORT
    cmd = 'mongod --port {0}'.format(port)
    if config:
        cmd += ' --config {0}'.format(config)
    if daemon:
        cmd += ' --fork'
    ctx.run(cmd, echo=True)

@task(aliases=['mongoshell'])
def mongoclient(ctx):
    """Run the mongo shell for the OSF database."""
    db = settings.DB_NAME
    port = settings.DB_PORT
    ctx.run('mongo {db} --port {port}'.format(db=db, port=port), pty=True)

@task
def mongodump(ctx, path):
    """Back up the contents of the running OSF database"""
    db = settings.DB_NAME
    port = settings.DB_PORT

    cmd = 'mongodump --db {db} --port {port} --out {path}'.format(
        db=db,
        port=port,
        path=path,
        pty=True)

    if settings.DB_USER:
        cmd += ' --username {0}'.format(settings.DB_USER)
    if settings.DB_PASS:
        cmd += ' --password {0}'.format(settings.DB_PASS)

    ctx.run(cmd, echo=True)

    print()
    print('To restore from the dumped database, run `invoke mongorestore {0}`'.format(
        os.path.join(path, settings.DB_NAME)))

@task
def mongorestore(ctx, path, drop=False):
    """Restores the running OSF database with the contents of the database at
    the location given its argument.

    By default, the contents of the specified database are added to
    the existing database. The `--drop` option will cause the existing database
    to be dropped.

    A caveat: if you `invoke mongodump {path}`, you must restore with
    `invoke mongorestore {path}/{settings.DB_NAME}, as that's where the
    database dump will be stored.
    """
    db = settings.DB_NAME
    port = settings.DB_PORT

    cmd = 'mongorestore --db {db} --port {port}'.format(
        db=db,
        port=port,
        pty=True)

    if settings.DB_USER:
        cmd += ' --username {0}'.format(settings.DB_USER)
    if settings.DB_PASS:
        cmd += ' --password {0}'.format(settings.DB_PASS)

    if drop:
        cmd += ' --drop'

    cmd += ' ' + path
    ctx.run(cmd, echo=True)

@task
def sharejs(ctx, host=None, port=None, db_url=None, cors_allow_origin=None):
    """Start a local ShareJS server."""
    if host:
        os.environ['SHAREJS_SERVER_HOST'] = host
    if port:
        os.environ['SHAREJS_SERVER_PORT'] = port
    if db_url:
        os.environ['SHAREJS_DB_URL'] = db_url
    if cors_allow_origin:
        os.environ['SHAREJS_CORS_ALLOW_ORIGIN'] = cors_allow_origin

    if settings.SENTRY_DSN:
        os.environ['SHAREJS_SENTRY_DSN'] = settings.SENTRY_DSN

    share_server = os.path.join(settings.ADDON_PATH, 'wiki', 'shareServer.js')
    ctx.run('node {0}'.format(share_server))

@task(aliases=['celery'])
def celery_worker(ctx, level='debug', hostname=None, beat=False):
    """Run the Celery process."""
    cmd = 'celery worker -A framework.celery_tasks -l {0}'.format(level)
    if hostname:
        cmd = cmd + ' --hostname={}'.format(hostname)
    # beat sets up a cron like scheduler, refer to website/settings
    if beat:
        cmd = cmd + ' --beat'
    ctx.run(bin_prefix(cmd), pty=True)

@task(aliases=['beat'])
def celery_beat(ctx, level='debug', schedule=None):
    """Run the Celery process."""
    # beat sets up a cron like scheduler, refer to website/settings
    cmd = 'celery beat -A framework.celery_tasks -l {0} --pidfile='.format(level)
    if schedule:
        cmd = cmd + ' --schedule={}'.format(schedule)
    ctx.run(bin_prefix(cmd), pty=True)

@task
def rabbitmq(ctx):
    """Start a local rabbitmq server.

    NOTE: this is for development only. The production environment should start
    the server as a daemon.
    """
    ctx.run('rabbitmq-server', pty=True)

@task(aliases=['elastic'])
def elasticsearch(ctx):
    """Start a local elasticsearch server

    NOTE: Requires that elasticsearch is installed. See README for instructions
    """
    import platform
    if platform.linux_distribution()[0] == 'Ubuntu':
        ctx.run('sudo service elasticsearch start')
    elif platform.system() == 'Darwin':  # Mac OSX
        ctx.run('elasticsearch')
    else:
        print('Your system is not recognized, you will have to start elasticsearch manually')

@task
def migrate_search(ctx, delete=False, index=settings.ELASTIC_INDEX):
    """Migrate the search-enabled models."""
    from website.search_migration.migrate import migrate
    migrate(delete, index=index)

@task
def rebuild_search(ctx):
    """Delete and recreate the index for elasticsearch"""
    ctx.run('curl -s -XDELETE {uri}/{index}*'.format(uri=settings.ELASTIC_URI,
                                             index=settings.ELASTIC_INDEX))
    ctx.run('curl -s -XPUT {uri}/{index}'.format(uri=settings.ELASTIC_URI,
                                          index=settings.ELASTIC_INDEX))
    migrate_search(ctx)

@task
def mailserver(ctx, port=1025):
    """Run a SMTP test server."""
    cmd = 'python -m smtpd -n -c DebuggingServer localhost:{port}'.format(port=port)
    ctx.run(bin_prefix(cmd), pty=True)

@task
def jshint(ctx):
    """Run JSHint syntax check"""
    js_folder = os.path.join(HERE, 'website', 'static', 'js')
    cmd = 'jshint {}'.format(js_folder)
    ctx.run(cmd, echo=True)

@task(aliases=['flake8'])
def flake(ctx):
    ctx.run('flake8 .', echo=True)

@task(aliases=['req'])
def requirements(ctx, base=False, addons=False, release=False, dev=False, metrics=False, quick=False):
    """Install python dependencies.

    Examples:
        inv requirements
        inv requirements --quick

    Quick requirements are, in order, addons, dev and the base requirements. You should be able to use --quick for
    day to day development.

    By default, base requirements will run. However, if any set of addons, release, dev, or metrics are chosen, base
    will have to be mentioned explicitly in order to run. This is to remain compatible with previous usages. Release
    requirements will prevent dev, metrics, and base from running.
    """
    if quick:
        base = True
        addons = True
        dev = True
    if not(addons or dev or metrics):
        base = True
    if release or addons:
        addon_requirements(ctx)
    # "release" takes precedence
    if release:
        req_file = os.path.join(HERE, 'requirements', 'release.txt')
        ctx.run(
            pip_install(req_file, constraints_file=CONSTRAINTS_PATH),
            echo=True
        )
    else:
        if dev:  # then dev requirements
            req_file = os.path.join(HERE, 'requirements', 'dev.txt')
            ctx.run(
                pip_install(req_file, constraints_file=CONSTRAINTS_PATH),
                echo=True
            )
        if metrics:  # then dev requirements
            req_file = os.path.join(HERE, 'requirements', 'metrics.txt')
            ctx.run(
                pip_install(req_file, constraints_file=CONSTRAINTS_PATH),
                echo=True
            )
        if base:  # then base requirements
            req_file = os.path.join(HERE, 'requirements.txt')
            ctx.run(
                pip_install(req_file, constraints_file=CONSTRAINTS_PATH),
                echo=True
            )
    # fix URITemplate name conflict h/t @github
    ctx.run('pip uninstall uritemplate.py --yes || true')
    ctx.run('pip install --no-cache-dir uritemplate.py==0.3.0')

@task
def test_module(ctx, module=None, verbosity=2):
    """Helper for running tests.
    """
    # Allow selecting specific submodule
    module_fmt = ' '.join(module) if isinstance(module, list) else module
    args = ' --verbosity={0} -s {1}'.format(verbosity, module_fmt)
    # Use pty so the process buffers "correctly"
    ctx.run(bin_prefix(TEST_CMD) + args, pty=True)

@task
def test_osf(ctx):
    """Run the OSF test suite."""
    test_module(ctx, module='tests/')

@task
def test_api(ctx):
    """Run the API test suite."""
    test_module(ctx, module='api_tests/')

@task
def test_admin(ctx):
    """Run the Admin test suite."""
    # test_module(ctx, module="admin_tests/")
    module = 'admin_tests/'
    module_fmt = ' '.join(module) if isinstance(module, list) else module
    admin_tasks.manage(ctx, 'test {}'.format(module_fmt))

@task
def test_varnish(ctx):
    """Run the Varnish test suite."""
    proc = apiserver(ctx, wait=False, autoreload=False)
    try:
        sleep(5)
        test_module(ctx, module='api/caching/tests/test_caching.py')
    finally:
        proc.kill()

@task
def test_addons(ctx):
    """Run all the tests in the addons directory.
    """
    modules = []
    for addon in settings.ADDONS_REQUESTED:
        module = os.path.join(settings.BASE_PATH, 'addons', addon)
        modules.append(module)
    test_module(ctx, module=modules)

@task
def test(ctx, all=False, syntax=False):
    """
    Run unit tests: OSF (always), plus addons and syntax checks (optional)
    """
    if syntax:
        flake(ctx)
        jshint(ctx)

    test_osf(ctx)
    test_api(ctx)
    test_admin(ctx)

    if all:
        test_addons(ctx)
        karma(ctx, single=True, browsers='PhantomJS')

@task
def test_js(ctx):
    jshint(ctx)
    karma(ctx, single=True, browsers='PhantomJS')

@task
def test_travis_osf(ctx):
    """
    Run half of the tests to help travis go faster. Lints and Flakes happen everywhere to keep from wasting test time.
    """
    flake(ctx)
    jshint(ctx)
    test_osf(ctx)
    test_addons(ctx)

@task
def test_travis_else(ctx):
    """
    Run other half of the tests to help travis go faster. Lints and Flakes happen everywhere to keep from
    wasting test time.
    """
    flake(ctx)
    jshint(ctx)
    test_api(ctx)
    test_admin(ctx)

@task
def test_travis_varnish(ctx):
    """
    Run the fast and quirky JS tests and varnish tests in isolation
    """
    test_js(ctx)
    test_varnish(ctx)

@task
def karma(ctx, single=False, sauce=False, browsers=None):
    """Run JS tests with Karma. Requires PhantomJS to be installed."""
    karma_bin = os.path.join(
        HERE, 'node_modules', 'karma', 'bin', 'karma'
    )
    cmd = '{} start'.format(karma_bin)
    if sauce:
        cmd += ' karma.saucelabs.conf.js'
    if single:
        cmd += ' --single-run'
    # Use browsers if specified on the command-line, otherwise default
    # what's specified in karma.conf.js
    if browsers:
        cmd += ' --browsers {}'.format(browsers)
    ctx.run(cmd, echo=True)

@task
def wheelhouse(ctx, addons=False, release=False, dev=False, metrics=False, pty=True):
    """Build wheels for python dependencies.

    Examples:

        inv wheelhouse --dev
        inv wheelhouse --addons
        inv wheelhouse --release
        inv wheelhouse --metrics
    """
    if release or addons:
        for directory in os.listdir(settings.ADDON_PATH):
            path = os.path.join(settings.ADDON_PATH, directory)
            if os.path.isdir(path):
                req_file = os.path.join(path, 'requirements.txt')
                if os.path.exists(req_file):
                    cmd = 'pip wheel --find-links={} -r {} --wheel-dir={} -c {}'.format(
                        WHEELHOUSE_PATH, req_file, WHEELHOUSE_PATH, CONSTRAINTS_PATH,
                    )
                    ctx.run(cmd, pty=pty)
    if release:
        req_file = os.path.join(HERE, 'requirements', 'release.txt')
    elif dev:
        req_file = os.path.join(HERE, 'requirements', 'dev.txt')
    elif metrics:
        req_file = os.path.join(HERE, 'requirements', 'metrics.txt')
    else:
        req_file = os.path.join(HERE, 'requirements.txt')
    cmd = 'pip wheel --find-links={} -r {} --wheel-dir={} -c {}'.format(
        WHEELHOUSE_PATH, req_file, WHEELHOUSE_PATH, CONSTRAINTS_PATH,
    )
    ctx.run(cmd, pty=pty)

@task
def addon_requirements(ctx):
    """Install all addon requirements."""
    for directory in os.listdir(settings.ADDON_PATH):
        path = os.path.join(settings.ADDON_PATH, directory)

        requirements_file = os.path.join(path, 'requirements.txt')
        if os.path.isdir(path) and os.path.isfile(requirements_file):
            print('Installing requirements for {0}'.format(directory))
            ctx.run(
                pip_install(requirements_file, constraints_file=CONSTRAINTS_PATH),
                echo=True
            )

    print('Finished installing addon requirements')

@task
def travis_addon_settings(ctx):
    for directory in os.listdir(settings.ADDON_PATH):
        path = os.path.join(settings.ADDON_PATH, directory, 'settings')
        if os.path.isdir(path):
            try:
                open(os.path.join(path, 'local-travis.py'))
                ctx.run('cp {path}/local-travis.py {path}/local.py'.format(path=path))
            except IOError:
                pass

@task
def copy_addon_settings(ctx):
    for directory in os.listdir(settings.ADDON_PATH):
        path = os.path.join(settings.ADDON_PATH, directory, 'settings')
        if os.path.isdir(path) and not os.path.isfile(os.path.join(path, 'local.py')):
            try:
                open(os.path.join(path, 'local-dist.py'))
                ctx.run('cp {path}/local-dist.py {path}/local.py'.format(path=path))
            except IOError:
                pass

@task
def copy_settings(ctx, addons=False):
    # Website settings
    if not os.path.isfile('website/settings/local.py'):
        print('Creating local.py file')
        ctx.run('cp website/settings/local-dist.py website/settings/local.py')

    # Addon settings
    if addons:
        copy_addon_settings(ctx)

@task
def packages(ctx):
    brew_commands = [
        'update',
        'upgrade',
        'install libxml2',
        'install libxslt',
        'install elasticsearch',
        'install rabbitmq',
        'install node',
        'tap tokutek/tokumx',
        'install tokumx-bin',
    ]
    if platform.system() == 'Darwin':
        print('Running brew commands')
        for item in brew_commands:
            command = 'brew {cmd}'.format(cmd=item)
            ctx.run(command)
    elif platform.system() == 'Linux':
        # TODO: Write a script similar to brew bundle for Ubuntu
        # e.g., run('sudo apt-get install [list of packages]')
        pass

@task(aliases=['bower'])
def bower_install(ctx):
    print('Installing bower-managed packages')
    bower_bin = os.path.join(HERE, 'node_modules', 'bower', 'bin', 'bower')
    ctx.run('{} prune --allow-root'.format(bower_bin), echo=True)
    ctx.run('{} install --allow-root'.format(bower_bin), echo=True)

@task
def setup(ctx):
    """Creates local settings, and installs requirements"""
    copy_settings(ctx, addons=True)
    packages(ctx)
    requirements(ctx, addons=True, dev=True)
    # Build nodeCategories.json before building assets
    build_js_config_files(ctx)
    assets(ctx, dev=True, watch=False)

@task
def clear_sessions(ctx, months=1, dry_run=False):
    from website.app import init_app
    init_app(routes=False, set_backends=True)
    from scripts import clear_sessions
    clear_sessions.clear_sessions_relative(months=months, dry_run=dry_run)

# Release tasks

@task
def hotfix(ctx, name, finish=False, push=False):
    """Rename hotfix branch to hotfix/<next-patch-version> and optionally
    finish hotfix.
    """
    print('Checking out master to calculate curent version')
    ctx.run('git checkout master')
    latest_version = latest_tag_info()['current_version']
    print('Current version is: {}'.format(latest_version))
    major, minor, patch = latest_version.split('.')
    next_patch_version = '.'.join([major, minor, str(int(patch) + 1)])
    print('Bumping to next patch version: {}'.format(next_patch_version))
    print('Renaming branch...')

    new_branch_name = 'hotfix/{}'.format(next_patch_version)
    ctx.run('git checkout {}'.format(name), echo=True)
    ctx.run('git branch -m {}'.format(new_branch_name), echo=True)
    if finish:
        ctx.run('git flow hotfix finish {}'.format(next_patch_version), echo=True, pty=True)
    if push:
        ctx.run('git push origin master', echo=True)
        ctx.run('git push --tags', echo=True)
        ctx.run('git push origin develop', echo=True)

@task
def feature(ctx, name, finish=False, push=False):
    """Rename the current branch to a feature branch and optionally finish it."""
    print('Renaming branch...')
    ctx.run('git branch -m feature/{}'.format(name), echo=True)
    if finish:
        ctx.run('git flow feature finish {}'.format(name), echo=True)
    if push:
        ctx.run('git push origin develop', echo=True)

# Adapted from bumpversion
def latest_tag_info():
    try:
        # git-describe doesn't update the git-index, so we do that
        # subprocess.check_output(["git", "update-index", "--refresh"])

        # get info about the latest tag in git
        describe_out = subprocess.check_output([
            'git',
            'describe',
            '--dirty',
            '--tags',
            '--long',
            '--abbrev=40'
        ], stderr=subprocess.STDOUT
        ).decode().split('-')
    except subprocess.CalledProcessError as err:
        raise err
        # logger.warn("Error when running git describe")
        return {}

    info = {}

    if describe_out[-1].strip() == 'dirty':
        info['dirty'] = True
        describe_out.pop()

    info['commit_sha'] = describe_out.pop().lstrip('g')
    info['distance_to_latest_tag'] = int(describe_out.pop())
    info['current_version'] = describe_out.pop().lstrip('v')

    # assert type(info["current_version"]) == str
    assert 0 == len(describe_out)

    return info

# Tasks for generating and bundling SSL certificates
# See http://cosdev.readthedocs.org/en/latest/osf/ops.html for details

@task
def generate_key(ctx, domain, bits=2048):
    cmd = 'openssl genrsa -des3 -out {0}.key {1}'.format(domain, bits)
    ctx.run(cmd)

@task
def generate_key_nopass(ctx, domain):
    cmd = 'openssl rsa -in {domain}.key -out {domain}.key.nopass'.format(
        domain=domain
    )
    ctx.run(cmd)

@task
def generate_csr(ctx, domain):
    cmd = 'openssl req -new -key {domain}.key.nopass -out {domain}.csr'.format(
        domain=domain
    )
    ctx.run(cmd)

@task
def request_ssl_cert(ctx, domain):
    """Generate a key, a key with password removed, and a signing request for
    the specified domain.

    Usage:
    > invoke request_ssl_cert pizza.osf.io
    """
    generate_key(ctx, domain)
    generate_key_nopass(ctx, domain)
    generate_csr(ctx, domain)

@task
def bundle_certs(ctx, domain, cert_path):
    """Concatenate certificates from NameCheap in the correct order. Certificate
    files must be in the same directory.
    """
    cert_files = [
        '{0}.crt'.format(domain),
        'COMODORSADomainValidationSecureServerCA.crt',
        'COMODORSAAddTrustCA.crt',
        'AddTrustExternalCARoot.crt',
    ]
    certs = ' '.join(
        os.path.join(cert_path, cert_file)
        for cert_file in cert_files
    )
    cmd = 'cat {certs} > {domain}.bundle.crt'.format(
        certs=certs,
        domain=domain,
    )
    ctx.run(cmd)

@task
def clean_assets(ctx):
    """Remove built JS files."""
    public_path = os.path.join(HERE, 'website', 'static', 'public')
    js_path = os.path.join(public_path, 'js')
    ctx.run('rm -rf {0}'.format(js_path), echo=True)

@task(aliases=['pack'])
def webpack(ctx, clean=False, watch=False, dev=False, colors=False):
    """Build static assets with webpack."""
    if clean:
        clean_assets(ctx)
    webpack_bin = os.path.join(HERE, 'node_modules', 'webpack', 'bin', 'webpack.js')
    args = [webpack_bin]
    args += ['--progress']
    if watch:
        args += ['--watch']
    if colors:
        args += ['--colors']
    config_file = 'webpack.dev.config.js' if dev else 'webpack.prod.config.js'
    args += ['--config {0}'.format(config_file)]
    command = ' '.join(args)
    ctx.run(command, echo=True)

@task()
def build_js_config_files(ctx):
    from website import settings
    print('Building JS config files...')
    with open(os.path.join(settings.STATIC_FOLDER, 'built', 'nodeCategories.json'), 'wb') as fp:
        json.dump(settings.NODE_CATEGORY_MAP, fp)
    print('...Done.')

@task()
def assets(ctx, dev=False, watch=False, colors=False):
    """Install and build static assets."""
    npm = 'npm install'
    if not dev:
        npm += ' --production'
    ctx.run(npm, echo=True)
    bower_install(ctx)
    build_js_config_files(ctx)
    # Always set clean=False to prevent possible mistakes
    # on prod
    webpack(ctx, clean=False, watch=watch, dev=dev, colors=colors)

@task
def generate_self_signed(ctx, domain):
    """Generate self-signed SSL key and certificate.
    """
    cmd = (
        'openssl req -x509 -nodes -days 365 -newkey rsa:2048'
        ' -keyout {0}.key -out {0}.crt'
    ).format(domain)
    ctx.run(cmd)

@task
def update_citation_styles(ctx):
    from scripts import parse_citation_styles
    total = parse_citation_styles.main()
    print('Parsed {} styles'.format(total))

@task
def clean(ctx, verbose=False):
    ctx.run('find . -name "*.pyc" -delete', echo=True)

@task(default=True)
def usage(ctx):
    ctx.run('invoke --list')

### Maintenance Tasks ###

@task
def set_maintenance(ctx, start=None, end=None):
    from website.maintenance import set_maintenance, get_maintenance
    """Set the time period for the maintenance notice to be displayed.
    If no start or end values are displayed, default to starting now
    and ending 24 hours from now. If no timezone info is passed along,
    everything will be converted to UTC.

    If a given end time results in a start that is after the end, start
    will be changed to be 24 hours before the end time.

    Examples:
        invoke set_maintenance_state
        invoke set_maintenance_state --start 2016-03-16T15:41:00-04:00
        invoke set_maintenance_state --end 2016-03-16T15:41:00-04:00
    """
    set_maintenance(start, end)
    state = get_maintenance()
    print('Maintenance notice up for {} to {}.'.format(state['start'], state['end']))

@task
def unset_maintenance(ctx):
    from website.maintenance import unset_maintenance
    print('Taking down maintenance notice...')
    unset_maintenance()
    print('...Done.')


text:
<!DOCTYPE html>
<!--
Copyright 2013 The Polymer Authors. All rights reserved.
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file.
-->
<html>
  <head>
    <title></title>
    <meta charset="UTF-8">
    <script src="../../../ShadowDOM/shadowdom.js"></script>
    <script src="../../../lib/patches-shadowdom-polyfill.js"></script>
    <script src="../../../lib/template.js"></script>
    <script src="../../../MDV/src/mdv.js"></script>
    <script src="../../../lib/querySelector.js"></script>
  </head>
  <style>
    template {
      display: none;
    }
  </style>
  <body>
    <template>
      Hello World from Working Test
    </template>
    <script>
      doc = ShadowDOMPolyfill.wrap(document);
      doc.addEventListener('DOMContentLoaded', function() {
        var template = document.querySelector('template');
        var instance = template.createInstance();
        doc.body.appendChild(instance);
      });
    </script>
  </body>
</html>

redpajama_set_name: RedPajamaGithub


text:
/*
 * Public domain
 * arpa/inet.h compatibility shim
 */

#ifndef _WIN32
#include_next <arpa/inet.h>
#else
#include <win32netcompat.h>

#ifndef AI_ADDRCONFIG
#define AI_ADDRCONFIG               0x00000400
#endif

#endif

#ifndef HAVE_INET_PTON
int inet_pton(int af, const char * src, void * dst);
#endif


text:
//
// InterConnect.cs
//
// Author:
//       Martin Haesemeyer <m.haesemeyer@gmail.com>
//
// Copyright (c) 2015 Martin Haesemeyer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

using System;
using System.Collections.Generic;
using System.Text;

namespace PythonInterface
{
    internal interface PyObject<T>
    {
        T Data{ get;}

        string VarName{ get;}

        string EncodingStatement{get;}
    }

    internal struct PyScalar<T> : PyObject<T> where T : struct, IComparable, IComparable<T>
    {
        private static int lastID = 0;

        public T Data{ get; private set; }

        public string VarName{ get; private set; }

        public string EncodingStatement
        {
            get
            {
                return string.Format("{0} = {1}", VarName, Data);
            }
        }

        public override string ToString()
        {
            return EncodingStatement;
        }

        public PyScalar(T value, string varName="")
        {
            if (varName == "")
            {
                VarName = "s" + lastID.ToString();
                lastID++;
            }
            else
                VarName = varName;
            Data = value;
        }
    }//PyScalar<T>

    /// <summary>
    /// Represents a Numpy array as a python statement
    /// </summary>
    internal struct NumpyArray1D : PyObject<double[]>
    {
        private static int lastID = 0;

        public double[] Data{ get; private set; }

        /// <summary>
        /// The name of the numpy variable
        /// </summary>
        public string VarName{get;private set;}

        public string EncodingStatement
        {
            get
            {
                //TODO: It is unclear what the maximum length statement
                //would be that we can "send over the wire" - have tested
                //arrays with 5e6 elements which worked fine but a better
                //approac might be to return a string[] of multiple statement
                //i.e. appends for long arrays!
                //In that case we will have to decide on what to do with
                //the ToString() override
                if (Data == null || Data.Length == 0)
                    return "";
                StringBuilder sd = new StringBuilder(Data.Length * 2 + 10);
                sd.Append(VarName);
                sd.Append('=');
                sd.Append(string.Format("{0}.array([",PyPlotInterface.NP));
                //add data to statement
                foreach (double d in Data)
                {
                    sd.Append(d.ToString() + ",");
                }
                sd.Append("])");//close list bracket and array function bracket
                return sd.ToString();
            }
        }

        public override string ToString()
        {
            return EncodingStatement;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="PythonProcess.NumpyArray1D"/> struct.
        /// </summary>
        /// <param name="data">The data in the array</param>
        /// <param name="varName">The name of the numpy variable</param>
        public NumpyArray1D(double[] data, string varName = "")
        {
            if (varName == "")
            {
                VarName = "x" + lastID.ToString();
                lastID++;
            }
            else
                VarName = varName;
            Data = data;
        }
    }//NumpyArray1D

    /// <summary>
    /// Represents a (strongly typed) python tuple
    /// </summary>
    internal struct PyTuple<T> : PyObject<T[]> where T : struct
    {
        private static int lastID = 0;

        public T[] Data{ get; private set; }

        /// <summary>
        /// The name of the numpy variable
        /// </summary>
        public string VarName{get;private set;}

        public string EncodingStatement
        {
            get
            {
                //TODO: It is unclear what the maximum length statement
                //would be that we can "send over the wire" - have tested
                //arrays with 5e6 elements which worked fine but a better
                //approac might be to return a string[] of multiple statement
                //i.e. appends for long arrays!
                //In that case we will have to decide on what to do with
                //the ToString() override
                if (Data == null || Data.Length == 0)
                    return "";
                StringBuilder sd = new StringBuilder(Data.Length * 2 + 10);
                sd.Append(VarName);
                sd.Append('=');
                sd.Append('(');
                //add data to statement
                foreach (T d in Data)
                {
                    sd.Append(d.ToString() + ",");
                }
                sd.Append(')');//close bracket
                return sd.ToString();
            }
        }

        public override string ToString()
        {
            return EncodingStatement;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="PythonProcess.PyTuple"/> struct.
        /// </summary>
        /// <param name="data">The data in the array</param>
        /// <param name="varName">The name of the tuple variable</param>
        public PyTuple(T[] data, string varName = "")
        {
            if (varName == "")
            {
                VarName = "t" + lastID.ToString();
                lastID++;
            }
            else
                VarName = varName;
            Data = data;
        }
    }//PyTuple

}


text:
package com.redshape.utils.range;

import com.redshape.utils.Commons;
import com.redshape.utils.ILambda;
import com.redshape.utils.InvocationException;
import com.redshape.utils.Lambda;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Cyril A. Karpenko <self@nikelin.ru>
 * @package com.redshape.utils.range
 * @date 8/14/11 6:37 PM
 */
public final class RangeUtils {
    private static final String CHECK_INTERSECTIONS_METHOD = "checkIntersections";

    private static final Map<Class<?>,Map<Class<?>, Lambda<Boolean>>> checkIntersectionsMapping
            = new HashMap<Class<?>,Map<Class<?>, Lambda<Boolean>>>();

    static {
        checkIntersectionsMapping.put(
                ListRange.class,
                Commons.map(
                    Commons.<Class<?>, Lambda<Boolean>>pair(
                            ListRange.class,
                            new Lambda<Boolean>() {
                                @Override
                                public Boolean invoke(Object... object) throws InvocationException {
                                    ListRange source = (ListRange) object[0];
                                    ListRange target = (ListRange) object[1];

                                    for ( IRange sourceSubRange : (Collection<IRange>) source.getSubRanges() ) {
                                        for ( IRange targetSubRange : (Collection<IRange>) target.getSubRanges() ) {
                                            if ( checkIntersections(
                                                    sourceSubRange,
                                                    targetSubRange ) ) {
                                                return true;
                                            }
                                        }
                                    }

                                    return false;
                                }
                            }
                    ),
                    Commons.<Class<?>, Lambda<Boolean>>pair(
                            SingularRange.class,
                            new Lambda<Boolean>() {
                                @Override
                                public Boolean invoke(Object... object) throws InvocationException {
                                    ListRange<? extends Comparable> source = (ListRange<? extends Comparable>) object[0];
                                    SingularRange<? extends Comparable> target = (SingularRange<? extends Comparable>) object[1];

                                    return checkIntersections( target, source );
                                }
                            }
                    ),
                    Commons.<Class<?>, Lambda<Boolean>>pair(
                            IntervalRange.class,
                            new Lambda<Boolean>() {
                                @Override
                                public Boolean invoke(Object... object) throws InvocationException {
                                    ListRange source = (ListRange) object[0];
                                    IntervalRange target = (IntervalRange) object[1];

                                    for ( IRange subRange : (Collection<IRange>) source.getSubRanges() ) {
                                        if ( checkIntersections( subRange, target ) ) {
                                            return true;
                                        }
                                    }

                                    return false;
                                }
                            }
                    )
                )
        );
        checkIntersectionsMapping.put(
                IntervalRange.class,
                Commons.<Class<?>, Lambda<Boolean>>map(
                        Commons.<Class<?>, Lambda<Boolean>>pair(
                                SingularRange.class,
                                new Lambda<Boolean>() {
                                    @Override
                                    public Boolean invoke(Object... object) throws InvocationException {
                                        assertArgumentsCount(object, 2);

                                        return checkIntersections(
                                            (SingularRange<? extends Comparable>) object[1],
                                            (IntervalRange<? extends Comparable >) object[0]
                                        );
                                    }
                                }
                        ),
                        Commons.<Class<?>, Lambda<Boolean>>pair(
                                ListRange.class,
                                new Lambda<Boolean>() {
                                    @Override
                                    public Boolean invoke(Object... object) throws InvocationException {
                                        return checkIntersections( (ListRange<? extends Comparable>) object[1],
                                                (IntervalRange<? extends Comparable>) object[0] );
                                    }
                                }
                        ),
                        Commons.<Class<?>, Lambda<Boolean>>pair(
                                IntervalRange.class,
                                new Lambda<Boolean>() {
                                    @Override
                                    public Boolean invoke(Object... object) throws InvocationException {
                                        IntervalRange source = (IntervalRange) object[0];
                                        IntervalRange target = (IntervalRange) object[1];

                                        switch (source.getType()) {
                                            case INCLUSIVE:
                                                return source.getStart().compareTo(target.getEnd()) != 1
                                                        && source.getEnd().compareTo(target.getStart()) != -1;
                                            case EXCLUSIVE:
                                                return source.getStart().compareTo(target.getEnd()) == -1
                                                        && source.getEnd().compareTo(target.getStart()) == 1;
                                            default:
                                                throw new IllegalArgumentException("Unsupported interval range type");
                                        }
                                    }
                                }
                        )
                )
        );
        checkIntersectionsMapping.put(
                SingularRange.class,
                Commons.<Class<?>, Lambda<Boolean>>map(
                        Commons.<Class<?>, Lambda<Boolean>>pair(
                                SingularRange.class,
                                new Lambda<Boolean>() {
                                    @Override
                                    public Boolean invoke(Object... object) throws InvocationException {
                                        assertArgumentsCount(object, 2);

                                        return ( (SingularRange<?>) object[0]).getValue()
                                                .equals(((SingularRange<?>) object[1]).getValue());
                                    }
                                }
                        ),
                        Commons.<Class<?>, Lambda<Boolean>>pair(
                                IntervalRange.class,
                                new Lambda<Boolean>() {
                                    @Override
                                    public Boolean invoke(Object... object) throws InvocationException {
                                        SingularRange source = (SingularRange) object[0];
                                        IntervalRange target = (IntervalRange) object[1];

                                        switch ( target.getType() ) {
                                            case EXCLUSIVE:
                                                return source.getValue().compareTo( target.getStart() ) == 1
                                                        && source.getValue().compareTo( target.getEnd() ) == -1;
                                            case INCLUSIVE:
                                                return source.getValue().compareTo( target.getStart() ) != -1
                                                        && source.getValue().compareTo( target.getEnd() ) != 1;
                                            default:
                                                throw new IllegalArgumentException("Unsupported interval range type");
                                        }
                                    }
                                }
                        ),
                        Commons.<Class<?>, Lambda<Boolean>>pair(
                                ListRange.class,
                                new Lambda<Boolean>() {
                                    @Override
                                    public Boolean invoke(Object... object) throws InvocationException {
                                        SingularRange source = (SingularRange) object[0];
                                        ListRange target = (ListRange) object[1];

                                        for ( IRange subRange : (Collection<IRange>) target.getSubRanges() ) {
                                            if ( checkIntersections(source, subRange) ) {
                                                return true;
                                            }
                                        }

                                        return false;
                                    }
                                }
                        )
                )
        );
    }

    public static <T extends Comparable<T>>
    boolean checkIntersections( IRange<T> source, IRange<? extends Comparable> target ) {
        if ( source.isEmpty() || target.isEmpty() ) {
            return false;
        }

        if ( null == source || null == target ) {
            throw new IllegalArgumentException("<null>");
        }

        Map<Class<?>, Lambda<Boolean>> mappings;
        if ( null == ( mappings = checkIntersectionsMapping.get(source.getClass() ) ) ) {
            throw new IllegalArgumentException("Unsupported range type "
                    + target.getClass().getName() );
        }

        ILambda<Boolean> method;
        if ( null == ( method = mappings.get( target.getClass() ) ) ) {
            throw new IllegalArgumentException("Unsupported range type "
                    + target.getClass().getName() );
        }

        try {
            return method.invoke(source, target);
        } catch ( Throwable e ) {
            throw new RuntimeException("Unable to invoke method ", e );
        }
    }

}


text:
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.api.ads.admanager.jaxws.v202208;

import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlType;

/**
 *
Java class for LineItemActivityAssociationError.Reason.
 *
 *
The following schema fragment specifies the expected content contained within this class.
 *

 *

 * <simpleType name="LineItemActivityAssociationError.Reason">
 *   <restriction base="{http://www.w3.org/2001/XMLSchema}string">
 *     <enumeration value="INVALID_ACTIVITY_FOR_ADVERTISER"/>
 *     <enumeration value="INVALID_COST_TYPE_FOR_ASSOCIATION"/>
 *     <enumeration value="UNKNOWN"/>
 *   </restriction>
 * </simpleType>
 *

 *
 */
@XmlType(name = "LineItemActivityAssociationError.Reason")
@XmlEnum
public enum LineItemActivityAssociationErrorReason {

    /**
     *
     *                 When associating an activity to a line item the activity must belong to the same
     *                 advertiser as the line item.
     *
     *
     */
    INVALID_ACTIVITY_FOR_ADVERTISER,

    /**
     *
     *                 Activities can only be associated with line items of {@link CostType.CPA}.
     *
     *
     */
    INVALID_COST_TYPE_FOR_ASSOCIATION,

    /**
     *
     *                 The value returned if the actual value is not exposed by the requested API version.
     *
     *
     */
    UNKNOWN;

    public String value() {
        return name();
    }

    public static LineItemActivityAssociationErrorReason fromValue(String v) {
        return valueOf(v);
    }

}


text:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

          <title>dashboards - models.api.responses.dashboards</title>
          <meta name="description" content="dashboards - models.api.responses.dashboards" />
          <meta name="keywords" content="dashboards models.api.responses.dashboards" />
          <meta http-equiv="content-type" content="text/html; charset=UTF-8" />

      <link href="../../../../lib/template.css" media="screen" type="text/css" rel="stylesheet" />
      <link href="../../../../lib/diagrams.css" media="screen" type="text/css" rel="stylesheet" id="diagrams-css" />

models.api.responses

dashboards

        package

        dashboards

<input id="mbrsel-input" type="text" accesskey="/" />

            Visibility

Public

All

Type Members

        class

        DashboardSummaryResponse extends AnyRef

        class

        DashboardWidgetResponse extends AnyRef

        class

        DashboardWidgetValueResponse extends AnyRef

        class

        GetDashboardsResponse extends AnyRef

        class

        WidgetPositionResponse extends AnyRef

Ungrouped


text:
Dynamic Synchronous Internet Speed Data Collector Ultimate 3000™ ©
=====================

A quick and dirty C# application I wrote up to store the Average and Maximum download speed every five minutes into a MySQL Database that can be later extracted and analysed.

Working application, configuration is hard-coded to my Database as of now, can be changed by changing the code.


text:
/**
 * Provides {@link de.codescape.bitvunit.rule.Rule} implementations focusing on accessible lists.
 */
package de.codescape.bitvunit.rule.lists;