<commit_before>"""
   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.
"""

import os
import logging
from functools import cmp_to_key
import collections

from .server import runtimeInstances, update_event

log = logging.getLogger('remi.gui')


class VersionedDictionary(dict):
    """This dictionary allows to check if its content is changed.
       It has an attribute __version__ of type int that increments every change
    """
    def __init__(self, *args, **kwargs):
        self.__version__ = 0
        super(VersionedDictionary, self).__init__(*args, **kwargs)

    def __setitem__(self, key, value):
        if key in self:
            if self[key] == value:
                return
        self.__version__ += 1
        return super(VersionedDictionary, self).__setitem__(key, value)

    def __delitem__(self, key):
        if not key in self:
            return
        self.__version__ += 1
        return super(VersionedDictionary, self).__delitem__(key)


def decorate_set_on_listener(event_name, params):
    """ private decorator for use in the editor

    Parameters
    ----------
    event_name : str
        Name of the event to which it refers (es. For set_on_click_listener the event_name is "onclick"
    params : str
        The list of parameters for the listener function (es. "(self, new_value)")
    """

    def add_annotation(function):
        function._event_listener = {}
        function._event_listener['eventName'] = event_name
        function._event_listener['prototype'] = params
        return function

    return add_annotation


def decorate_constructor_parameter_types(type_list):
    def add_annotation(function):
        function._constructor_types = type_list
        return function

    return add_annotation


def to_pix(x):
    return str(x) + 'px'


def from_pix(x):
    v = 0
    try:
        v = int(float(x.replace('px', '')))
    except ValueError:
        log.error('error parsing px', exc_info=True)
    return v


def jsonize(d):
    return ';'.join(map(lambda k, v: k + ':' + v + '', d.keys(), d.values()))


class EventManager(object):
    """Manages the event propagation to the listeners functions"""

    def __init__(self):
        self.listeners = {}

    def propagate(self, eventname, params):
        # if for an event there is a listener, it calls the listener passing the parameters
        if eventname not in self.listeners:
            return
        listener = self.listeners[eventname]
        return getattr(listener['instance'], listener['funcname'])(*params)

    def register_listener(self, eventname, instance, funcname):
        """register a listener for a specific event

        Parameters
        ----------
        eventname : str
            The event identifier, like Widget.EVENT_ONCLICK that is 'onclick'.
        instance : Widget or App
            The widget or app instance that will listen for an event.
        funcname : str
            The literal function name, member of *instance* that will be called on event.
        """
        self.listeners[eventname] = {'instance': instance, 'funcname': funcname}


class Tag(object):
    """
    Tag is the base class of the framework. It represents an element that can be added to the GUI,
    but it is not necessarily graphically representable.
    You can use this class for sending javascript code to the clients.
    """
    def __init__(self, **kwargs):
        self.kwargs = kwargs
        # the runtime instances are processed every time a requests arrives, searching for the called method
        # if a class instance is not present in the runtimeInstances, it will
        # we not callable
        runtimeInstances[str(id(self))] = self

        self._render_children_list = []

        self.children = VersionedDictionary()
        self.attributes = VersionedDictionary()  # properties as class id style

        self.type = kwargs.get('_type', '')
        self.attributes['id'] = str(id(self))

        cls = kwargs.get('_class', self.__class__.__name__)
        if cls:
            self.attributes['class'] = cls
<commit_msg>gui: expose identifier (html id=xx) in public API<commit_after>"""
   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.
"""

import os
import logging
from functools import cmp_to_key
import collections

from .server import runtimeInstances, update_event

log = logging.getLogger('remi.gui')


class VersionedDictionary(dict):
    """This dictionary allows to check if its content is changed.
       It has an attribute __version__ of type int that increments every change
    """
    def __init__(self, *args, **kwargs):
        self.__version__ = 0
        super(VersionedDictionary, self).__init__(*args, **kwargs)

    def __setitem__(self, key, value):
        if key in self:
            if self[key] == value:
                return
        self.__version__ += 1
        return super(VersionedDictionary, self).__setitem__(key, value)

    def __delitem__(self, key):
        if not key in self:
            return
        self.__version__ += 1
        return super(VersionedDictionary, self).__delitem__(key)


def decorate_set_on_listener(event_name, params):
    """ private decorator for use in the editor

    Parameters
    ----------
    event_name : str
        Name of the event to which it refers (es. For set_on_click_listener the event_name is "onclick"
    params : str
        The list of parameters for the listener function (es. "(self, new_value)")
    """

    def add_annotation(function):
        function._event_listener = {}
        function._event_listener['eventName'] = event_name
        function._event_listener['prototype'] = params
        return function

    return add_annotation


def decorate_constructor_parameter_types(type_list):
    def add_annotation(function):
        function._constructor_types = type_list
        return function

    return add_annotation


def to_pix(x):
    return str(x) + 'px'


def from_pix(x):
    v = 0
    try:
        v = int(float(x.replace('px', '')))
    except ValueError:
        log.error('error parsing px', exc_info=True)
    return v


def jsonize(d):
    return ';'.join(map(lambda k, v: k + ':' + v + '', d.keys(), d.values()))


class EventManager(object):
    """Manages the event propagation to the listeners functions"""

    def __init__(self):
        self.listeners = {}

    def propagate(self, eventname, params):
        # if for an event there is a listener, it calls the listener passing the parameters
        if eventname not in self.listeners:
            return
        listener = self.listeners[eventname]
        return getattr(listener['instance'], listener['funcname'])(*params)

    def register_listener(self, eventname, instance, funcname):
        """register a listener for a specific event

        Parameters
        ----------
        eventname : str
            The event identifier, like Widget.EVENT_ONCLICK that is 'onclick'.
        instance : Widget or App
            The widget or app instance that will listen for an event.
        funcname : str
            The literal function name, member of *instance* that will be called on event.
        """
        self.listeners[eventname] = {'instance': instance, 'funcname': funcname}


class Tag(object):
    """
    Tag is the base class of the framework. It represents an element that can be added to the GUI,
    but it is not necessarily graphically representable.
    You can use this class for sending javascript code to the clients.
    """
    def __init__(self, **kwargs):
        self.kwargs = kwargs
        # the runtime instances are processed every time a requests arrives, searching for the called method
        # if a class instance is not present in the runtimeInstances, it will
        # we not callable
        runtimeInstances[str(id(self))] = self

        self._render_children_list = []

        self.children = VersionedDictionary()
        self.attributes = VersionedDictionary()  # properties as class id style

        self.type = kwargs.get('_type', '')
        self.attributes['id'] = str(id(self))

        cls = kwargs.get('_class', self.__class__.__name__)
        if cls:
            self.attributes['class'] = cls

    @property
    def identifier(self):
        return self.attributes['id']

{'fraction_non_alphanumeric': 0.08848889846949774, 'fraction_numerical': 0.0017245095925846087, 'mean_word_length': 2.749090909090909, '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': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '445089', 'n_tokens_mistral': 2468, 'n_tokens_neox': 2416, 'n_words': 916}