<commit_before>"""
switchboard.manager
~~~~~~~~~~~~~~~~

:copyright: (c) 2012 SourceForge.
:license: Apache License 2.0, see LICENSE for more details.
"""

import logging
from decorator import decorator

from pymongo import Connection

from . import signals
from .base import MongoModelDict
from .models import (
    Switch,
    DISABLED, SELECTIVE, GLOBAL, INHERIT,
    INCLUDE, EXCLUDE,
)
from .proxy import SwitchProxy
from .settings import settings, Settings
from .helpers import get_cache

log = logging.getLogger(__name__)


def nested_config(config):
    cfg = {}
    token = 'switch<PASSWORD>.'
    for k, v in config.iteritems():
        if k.startswith(token):
            cfg[k.replace(token, '')] = v
    return cfg


def configure(config, nested=False):
    """
    Useful for when you need to control Switchboard's setup
    """
    if nested:
        config = nested_config(config)
    # Re-read settings to make sure we have everything
    Settings.init(**config)
    # Establish the connection to Mongo
    mongo_timeout = getattr(settings, 'SWITCHBOARD_MONGO_TIMEOUT', None)
    # The config is in ms to match memcached, but pymongo wants seconds
    mongo_timeout = mongo_timeout // 1000 if mongo_timeout else mongo_timeout
    try:
        conn = Connection(settings.SWITCHBOARD_MONGO_HOST,
                          settings.SWITCHBOARD_MONGO_PORT,
                          network_timeout=mongo_timeout)
        db = conn[settings.SWITCHBOARD_MONGO_DB]
        collection = db[settings.SWITCHBOARD_MONGO_COLLECTION]
        Switch.c = collection
    except:
        log.exception('Unable to connect to the datastore')
    # Setup the cache
    cache_hosts = getattr(settings, 'SWITCHBOARD_CACHE_HOSTS', None)
    cache_timeout = getattr(settings, 'SWITCHBOARD_CACHE_TIMEOUT', None)
    operator.cache = get_cache(cache_hosts, cache_timeout)


@decorator
def switch_checked(func, *args, **kwargs):
    active = func(*args, **kwargs)
    key = args[1]
    signals.switch_checked.send(key, active=active)
    return active


class SwitchManager(MongoModelDict):
    DISABLED = DISABLED
    SELECTIVE = SELECTIVE
    GLOBAL = GLOBAL
    INHERIT = INHERIT

    INCLUDE = INCLUDE
    EXCLUDE = EXCLUDE

    def __init__(self, *args, **kwargs):
        # We'll store available conditions in the registry
        self._registry = {}
        # Inject args and kwargs that are known quantities; the SwitchManager
        # will always deal with the Switch model and so on.
        new_args = [Switch]
        for a in args:
            new_args.append(a)
        kwargs['key'] = 'key'
        kwargs['value'] = 'value'
        kwargs['cache'] = get_cache()
        super(SwitchManager, self).__init__(*new_args, **kwargs)

    def __unicode__(self):
        return "<%s: %s (%s)>" % (self.__class__.__name__,
                                  getattr(self, 'model', ''),
                                  self._registry.values())

    def __getitem__(self, key):
        """
        Returns a SwitchProxy, rather than a Switch. It allows us to
        easily extend the Switches method and automatically include our
        manager instance.
        """
        return SwitchProxy(self, super(SwitchManager, self).__getitem__(key))

    @switch_checked
    def is_active(self, key, *instances, **kwargs):
        """
        Returns ``True`` if any of ``instances`` match an active switch.
        Otherwise returns ``False``.

        >>> opersator.is_active('my_feature', request) #doctest: +SKIP
        """
        try:
            default = kwargs.pop('default', False)

            # Check all parents for a disabled state
            parts = key.split(':')
            if len(parts) > 1:
                child_kwargs = kwargs.copy()
                child_kwargs['default'] = None
                result = self.is_active(':'.join(parts[:-1]), *instances,
                                        **child_kwargs)

                if result is False:
                    return result
                elif result is True:
                    default = result

            try:
                switch = self[key]
            except KeyError:
                # switch is not defined, defer to parent
                return default

            if switch.status == GLOBAL:
                return True
            elif switch.status == DISABLED:
                return False<commit_msg>Sync'd with internal code.<commit_after>"""
switchboard.manager
~~~~~~~~~~~~~~~~

