<commit_before>#!/usr/bin/env python
#
# Copyright 2013 Facebook
#
# 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.

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
import inspect
import collections
from importlib import import_module

from gevent.event import AsyncResult
import gevent

from .util.decorator import EasyDecorator
from .irc import Message

__all__ = ['component_class',
           'msg_parser',
           'watches', 'observe', 'observes', 'handle', 'handles',
           'every',
           'triggers_on', 'keyword', 'keywords', 'trigger', 'triggers',
           'ComponentManager']

#Used to mark classes for later inspection
CLASS_MARKER = '_PYAIB_COMPONENT'


def component_class(cls):
    """
        Let the component loader know to load this class
        If they pass a string argument to the decorator use it as a context
        name for the instance
    """
    if isinstance(cls, basestring):
        context = cls

        def wrapper(cls):
            setattr(cls, CLASS_MARKER, context)
            return cls
        return wrapper

    elif inspect.isclass(cls):
        setattr(cls, CLASS_MARKER, True)
        return cls


def _requires(*names):
    def wrapper(cls):
        cls.__requires__ = names
        return cls
    return wrapper

component_class.requires = _requires


def _get_plugs(method, kind):
    """ Setup a place to put plugin hooks, allowing only one type per func """
    if not hasattr(method, '__plugs__'):
        method.__plugs__ = (kind, [])
    elif method.__plugs__[0] != kind:
        raise RuntimeError('Multiple Hook Types on a single method (%s)' %
                           method.__name__)
    return method.__plugs__[1]


def msg_parser(*kinds, **kwargs):
    """
    Defines that this method is a message type parser
    @param kinds: List of IRC message types/numerics
    @param kwargs: Accepts chain keyword, True or 'after' executes this after
        the existing parser. 'before' execute before existing parsers.
        default is to replace the existing parser
    """
    chain = kwargs.pop('chain', False)
    def wrapper(func):
        parsers = _get_plugs(func, 'parsers')
        parsers.extend([(kind, chain) for kind in kinds])
        return func
    return wrapper


def watches(*events):
    """ Define a series of events to later be subscribed to """
    def wrapper(func):
        eplugs = _get_plugs(func, 'events')
        eplugs.extend([event for event in events if event not in eplugs])
        return func
    return wrapper
observes = watches
observe = watches
handle = watches
handles = watches


class _Ignore(EasyDecorator):
    """Only pass if triggers is from user not ignored"""
    def wrapper(dec, irc_c, msg, *args):
        if dec.args and dec.kwargs.get('runtime'):
            for attr in dec.args:
                if hasattr(dec._instance, attr):
                    ignore_nicks = getattr(dec._instance, attr)
                    if isinstance(ignore_nicks, basestring)\
                            and msg.sender.nick == ignore_nicks:
                        return
                    elif isinstance(ignore_nicks, collections.Container)\
                            and msg.sender.nick in ignore_nicks:
                        return
        elif dec.args and msg.sender.nick in dec.args:
            return
        return dec.call(irc_c, msg, *args)
watches.ignore = _Ignore


class _Channel(EasyDecorator):
    """Ignore triggers not in channels, or optionally a list of channels"""
    def wrapper(dec, irc_c, msg, *args):
        if msg.channel:
            #Did they want to restrict which channels
            #Should we lookup allowed channels at run time
            if dec.args and dec.kwargs.get('runtime'):
                for attr in dec.args:
                    if hasattr(dec._instance, attr):
                        channel = getattr(dec._instance, attr)
                        if isinstance(channel, basestring)\
                                and msg.channel.lower() == channel:
                            return
                        elif isinstance(channel, collections.Container)\
                                and msg.channel.lower() in channel:
                            return
            elif dec.args and msg.channel not in dec.args:
                return
            return dec.call(irc_c, msg, *args)
watches.channel = _Channel


def every(seconds, name=None):<commit_msg>Remove useless .lower()<commit_after>#!/usr/bin/env python
#
# Copyright 2013 Facebook
#
# 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.

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
import inspect
import collections
from importlib import import_module

