<commit_before>#coding:utf-8
"""
Created on 03.08.2012
@author: pirogov
"""
import re
import inspect
import warnings

import tools

from m3.ui import actions as m3_actions

ACTION_NAME_ATTR = '_observing_name'


def _warn(msg):
    warnings.warn(msg, FutureWarning, 3)


#==============================================================================
# ControllerMixin
#==============================================================================
class ObservableMixin(object):
    """
    Наблюдатель за вызовом actions и кода в точках их (actions) расшрения
    """

    def __init__(self, observer, *args, **kwargs):
        super(ObservableMixin, self).__init__(*args, **kwargs)
        self._observer = observer
        self._already_registered = set()

    def _invoke(self, request, action, stack):
        """
        Вызов action под наблюдением
        """
        stack = stack[:]
        self._observer._prepare_for_listening(action, request, stack)

        # обработка контроллером
        with action._catcher as catcher:
            return super(ObservableMixin, self)._invoke(request, action, stack)
        return catcher.result

    def append_pack(self, pack):
        """
        Добавление ActionPack`а с регистрацией его action`ов в ObserVer`е
        """
        if self._observer._is_pack_populated(pack):
            # регистрация Pack`а в контроллере
            super(ObservableMixin, self).append_pack(pack)

    @property
    def urlpattern(self):
        """
        Возвращает кортеж вида (pattern, method), пригодный для регистрации
        в urlpatterns Django
        """
        url = self.url
        if url.startswith('/'):
            url = url[1:]
        if url.endswith('/'):
            url = url[:-2]
        return (r'^%s/' % url, self.process_request)


#==============================================================================
# ObservableController
#==============================================================================
class ObservableController(ObservableMixin, m3_actions.ActionController):
    """
    Контроллер, поддерживающий механизм подписки через Observer
    """
    class VerboseDeclarativeContext(m3_actions.DeclarativeActionContext):

        _internal_attrs = ['m3_window_id']

        def __init__(self, debug, **kwargs):
            m3_actions.DeclarativeActionContext.__init__(self, **kwargs)
            self.__debug = debug
            self.__declared = []

        def build(self, request, rules):
            self.__declared = rules.keys() + self._internal_attrs
            try:
                m3_actions.DeclarativeActionContext.build(self, request, rules)
            except m3_actions.CriticalContextBuildingError as e:
                if self.__debug:
                    raise
                else:
                    _warn(repr(e))
            for k, v in request.REQUEST.items():
                if not hasattr(self, k):
                    setattr(self, k, v)

        def __getattr__(self, attr):
            if not attr.startswith('__'):
                if attr not in self.__declared:
                    _warn('Attribute "%s" not declared!' % attr)
            return self.__dict__[attr]

    def build_context(self, request, rules):
        '''
        Выполняет построение контекста вызова операции ActionContext
        на основе переданного request
        '''
        if isinstance(rules, dict):
            from django.conf import settings
            return self.VerboseDeclarativeContext(debug=settings.DEBUG)
        else:
            return m3_actions.ActionContext()


#==============================================================================
# Observer
#==============================================================================
class Observer(object):
    """
    Реестр слушателей, реализующий подписку последних на действия в actions<commit_msg>Теперь VerboseDeclarativeContext выводит сообщения через logging<commit_after>#coding:utf-8
"""
Created on 03.08.2012
@author: pirogov
"""
import re
import inspect
import sys
import logging

import tools

from m3.ui import actions as m3_actions

ACTION_NAME_ATTR = '_observing_name'


def _warn(msg, level=3):
    """
    Костыль для вывода предупреждений в лог
    """
    frame = sys._getframe(level)
    fmt = '%%s (%s:%s)' % (frame.f_globals['__name__'], frame.f_lineno)
    logging.warn(fmt % msg)


#==============================================================================
# ControllerMixin
#==============================================================================
class ObservableMixin(object):
    """
    Наблюдатель за вызовом actions и кода в точках их (actions) расшрения
    """

    def __init__(self, observer, *args, **kwargs):
        super(ObservableMixin, self).__init__(*args, **kwargs)
        self._observer = observer
        self._already_registered = set()

    def _invoke(self, request, action, stack):
        """
        Вызов action под наблюдением
        """
        stack = stack[:]
        self._observer._prepare_for_listening(action, request, stack)

        # обработка контроллером
        with action._catcher as catcher:
            return super(ObservableMixin, self)._invoke(request, action, stack)
        return catcher.result

    def append_pack(self, pack):
        """
        Добавление ActionPack`а с регистрацией его action`ов в ObserVer`е
        """
        if self._observer._is_pack_populated(pack):
            # регистрация Pack`а в контроллере
            super(ObservableMixin, self).append_pack(pack)

    @property
    def urlpattern(self):
        """
        Возвращает кортеж вида (pattern, method), пригодный для регистрации
        в urlpatterns Django
        """
        url = self.url
        if url.startswith('/'):
            url = url[1:]
        if url.endswith('/'):
            url = url[:-2]
        return (r'^%s/' % url, self.process_request)


#==============================================================================
# ObservableController
#==============================================================================
class ObservableController(ObservableMixin, m3_actions.ActionController):
    """
    Контроллер, поддерживающий механизм подписки через Observer
    """
    class VerboseDeclarativeContext(m3_actions.DeclarativeActionContext):

        __internal_attrs = ['m3_window_id']

        def __init__(self, debug, **kwargs):
            m3_actions.DeclarativeActionContext.__init__(self, **kwargs)
            self.__debug = debug
            self.__declared = []

        def build(self, request, rules):
            self.__declared = rules.keys() + self.__internal_attrs
            try:
                m3_actions.DeclarativeActionContext.build(self, request, rules)
            except m3_actions.CriticalContextBuildingError as e:
                if self.__debug:
                    raise
                else:
                    _warn('%r, url="%s"' % (e, request.path_info))
            for k, v in request.REQUEST.items():
                if not hasattr(self, k):
                    setattr(self, k, v)

        def __getattr__(self, attr, default=(((),),)):
            if not attr.startswith('__'):
                if attr not in self.__declared:
                    _warn('Attribute "%s" not declared!' % attr)
            try:
                return self.__dict__[attr]
            except KeyError:
                if default == (((),),):
                    raise AttributeError(
                        "'%s' object has no attribute '%s'" % (
                            self.__class__.__name__, attr
                        ))
                return default

    def build_context(self, request, rules):
        '''
        Выполняет построение контекста вызова операции ActionContext
        на основе переданного request
        '''
        if isinstance(rules, dict):
            from django.conf import settings
            return self.VerboseDeclarativeContext(debug=settings.DEBUG)
        else:
            return m3_actions.ActionContext()


#==============================================================================
# Observer
#==============================================================================
class Observer(object):
    """
    Реестр слушателей, реализующий подписку последних на действия в actions
{'fraction_non_alphanumeric': 0.1991596638655462, 'fraction_numerical': 0.005042016806722689, 'mean_word_length': 2.6064935064935066, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4800564', 'n_tokens_mistral': 2281, 'n_tokens_neox': 2252, 'n_words': 516}