:copyright: (c) 2012 SourceForge.
:license: Apache License 2.0, see LICENSE for more details.
"""

import logging
from decorator import decorator

from pymongo import Connection

from . import signals
from .base import MongoModelDict
from .models import (
    Switch,
    DISABLED, SELECTIVE, GLOBAL, INHERIT,
    INCLUDE, EXCLUDE,
)
from .proxy import SwitchProxy
from .settings import settings, Settings
from .helpers import get_cache

log = logging.getLogger(__name__)


def nested_config(config):
    cfg = {}
    token = '<PASSWORD>.'
    for k, v in config.iteritems():
        if k.startswith(token):
            cfg[k.replace(token, '')] = v
    return cfg


def configure(config, nested=False):
    """
    Useful for when you need to control Switchboard's setup
    """
    if nested:
        config = nested_config(config)
    # Re-read settings to make sure we have everything
    Settings.init(**config)
    # Establish the connection to Mongo
    mongo_timeout = getattr(settings, 'SWITCHBOARD_MONGO_TIMEOUT', None)
    # The config is in ms to match memcached, but pymongo wants seconds
    mongo_timeout = mongo_timeout // 1000 if mongo_timeout else mongo_timeout
    try:
        conn = Connection(settings.SWITCHBOARD_MONGO_HOST,
                          settings.SWITCHBOARD_MONGO_PORT,
                          network_timeout=mongo_timeout)
        db = conn[settings.SWITCHBOARD_MONGO_DB]
        collection = db[settings.SWITCHBOARD_MONGO_COLLECTION]
        Switch.c = collection
    except:
        log.exception('Unable to connect to the datastore')
    # Setup the cache
    cache_hosts = getattr(settings, 'SWITCHBOARD_CACHE_HOSTS', None)
    cache_timeout = getattr(settings, 'SWITCHBOARD_CACHE_TIMEOUT', None)
    operator.cache = get_cache(cache_hosts, cache_timeout)


@decorator
def switch_checked(func, *args, **kwargs):
    active = func(*args, **kwargs)
    key = args[1]
    signals.switch_checked.send(key, active=active)
    return active


class SwitchManager(MongoModelDict):
    DISABLED = DISABLED
    SELECTIVE = SELECTIVE
    GLOBAL = GLOBAL
    INHERIT = INHERIT

    INCLUDE = INCLUDE
    EXCLUDE = EXCLUDE

    def __init__(self, *args, **kwargs):
        # We'll store available conditions in the registry
        self._registry = {}
        # Inject args and kwargs that are known quantities; the SwitchManager
        # will always deal with the Switch model and so on.
        new_args = [Switch]
        for a in args:
            new_args.append(a)
        kwargs['key'] = 'key'
        kwargs['value'] = 'value'
        kwargs['cache'] = get_cache()
        super(SwitchManager, self).__init__(*new_args, **kwargs)

    def __unicode__(self):
        return "<%s: %s (%s)>" % (self.__class__.__name__,
                                  getattr(self, 'model', ''),
                                  self._registry.values())

    def __getitem__(self, key):
        """
        Returns a SwitchProxy, rather than a Switch. It allows us to
        easily extend the Switches method and automatically include our
        manager instance.
        """
        return SwitchProxy(self, super(SwitchManager, self).__getitem__(key))

    @switch_checked
    def is_active(self, key, *instances, **kwargs):
        """
        Returns ``True`` if any of ``instances`` match an active switch.
        Otherwise returns ``False``.

        >>> opersator.is_active('my_feature', request) #doctest: +SKIP
        """
        try:
            default = kwargs.pop('default', False)

            # Check all parents for a disabled state
            parts = key.split(':')
            if len(parts) > 1:
                child_kwargs = kwargs.copy()
                child_kwargs['default'] = None
                result = self.is_active(':'.join(parts[:-1]), *instances,
                                        **child_kwargs)

                if result is False:
                    return result
                elif result is True:
                    default = result

            try:
                switch = self[key]
            except KeyError:
                # switch is not defined, defer to parent
                signals.switch_checked.send(None, active=default)
                return default

            if switch.status == GLOBAL:
                return True
            elif switch.status == DISABLED:
                return False
{'fraction_non_alphanumeric': 0.09538843161574022, 'fraction_numerical': 0.0029315593640771224, 'mean_word_length': 2.2219397021431164, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7450277', 'n_tokens_mistral': 2521, 'n_tokens_neox': 2399, 'n_words': 716}