from gevent.event import AsyncResult
import gevent

from .util.decorator import EasyDecorator
from .irc import Message

__all__ = ['component_class',
           'msg_parser',
           'watches', 'observe', 'observes', 'handle', 'handles',
           'every',
           'triggers_on', 'keyword', 'keywords', 'trigger', 'triggers',
           'ComponentManager']

#Used to mark classes for later inspection
CLASS_MARKER = '_PYAIB_COMPONENT'


def component_class(cls):
    """
        Let the component loader know to load this class
        If they pass a string argument to the decorator use it as a context
        name for the instance
    """
    if isinstance(cls, basestring):
        context = cls

        def wrapper(cls):
            setattr(cls, CLASS_MARKER, context)
            return cls
        return wrapper

    elif inspect.isclass(cls):
        setattr(cls, CLASS_MARKER, True)
        return cls


def _requires(*names):
    def wrapper(cls):
        cls.__requires__ = names
        return cls
    return wrapper

component_class.requires = _requires


def _get_plugs(method, kind):
    """ Setup a place to put plugin hooks, allowing only one type per func """
    if not hasattr(method, '__plugs__'):
        method.__plugs__ = (kind, [])
    elif method.__plugs__[0] != kind:
        raise RuntimeError('Multiple Hook Types on a single method (%s)' %
                           method.__name__)
    return method.__plugs__[1]


def msg_parser(*kinds, **kwargs):
    """
    Defines that this method is a message type parser
    @param kinds: List of IRC message types/numerics
    @param kwargs: Accepts chain keyword, True or 'after' executes this after
        the existing parser. 'before' execute before existing parsers.
        default is to replace the existing parser
    """
    chain = kwargs.pop('chain', False)
    def wrapper(func):
        parsers = _get_plugs(func, 'parsers')
        parsers.extend([(kind, chain) for kind in kinds])
        return func
    return wrapper


def watches(*events):
    """ Define a series of events to later be subscribed to """
    def wrapper(func):
        eplugs = _get_plugs(func, 'events')
        eplugs.extend([event for event in events if event not in eplugs])
        return func
    return wrapper
observes = watches
observe = watches
handle = watches
handles = watches


class _Ignore(EasyDecorator):
    """Only pass if triggers is from user not ignored"""
    def wrapper(dec, irc_c, msg, *args):
        if dec.args and dec.kwargs.get('runtime'):
            for attr in dec.args:
                if hasattr(dec._instance, attr):
                    ignore_nicks = getattr(dec._instance, attr)
                    if isinstance(ignore_nicks, basestring)\
                            and msg.sender.nick == ignore_nicks:
                        return
                    elif isinstance(ignore_nicks, collections.Container)\
                            and msg.sender.nick in ignore_nicks:
                        return
        elif dec.args and msg.sender.nick in dec.args:
            return
        return dec.call(irc_c, msg, *args)
watches.ignore = _Ignore


class _Channel(EasyDecorator):
    """Ignore triggers not in channels, or optionally a list of channels"""
    def wrapper(dec, irc_c, msg, *args):
        if msg.channel:
            #Did they want to restrict which channels
            #Should we lookup allowed channels at run time
            if dec.args and dec.kwargs.get('runtime'):
                for attr in dec.args:
                    if hasattr(dec._instance, attr):
                        channel = getattr(dec._instance, attr)
                        if isinstance(channel, basestring)\
                                and msg.channel == channel:
                            return
                        elif isinstance(channel, collections.Container)\
                                and msg.channel in channel:
                            return
            elif dec.args and msg.channel not in dec.args:
                return
            return dec.call(irc_c, msg, *args)
watches.channel = _Channel


def every(seconds, name=None):
{'fraction_non_alphanumeric': 0.08152392440691596, 'fraction_numerical': 0.002010454362685967, 'mean_word_length': 2.2218264248704664, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '1832931', 'n_tokens_mistral': 2643, 'n_tokens_neox': 2544, 'n_words': 953}