<commit_before># This file is part of Indico.
# Copyright (C) 2002 - 2022 CERN
#
# Indico is free software; you can redistribute it and/or
# modify it under the terms of the MIT License; see the
# LICENSE file for more details.

import weakref
from collections.abc import Mapping

from flask import flash, g, has_request_context, request, session
from flask_wtf import FlaskForm
from wtforms import ValidationError
from wtforms.csrf.core import CSRF
from wtforms.fields import FieldList
from wtforms.form import FormMeta
from wtforms.widgets.core import HiddenInput
from wtforms_sqlalchemy.fields import QuerySelectField

from indico.core import signals
from indico.util.i18n import _
from indico.util.signals import values_from_signal
from indico.util.string import strip_whitespace
from indico.web.flask.util import url_for
from indico.web.util import get_request_user

class _DataWrapper:
    """Wrapper for the return value of generated_data properties."""
    def __init__(self, data):
        self.data = data

    def __repr__(self):
        return f'<DataWrapper({self.data!r})>'

class generated_data(property):
    """Property decorator for generated data in forms."""

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        if self.fget is None:
            raise AttributeError('unreadable attribute')
        return _DataWrapper(self.fget(obj))

class IndicoFormMeta(FormMeta):
    def __call__(cls, *args, **kwargs):
        # If we are instantiating a form that was just extended, don't
        # send the signal again - it's pointless to extend the extended
        # form and doing so could actually result in infinite recursion
        # if the signal receiver didn't specify a sender.
        if kwargs.pop('__extended', False):
            return super().__call__(*args, **kwargs)
        extra_fields = values_from_signal(signals.core.add_form_fields.send(cls))
        # If there are no extra fields, we don't need any custom logic
        # and simply create an instance of the original form.
        if not extra_fields:
            return super().__call__(*args, **kwargs)
        kwargs['__extended'] = True
        ext_cls = type('_Extended' + cls.__name__, (cls,), {})
        for name, field in extra_fields:
            name = 'ext__' + name
            if hasattr(ext_cls, name):
                raise RuntimeError(f'Field name collision in {cls.__name__}: {name}')
            setattr(ext_cls, name, field)
        return ext_cls(*args, **kwargs)

class IndicoFormCSRF(CSRF):
    def generate_csrf_token(self, csrf_token_field):
        return session.csrf_token

    def validate_csrf_token(self, form, field):
        if field.current_token == field.data:
            return
        if not g.get('flashed_csrf_message'):
            # Only flash the message once per request. We may end up in here
            # multiple times if `validate()` is called more than once
            flash(_('It looks like there was a problem with your current session. Please submit the form again.'),
                  'error')
            g.flashed_csrf_message = True
        raise ValidationError(_('Invalid CSRF token'))

class IndicoForm(FlaskForm, metaclass=IndicoFormMeta):
    class Meta:
        csrf = True
        csrf_class = IndicoFormCSRF

        def bind_field(self, form, unbound_field, options):
            # We don't set default filters for query-based fields as it breaks them if no query_factory is set
            # while the Form is instantiated. Also, it's quite pointless for those fields...
            # FieldList simply doesn't support filters.
            no_filter_fields = (QuerySelectField, FieldList)
            filters = [strip_whitespace] if not issubclass(unbound_field.field_class, no_filter_fields) else []
            filters += unbound_field.kwargs.get('filters', [])
            bound = unbound_field.bind(form=form, filters=filters, **options)
            bound.get_form = weakref.ref(form)  # GC won't collect the form if we don't use a weakref
            return bound

    def __init__(self, *args, **kwargs):
        csrf_enabled = kwargs.pop('csrf_enabled', None)
        if has_request_context() and get_request_user()[1] in ('oauth', 'signed_url'):
            # no csrf checks needed since oauth/token/signature auth requires a secret that's not available
            # to a malicious site, and even if it was, they wouldn't have to use CSRF to abuse it.
            csrf_enabled = False

        if csrf_enabled is not None:
            # This is exactly what FlaskForm already does, but without
            # a deprecation warning.
            # Being able to set ``csrf_enabled=False`` is much nicer
            # than ``meta={'csrf': False}`` and if we ever need to
            # change it for some reason we can always replace it everywhere
            kwargs['meta'] = kwargs.get('meta') or {}
            kwargs['meta'].setdefault('csrf', csrf_enabled)
        super().__init__(*args, **kwargs)
        self.ajax_response = None

    def process_ajax(self):
        """
        Check if the current request is an AJAX request related to a
        field in this form and execute the field's AJAX logic.

        The response is available in the `ajax_response` attribute
        afterwards.

        :return: Whether an AJAX response was processed.
        """
        field_id = request.args.get('__wtf_ajax')
        if not field_id:
            return False
        field = next((f for f in self._fields.values() if f.id == field_id and isinstance(f, AjaxFieldMixin)), None)
        if not field:
            return False
        rv = field.process_ajax()
        self.ajax_response = rv
        return True

    def validate(self):
        valid = super().validate()
        if not valid:
            return False
        if not all(values_from_signal(signals.core.form_validated.send(self), single_value=True)):
            return False
        self.post_validate()
        return True

    def post_validate(self):
        """Called after the form was successfully validated.

        This method is a good place e.g. to override the data of fields in
        certain cases without going through the hassle of generated_data.
        """

    def populate_obj(self, obj, fields=None, skip=None, existing_only=False):
        """Populate the given object with form data.

        If `fields` is set, only fields from that list are populated.
        If `skip` is set, fields in that list are skipped.
        If `existing_only` is True, only attributes that already exist on `obj` are populated.

        Attributes starting with ``ext__`` are always skipped as they
        are from plugin-defined fields which should always be handled
        separately.
        """
        def _included(field_name):
            if fields and field_name not in fields:
                return False
            if skip and field_name in skip:
                return False
            if existing_only and not hasattr(obj, field_name):
                return False
            if field_name.startswith('ext__'):
                return False
            return True

        # Populate data from actual fields
        for name, field in self._fields.items():
            if not _included(name):
                continue
            field.populate_obj(obj, name)

        # Populate generated data
        for name, value in self.generated_data.items():
            if not _included(name):
                continue
            setattr(obj, name, value)

    @property
    def visible_fields(self):
        """A list containing all fields that are not hidden."""
        return [field for field in self if not isinstance(field.widget, HiddenInput)]

    @property
    def error_list(self):
        """A list containing all errors, prefixed with the field's label.'"""
        all_errors = []
        for field_name, errors in self.errors.items():
            for error in errors:
                if isinstance(error, dict) and isinstance(self[field_name], FieldList):
                    for field in self[field_name].entries:
                        all_errors += [f'{self[field_name].label.text}: {sub_error}'
                                       for sub_error in field.form.error_list]
                else:
                    all_errors.append(f'{self[field_name].label.text}: {error}')
        return all_errors

    @property
    def generated_data(self):
        """Return a dict containing all generated data."""
        cls = type(self)
        return {field: getattr(self, field).data
                for field in dir(cls)
                if isinstance(getattr(cls, field), generated_data)}

    @property
    def data(self):
        """Extend form.data with generated data from properties."""
        data = {k: v
                for k, v in super(IndicoForm, self).data.items()
                if k != self.meta.csrf_field_name and not k.startswith('ext__')}
        data.update(self.generated_data)
        return data

class FormDefaults:
    """Simple wrapper to be used for Form(obj=...) default values.

    It allows you to specify default values via kwargs or certain attrs from an object.
    You can also set attributes directly on this object, which will act just like kwargs

    :param obj: The object to get data from
    :param attrs: Set of attributes that may be taken from obj
    :param skip_attrs: Set of attributes which are never taken from obj
    :param defaults: Additional values which are used only if not taken from obj
    """

    def __init__(self, obj=None, attrs=None, skip_attrs=None, **defaults):
        self.__obj = obj
        self.__use_items = isinstance(obj, Mapping)
        self.__obj_attrs = attrs
        self.__obj_attrs_skip = skip_attrs
        self.__defaults = defaults

    def __valid_attr(self, name):
        """Check if an attr may be retrieved from the object."""
        if self.__obj is None:
            return False
        if self.__obj_attrs is not None and name not in self.__obj_attrs:
            return False
        if self.__obj_attrs_skip is not None and name in self.__obj_attrs_skip:
            return False
        return True

    def __setitem__(self, key, value):
        self.__defaults[key] = value

    def __setattr__(self, key, value):
        if key.startswith(f'_{type(self).__name__}__'):
            object.__setattr__(self, key, value)
        else:
            self.__defaults[key] = value

    def __getattr__(self, item):
        if self.__valid_attr(item):
            if self.__use_items:
                return self.__obj.get(item, self.__defaults.get(item))
            else:
                return getattr(self.__obj, item, self.__defaults.get(item))
        elif item in self.__defaults:
            return self.__defaults[item]
        else:
            raise AttributeError(item)

    def __contains__(self, item):
        return hasattr(self, item)

class AjaxFieldMixin:
    """Mixin for a Field to be able to handle AJAX requests.

    This mixin will allow you to handle AJAX requests during regular
    form processing, e.g. when you have a field that needs an AJAX
    callback to perform search operations.

    To use this mixin, the controllers processing the form must
    include the following code::

        if form.process_ajax():
            return form.ajax_response

    It is a good idea to run this code as early as possible to avoid
    doing expensive operations like loading a big list of objects
    which may be never used when returning early due to the AJAX
    request.
    """

    def process_ajax(self):
        raise NotImplementedError

    def get_ajax_url(self, **url_args):
        kwargs = request.view_args | request.args.to_dict(False)
        kwargs.update(url_args)
        kwargs['__wtf_ajax'] = self.id
        return url_for(request.endpoint, **kwargs)
<commit_msg>Remove obsolete wtform ajax integration<commit_after># This file is part of Indico.
# Copyright (C) 2002 - 2022 CERN
#
# Indico is free software; you can redistribute it and/or
# modify it under the terms of the MIT License; see the
# LICENSE file for more details.

import weakref
from collections.abc import Mapping

from flask import flash, g, has_request_context, session
from flask_wtf import FlaskForm
from wtforms import ValidationError
from wtforms.csrf.core import CSRF
from wtforms.fields import FieldList
from wtforms.form import FormMeta
from wtforms.widgets.core import HiddenInput
from wtforms_sqlalchemy.fields import QuerySelectField

from indico.core import signals
from indico.util.i18n import _
from indico.util.signals import values_from_signal
from indico.util.string import strip_whitespace
from indico.web.util import get_request_user

class _DataWrapper:
    """Wrapper for the return value of generated_data properties."""
    def __init__(self, data):
        self.data = data

    def __repr__(self):
        return f'<DataWrapper({self.data!r})>'

class generated_data(property):
    """Property decorator for generated data in forms."""

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        if self.fget is None:
            raise AttributeError('unreadable attribute')
        return _DataWrapper(self.fget(obj))

class IndicoFormMeta(FormMeta):
    def __call__(cls, *args, **kwargs):
        # If we are instantiating a form that was just extended, don't
        # send the signal again - it's pointless to extend the extended
        # form and doing so could actually result in infinite recursion
        # if the signal receiver didn't specify a sender.
        if kwargs.pop('__extended', False):
            return super().__call__(*args, **kwargs)
        extra_fields = values_from_signal(signals.core.add_form_fields.send(cls))
        # If there are no extra fields, we don't need any custom logic
        # and simply create an instance of the original form.
        if not extra_fields:
            return super().__call__(*args, **kwargs)
        kwargs['__extended'] = True
        ext_cls = type('_Extended' + cls.__name__, (cls,), {})
        for name, field in extra_fields:
            name = 'ext__' + name
            if hasattr(ext_cls, name):
                raise RuntimeError(f'Field name collision in {cls.__name__}: {name}')
            setattr(ext_cls, name, field)
        return ext_cls(*args, **kwargs)

class IndicoFormCSRF(CSRF):
    def generate_csrf_token(self, csrf_token_field):
        return session.csrf_token

    def validate_csrf_token(self, form, field):
        if field.current_token == field.data:
            return
        if not g.get('flashed_csrf_message'):
            # Only flash the message once per request. We may end up in here
            # multiple times if `validate()` is called more than once
            flash(_('It looks like there was a problem with your current session. Please submit the form again.'),
                  'error')
            g.flashed_csrf_message = True
        raise ValidationError(_('Invalid CSRF token'))

class IndicoForm(FlaskForm, metaclass=IndicoFormMeta):
    class Meta:
        csrf = True
        csrf_class = IndicoFormCSRF

        def bind_field(self, form, unbound_field, options):
            # We don't set default filters for query-based fields as it breaks them if no query_factory is set
            # while the Form is instantiated. Also, it's quite pointless for those fields...
            # FieldList simply doesn't support filters.
            no_filter_fields = (QuerySelectField, FieldList)
            filters = [strip_whitespace] if not issubclass(unbound_field.field_class, no_filter_fields) else []
            filters += unbound_field.kwargs.get('filters', [])
            bound = unbound_field.bind(form=form, filters=filters, **options)
            bound.get_form = weakref.ref(form)  # GC won't collect the form if we don't use a weakref
            return bound

    def __init__(self, *args, **kwargs):
        csrf_enabled = kwargs.pop('csrf_enabled', None)
        if has_request_context() and get_request_user()[1] in ('oauth', 'signed_url'):
            # no csrf checks needed since oauth/token/signature auth requires a secret that's not available
            # to a malicious site, and even if it was, they wouldn't have to use CSRF to abuse it.
            csrf_enabled = False

        if csrf_enabled is not None:
            # This is exactly what FlaskForm already does, but without
            # a deprecation warning.
            # Being able to set ``csrf_enabled=False`` is much nicer
            # than ``meta={'csrf': False}`` and if we ever need to
            # change it for some reason we can always replace it everywhere
            kwargs['meta'] = kwargs.get('meta') or {}
            kwargs['meta'].setdefault('csrf', csrf_enabled)
        super().__init__(*args, **kwargs)

    def validate(self):
        valid = super().validate()
        if not valid:
            return False
        if not all(values_from_signal(signals.core.form_validated.send(self), single_value=True)):
            return False
        self.post_validate()
        return True

    def post_validate(self):
        """Called after the form was successfully validated.

        This method is a good place e.g. to override the data of fields in
        certain cases without going through the hassle of generated_data.
        """

    def populate_obj(self, obj, fields=None, skip=None, existing_only=False):
        """Populate the given object with form data.

        If `fields` is set, only fields from that list are populated.
        If `skip` is set, fields in that list are skipped.
        If `existing_only` is True, only attributes that already exist on `obj` are populated.

        Attributes starting with ``ext__`` are always skipped as they
        are from plugin-defined fields which should always be handled
        separately.
        """
        def _included(field_name):
            if fields and field_name not in fields:
                return False
            if skip and field_name in skip:
                return False
            if existing_only and not hasattr(obj, field_name):
                return False
            if field_name.startswith('ext__'):
                return False
            return True

        # Populate data from actual fields
        for name, field in self._fields.items():
            if not _included(name):
                continue
            field.populate_obj(obj, name)

        # Populate generated data
        for name, value in self.generated_data.items():
            if not _included(name):
                continue
            setattr(obj, name, value)

    @property
    def visible_fields(self):
        """A list containing all fields that are not hidden."""
        return [field for field in self if not isinstance(field.widget, HiddenInput)]

    @property
    def error_list(self):
        """A list containing all errors, prefixed with the field's label.'"""
        all_errors = []
        for field_name, errors in self.errors.items():
            for error in errors:
                if isinstance(error, dict) and isinstance(self[field_name], FieldList):
                    for field in self[field_name].entries:
                        all_errors += [f'{self[field_name].label.text}: {sub_error}'
                                       for sub_error in field.form.error_list]
                else:
                    all_errors.append(f'{self[field_name].label.text}: {error}')
        return all_errors

    @property
    def generated_data(self):
        """Return a dict containing all generated data."""
        cls = type(self)
        return {field: getattr(self, field).data
                for field in dir(cls)
                if isinstance(getattr(cls, field), generated_data)}

    @property
    def data(self):
        """Extend form.data with generated data from properties."""
        data = {k: v
                for k, v in super(IndicoForm, self).data.items()
                if k != self.meta.csrf_field_name and not k.startswith('ext__')}
        data.update(self.generated_data)
        return data

class FormDefaults:
    """Simple wrapper to be used for Form(obj=...) default values.

    It allows you to specify default values via kwargs or certain attrs from an object.
    You can also set attributes directly on this object, which will act just like kwargs

    :param obj: The object to get data from
    :param attrs: Set of attributes that may be taken from obj
    :param skip_attrs: Set of attributes which are never taken from obj
    :param defaults: Additional values which are used only if not taken from obj
    """

    def __init__(self, obj=None, attrs=None, skip_attrs=None, **defaults):
        self.__obj = obj
        self.__use_items = isinstance(obj, Mapping)
        self.__obj_attrs = attrs
        self.__obj_attrs_skip = skip_attrs
        self.__defaults = defaults

    def __valid_attr(self, name):
        """Check if an attr may be retrieved from the object."""
        if self.__obj is None:
            return False
        if self.__obj_attrs is not None and name not in self.__obj_attrs:
            return False
        if self.__obj_attrs_skip is not None and name in self.__obj_attrs_skip:
            return False
        return True

    def __setitem__(self, key, value):
        self.__defaults[key] = value

    def __setattr__(self, key, value):
        if key.startswith(f'_{type(self).__name__}__'):
            object.__setattr__(self, key, value)
        else:
            self.__defaults[key] = value

    def __getattr__(self, item):
        if self.__valid_attr(item):
            if self.__use_items:
                return self.__obj.get(item, self.__defaults.get(item))
            else:
                return getattr(self.__obj, item, self.__defaults.get(item))
        elif item in self.__defaults:
            return self.__defaults[item]
        else:
            raise AttributeError(item)

    def __contains__(self, item):
        return hasattr(self, item)
<|endoftext|>


<commit_before>import random
from numpy import product
from Config import domain

class CustomAddress():
    def __init__(self):
        self.vowels = 'aeiou'
        self.consonants = 'bcdfgjklmnprstvz' # no hqx for pronouncability
        self.choices = map(lambda x: "".join(x), product(self.consonants, self.vowels))
        self.letterCount = 8
        self.numberCount = 2

    def get(self):
        return "".join(choice(self.choices) for _ in xrange(self.letterCount / 2))[:self.letterCount] + \
                       str(randint(10**(self.numberCount-1), (10**self.numberCount)-1))
<commit_msg>reverting new address<commit_after>import random
from Config import domain

class CustomAddress():
    def get(self):
        letterCount = 8
        numberCount = 2
        vowels = 'aeiou'
        consonants = 'bcdfgjklmnprstvz' # no hqx for pronouncability
        randString = ''

        for i in range(letterCount):
            if len(randString) == 0:
                randString += random.choice(consonants)
            else:
                if randString[-1:] in consonants:
                    randString += random.choice(vowels)
                else:
                    randString += random.choice(consonants)

        randString += str(random.randint(10**(numberCount-1), (10**numberCount)-1))
        randEmail = randString + '@' + domain

        return randEmail
<|endoftext|>


<commit_before># This file is part of Indico.
# Copyright (C) 2002 - 2015 European Organization for Nuclear Research (CERN).
#
# Indico is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# Indico is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Indico; if not, see <http://www.gnu.org/licenses/>.

from flask import request
from flask_wtf import Form
from wtforms.ext.sqlalchemy.fields import QuerySelectField
from wtforms.fields.core import FieldList
from wtforms.widgets.core import HiddenInput

from indico.core.auth import multipass
from indico.util.string import strip_whitespace

class _DataWrapper(object):
    """Wrapper for the return value of generated_data properties"""
    def __init__(self, data):
        self.data = data

    def __repr__(self):
        return '<DataWrapper({!r})>'.format(self.data)

class generated_data(property):
    """property decorator for generated data in forms"""

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        if self.fget is None:
            raise AttributeError("unreadable attribute")
        return _DataWrapper(self.fget(obj))

class IndicoForm(Form):
    class Meta:
        def bind_field(self, form, unbound_field, options):
            # We don't set default filters for query-based fields as it breaks them if no query_factory is set
            # while the Form is instantiated. Also, it's quite pointless for those fields...
            # FieldList simply doesn't support filters.
            no_filter_fields = (QuerySelectField, FieldList)
            filters = [strip_whitespace] if not issubclass(unbound_field.field_class, no_filter_fields) else []
            filters += unbound_field.kwargs.get('filters', [])
            return unbound_field.bind(form=form, filters=filters, **options)

    def populate_obj(self, obj, fields=None, skip=None, existing_only=False):
        """Populates the given object with form data.

        If `fields` is set, only fields from that list are populated.
        If `skip` is set, fields in that list are skipped.
        If `existing_only` is True, only attributes that already exist on `obj` are populated.
        """
        for name, field in self._fields.iteritems():
            if fields and name not in fields:
                continue
            if skip and name in skip:
                continue
            if existing_only and not hasattr(obj, name):
                continue
            field.populate_obj(obj, name)

    @property
    def visible_fields(self):
        """A list containing all fields that are not hidden."""
        return [field for field in self if not isinstance(field.widget, HiddenInput)]

    @property
    def error_list(self):
        """A list containing all errors, prefixed with the field's label.'"""
        all_errors = []
        for field_name, errors in self.errors.iteritems():
            for error in errors:
                if isinstance(error, dict) and isinstance(self[field_name], FieldList):
                    for field in self[field_name].entries:
                        all_errors += ['{}: {}'.format(self[field_name].label.text, sub_error)
                                       for sub_error in field.form.error_list]
                else:
                    all_errors.append('{}: {}'.format(self[field_name].label.text, error))
        return all_errors

    @property
    def data(self):
        """Extends form.data with generated data from properties"""
        data = super(IndicoForm, self).data
        cls = type(self)
        for field in dir(cls):
            if isinstance(getattr(cls, field), generated_data):
                data[field] = getattr(self, field).data
        return data

class FormDefaults(object):
    """Simple wrapper to be used for Form(obj=...) default values.

    It allows you to specify default values via kwargs or certain attrs from an object.
    You can also set attributes directly on this object, which will act just like kwargs

    :param obj: The object to get data from
    :param attrs: Set of attributes that may be taken from obj
    :param skip_attrs: Set of attributes which are never taken from obj
    :param defaults: Additional values which are used only if not taken from obj
    """

    def __init__(self, obj=None, attrs=None, skip_attrs=None, **defaults):
        self.__obj = obj
        self.__use_items = hasattr(obj, 'iteritems') and hasattr(obj, 'get')  # smells like a dict
        self.__obj_attrs = attrs
        self.__obj_attrs_skip = skip_attrs
        self.__defaults = defaults

    def __valid_attr(self, name):
        """Checks if an attr may be retrieved from the object"""
        if self.__obj is None:
            return False
        if self.__obj_attrs is not None and name not in self.__obj_attrs:
            return False
        if self.__obj_attrs_skip is not None and name in self.__obj_attrs_skip:
            return False
        return True

    def __setitem__(self, key, value):
        self.__defaults[key] = value

    def __setattr__(self, key, value):
        if key.startswith('_{}__'.format(type(self).__name__)):
            object.__setattr__(self, key, value)
        else:
            self.__defaults[key] = value

    def __getattr__(self, item):
        if self.__valid_attr(item):
            if self.__use_items:
                return self.__obj.get(item, self.__defaults.get(item))
            else:
                return getattr(self.__obj, item, self.__defaults.get(item))
        elif item in self.__defaults:
            return self.__defaults[item]
        else:
            raise AttributeError(item)

class SyncedInputsMixin(object):
    """Mixin for a form having inputs using the ``SyncedInputWidget``.

    This mixin will process the synced fields, adding them the necessary
    attributes for them to render and work properly.  The fields which
    are synced are defined by ``multipass.synced_fields``.

    :param synced_fields: set -- a subset of ``multipass.synced_fields``
                          which corresponds to the fields currently
                          being synchronized for the user.
    :param synced_values: dict -- a map of all the synced fields (as
                          defined by ``multipass.synced_fields``) and
                          the values they would have if they were synced
                          (regardless of whether it is or not).  Fields
                          not present in this dict do not show the sync
                          button at all.
    """

    def __init__(self, *args, **kwargs):
        synced_fields = kwargs.pop('synced_fields', set())
        synced_values = kwargs.pop('synced_values', {})
        super(SyncedInputsMixin, self).__init__(*args, **kwargs)
        self.syncable_fields = set(synced_values)
        for key in ('first_name', 'last_name'):
            if not synced_values.get(key):
                synced_values.pop(key, None)
                self.syncable_fields.discard(key)
        if self.is_submitted():
            synced_fields = self.synced_fields
        provider = multipass.sync_provider
        provider_name = provider.title if provider is not None else 'unknown identity provider'
        for field in multipass.synced_fields:
            self[field].synced = self[field].short_name in synced_fields
            self[field].synced_value = synced_values.get(field)
            self[field].provider_name = provider_name

    @property
    def synced_fields(self):
        """The fields which are set as synced for the current request."""
        return set(request.form.getlist('synced_fields')) & self.syncable_fields
<commit_msg>Include generated data in IndicoForm.populate_obj<commit_after># This file is part of Indico.
# Copyright (C) 2002 - 2015 European Organization for Nuclear Research (CERN).
#
# Indico is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# Indico is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Indico; if not, see <http://www.gnu.org/licenses/>.

from flask import request
from flask_wtf import Form
from wtforms.ext.sqlalchemy.fields import QuerySelectField
from wtforms.fields.core import FieldList
from wtforms.widgets.core import HiddenInput

from indico.core.auth import multipass
from indico.util.string import strip_whitespace

class _DataWrapper(object):
    """Wrapper for the return value of generated_data properties"""
    def __init__(self, data):
        self.data = data

    def __repr__(self):
        return '<DataWrapper({!r})>'.format(self.data)

class generated_data(property):
    """property decorator for generated data in forms"""

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        if self.fget is None:
            raise AttributeError("unreadable attribute")
        return _DataWrapper(self.fget(obj))

class IndicoForm(Form):
    class Meta:
        def bind_field(self, form, unbound_field, options):
            # We don't set default filters for query-based fields as it breaks them if no query_factory is set
            # while the Form is instantiated. Also, it's quite pointless for those fields...
            # FieldList simply doesn't support filters.
            no_filter_fields = (QuerySelectField, FieldList)
            filters = [strip_whitespace] if not issubclass(unbound_field.field_class, no_filter_fields) else []
            filters += unbound_field.kwargs.get('filters', [])
            return unbound_field.bind(form=form, filters=filters, **options)

    def populate_obj(self, obj, fields=None, skip=None, existing_only=False):
        """Populates the given object with form data.

        If `fields` is set, only fields from that list are populated.
        If `skip` is set, fields in that list are skipped.
        If `existing_only` is True, only attributes that already exist on `obj` are populated.
        """
        def _included(field_name):
            if fields and field_name not in fields:
                return False
            if skip and field_name in skip:
                return False
            if existing_only and not hasattr(obj, field_name):
                return False
            return True

        # Populate data from actual fields
        for name, field in self._fields.iteritems():
            if not _included(name):
                continue
            field.populate_obj(obj, name)

        # Populate generated data
        for name, value in self.generated_data.iteritems():
            if not _included(name):
                continue
            setattr(obj, name, value)

    @property
    def visible_fields(self):
        """A list containing all fields that are not hidden."""
        return [field for field in self if not isinstance(field.widget, HiddenInput)]

    @property
    def error_list(self):
        """A list containing all errors, prefixed with the field's label.'"""
        all_errors = []
        for field_name, errors in self.errors.iteritems():
            for error in errors:
                if isinstance(error, dict) and isinstance(self[field_name], FieldList):
                    for field in self[field_name].entries:
                        all_errors += ['{}: {}'.format(self[field_name].label.text, sub_error)
                                       for sub_error in field.form.error_list]
                else:
                    all_errors.append('{}: {}'.format(self[field_name].label.text, error))
        return all_errors

    @property
    def generated_data(self):
        """Returns a dict containing all generated data"""
        cls = type(self)
        return {field: getattr(self, field).data
                for field in dir(cls)
                if isinstance(getattr(cls, field), generated_data)}

    @property
    def data(self):
        """Extends form.data with generated data from properties"""
        data = super(IndicoForm, self).data
        data.update(self.generated_data)
        return data

class FormDefaults(object):
    """Simple wrapper to be used for Form(obj=...) default values.

    It allows you to specify default values via kwargs or certain attrs from an object.
    You can also set attributes directly on this object, which will act just like kwargs

    :param obj: The object to get data from
    :param attrs: Set of attributes that may be taken from obj
    :param skip_attrs: Set of attributes which are never taken from obj
    :param defaults: Additional values which are used only if not taken from obj
    """

    def __init__(self, obj=None, attrs=None, skip_attrs=None, **defaults):
        self.__obj = obj
        self.__use_items = hasattr(obj, 'iteritems') and hasattr(obj, 'get')  # smells like a dict
        self.__obj_attrs = attrs
        self.__obj_attrs_skip = skip_attrs
        self.__defaults = defaults

    def __valid_attr(self, name):
        """Checks if an attr may be retrieved from the object"""
        if self.__obj is None:
            return False
        if self.__obj_attrs is not None and name not in self.__obj_attrs:
            return False
        if self.__obj_attrs_skip is not None and name in self.__obj_attrs_skip:
            return False
        return True

    def __setitem__(self, key, value):
        self.__defaults[key] = value

    def __setattr__(self, key, value):
        if key.startswith('_{}__'.format(type(self).__name__)):
            object.__setattr__(self, key, value)
        else:
            self.__defaults[key] = value

    def __getattr__(self, item):
        if self.__valid_attr(item):
            if self.__use_items:
                return self.__obj.get(item, self.__defaults.get(item))
            else:
                return getattr(self.__obj, item, self.__defaults.get(item))
        elif item in self.__defaults:
            return self.__defaults[item]
        else:
            raise AttributeError(item)

class SyncedInputsMixin(object):
    """Mixin for a form having inputs using the ``SyncedInputWidget``.

    This mixin will process the synced fields, adding them the necessary
    attributes for them to render and work properly.  The fields which
    are synced are defined by ``multipass.synced_fields``.

    :param synced_fields: set -- a subset of ``multipass.synced_fields``
                          which corresponds to the fields currently
                          being synchronized for the user.
    :param synced_values: dict -- a map of all the synced fields (as
                          defined by ``multipass.synced_fields``) and
                          the values they would have if they were synced
                          (regardless of whether it is or not).  Fields
                          not present in this dict do not show the sync
                          button at all.
    """

    def __init__(self, *args, **kwargs):
        synced_fields = kwargs.pop('synced_fields', set())
        synced_values = kwargs.pop('synced_values', {})
        super(SyncedInputsMixin, self).__init__(*args, **kwargs)
        self.syncable_fields = set(synced_values)
        for key in ('first_name', 'last_name'):
            if not synced_values.get(key):
                synced_values.pop(key, None)
                self.syncable_fields.discard(key)
        if self.is_submitted():
            synced_fields = self.synced_fields
        provider = multipass.sync_provider
        provider_name = provider.title if provider is not None else 'unknown identity provider'
        for field in multipass.synced_fields:
            self[field].synced = self[field].short_name in synced_fields
            self[field].synced_value = synced_values.get(field)
            self[field].provider_name = provider_name

    @property
    def synced_fields(self):
        """The fields which are set as synced for the current request."""
        return set(request.form.getlist('synced_fields')) & self.syncable_fields
<|endoftext|>


<commit_before>#!/usr/bin/env python
#
# Aheui Editor
# Copyright (c) 2014, Joon Kim.
#
# 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.

import sys
import copy
import importlib
ea = importlib.import_module('pyaheui.esotope-aheui')

class AheuiCodeBlock(object):

	def __init__(self, acode):
		acode = copy.deepcopy(acode)
		if isinstance(acode, unicode):
			acode = ea.AheuiCode(acode)
		if not isinstance(acode, ea.AheuiCode):
			acode = ea.AheuiCode(str(acode).encode('utf-8'))
		self.block = self.make_rect_block(acode)

	def make_rect_block(self, acode):
		sizex = acode.sizex
		space = acode.space
		if not space: return acode
		for i in xrange(acode.sizey):
			padl = sizex - len(space[i])
			if padl > 0:
				space[i]+=[()]*padl
		acode.space = space
		return acode

	def flip_h(self, acode):
		space = acode.space
		for line in space:
			line.reverse()
		return acode
	def flip_v(self, acode):
		acode.space.reverse()
		return acode

	def rotate_L(self, acode):
		acode.sizey, acode.sizex = acode.sizex, acode.sizey
		space = acode.space
		acode.space = [list(i) for i in zip(*space)][::-1]
		return acode

	def rotate_R(self, acode):
		acode.sizey, acode.sizex = acode.sizex, acode.sizey
		space = acode.space
		acode.space = [list(i)[::-1] for i in zip(*space)]
		return acode

	def rotate_H(self, acode):
		space = acode.space
		acode.space = [line[::-1] for line in space][::-1]
		return acode

	def get_unicode(self, acode, pad=u'\u3147'):
		l=(lambda a,b,c: unichr(a*588+b*28+c+0xac00))
		return '\n'.join(\
			["".join([l(*char) if char else pad for char in line\
				]) for line in acode.space])

	make_rect_block = classmethod(make_rect_block)
	flip_h = classmethod(flip_h)
	flip_v = classmethod(flip_v)
	rotate_L = classmethod(rotate_L)
	rotate_R = classmethod(rotate_R)
	rotate_H = classmethod(rotate_H)
	get_unicode = classmethod(get_unicode)

def main():
	a=AheuiCodeBlock(u'\uac00\ub7a3s\ns\uafa3\ud7a3')
	print a.block.space
	AheuiCodeBlock.flip_h(a.block)
	print a.block.space
	AheuiCodeBlock.flip_v(a.block)
	print a.block.space
	AheuiCodeBlock.rotate_L(a.block)
	print a.block.space
	AheuiCodeBlock.rotate_R(a.block)
	print a.block.space
	AheuiCodeBlock.rotate_H(a.block)
	print a.block.space
	print AheuiCodeBlock.get_unicode(a.block, u'\u3147')
	print a.block.space

if __name__ == '__main__':
    sys.exit(main())

<commit_msg>add 'remove_margin' function<commit_after>#!/usr/bin/env python
#
# Aheui Editor
# Copyright (c) 2014, Joon Kim.
#
# 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.

import sys
import copy
import importlib
ea = importlib.import_module('pyaheui.esotope-aheui')

class AheuiCodeBlock(object):

	EMPTYAHEUICODE = ea.AheuiCode('')

	def __init__(self, acode):
		acode = copy.deepcopy(acode)
		if isinstance(acode, unicode):
			acode = ea.AheuiCode(acode)
		if not isinstance(acode, ea.AheuiCode):
			acode = ea.AheuiCode(str(acode).encode('utf-8'))
		self.block = self.make_rect_block(acode)

	def make_rect_block(self, acode):
		sizex = acode.sizex
		space = acode.space
		if not space: return acode
		for i in xrange(acode.sizey):
			padl = sizex - len(space[i])
			if padl > 0:
				space[i]+=[()]*padl
		acode.space = space
		return acode

	def flip_h(self, acode):
		space = acode.space
		for line in space:
			line.reverse()
		return acode
	def flip_v(self, acode):
		acode.space.reverse()
		return acode

	def rotate_L(self, acode):
		acode.sizey, acode.sizex = acode.sizex, acode.sizey
		space = acode.space
		acode.space = [list(i) for i in zip(*space)][::-1]
		return acode

	def rotate_R(self, acode):
		acode.sizey, acode.sizex = acode.sizex, acode.sizey
		space = acode.space
		acode.space = [list(i)[::-1] for i in zip(*space)]
		return acode

	def rotate_H(self, acode):
		space = acode.space
		acode.space = [line[::-1] for line in space][::-1]
		return acode

	def get_unicode(self, acode, pad=u'\u3147'):
		l=(lambda a,b,c: unichr(a*588+b*28+c+0xac00))
		return '\n'.join(\
			["".join([l(*char) if char else pad for char in line\
				]) for line in acode.space])

	def remove_margin(self, acode):
		space = acode.space
		if not space: return acode

		sizex = acode.sizex
		sizey = acode.sizey

		def v(l):#return True if it's emptyrow
			for i in l:
				if i: return False
			return True

		is_empty = True
		for i in xrange(acode.sizey):
			if not v(space[i]):
				space = space[i:]
				sizey -= i
				is_empty = False
				break
		if is_empty:
			acode.space = EMPTYAHEUICODE
		while space and v(space[-1]):
			space.pop()
			sizey -= 1

		def h(s,index):#return True if it's emptycloumn
			for l in s:
				if l[index]: return False
			return True

		for i in xrange(acode.sizex):
			if not h(space,i):
				space = [line[i:] for line in space]
				sizex -= i
				is_empty = False
				break
		while space and h(space,-1):
			[line.pop() for line in space]
			sizex -= 1

		acode.space = space
		acode.sizex = sizex
		acode.sizey = sizey
		return acode

	make_rect_block = classmethod(make_rect_block)
	flip_h = classmethod(flip_h)
	flip_v = classmethod(flip_v)
	rotate_L = classmethod(rotate_L)
	rotate_R = classmethod(rotate_R)
	rotate_H = classmethod(rotate_H)
	get_unicode = classmethod(get_unicode)
	remove_margin = classmethod(remove_margin)

def main():
	print 'main'
	a=AheuiCodeBlock(u'\n\ns\uac00\ub7a3sss\nss\uafa3\ud7a3ss\n5')
	print AheuiCodeBlock.get_unicode(a.block, u'\u3147')
	AheuiCodeBlock.flip_h(a.block)
	print AheuiCodeBlock.get_unicode(a.block, u'\u3147')
	AheuiCodeBlock.flip_v(a.block)
	print AheuiCodeBlock.get_unicode(a.block, u'\u3147')
	AheuiCodeBlock.rotate_L(a.block)
	print AheuiCodeBlock.get_unicode(a.block, u'\u3147')
	AheuiCodeBlock.rotate_R(a.block)
	print AheuiCodeBlock.get_unicode(a.block, u'\u3147')
	AheuiCodeBlock.rotate_H(a.block)
	print AheuiCodeBlock.get_unicode(a.block, u'\u3147')
	AheuiCodeBlock.remove_margin(a.block)
	print AheuiCodeBlock.get_unicode(a.block, u'\u3147')

if __name__ == '__main__':
    sys.exit(main())

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
#
# Copyright (C) 2015 Matt Martz <matt@sivel.net>
# Copyright (C) 2015 Rackspace US, Inc.
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

from voluptuous import PREVENT_EXTRA, Any, Required, Schema, Self
from ansible.module_utils.six import string_types
list_string_types = list(string_types)

suboption_schema = Schema(
    {
        Required('description'): Any(list_string_types, *string_types),
        'required': bool,
        'choices': list,
        'aliases': Any(list_string_types),
        'version_added': Any(float, *string_types),
        'default': Any(None, float, int, bool, list, dict, *string_types),
        # Note: Types are strings, not literal bools, such as True or False
        'type': Any(None, "bool"),
        # Recursive suboptions
        'suboptions': Any(None, *list({str_type: Self} for str_type in string_types)),
    },
    extra=PREVENT_EXTRA
)

# This generates list of dicts with keys from string_types and suboption_schema value
# for example in Python 3: {str: suboption_schema}
list_dict_suboption_schema = [{str_type: suboption_schema} for str_type in string_types]

option_schema = Schema(
    {
        Required('description'): Any(list_string_types, *string_types),
        'required': bool,
        'choices': list,
        'aliases': Any(list_string_types),
        'version_added': Any(float, *string_types),
        'default': Any(None, float, int, bool, list, dict, *string_types),
        'suboptions': Any(None, *list_dict_suboption_schema),
        # Note: Types are strings, not literal bools, such as True or False
        'type': Any(None, "bool")
    },
    extra=PREVENT_EXTRA
)

# This generates list of dicts with keys from string_types and option_schema value
# for example in Python 3: {str: option_schema}
list_dict_option_schema = [{str_type: option_schema} for str_type in string_types]

def return_schema(data):

    return_schema_dict = {
        Required('description'): Any(list_string_types, *string_types),
        Required('returned'): Any(*string_types),
        Required('type'): Any('string', 'list', 'boolean', 'dict', 'complex', 'bool', 'float', 'int', 'dictionary', 'str'),
        'version_added': Any(float, *string_types),
        'sample': Any(None, list, dict, int, float, *string_types),
        'example': Any(None, list, dict, int, float, *string_types)
    }
    if isinstance(data, dict):
        if 'type' in data and (data['type'] == 'complex'):
            # This will just check if the schema has a 'contains' value.
            # It won't recursively validate the contents of the 'contains' field
            additional_schema = {
                Required('contains'): Any(dict, list, *string_types)
            }
            return_schema_dict.update(additional_schema)

    return Schema(
        return_schema_dict,
        extra=PREVENT_EXTRA
    )

def deprecation_schema():

    deprecation_schema_dict = {
        # Only list branches that are deprecated or may have docs stubs in
        # Deprecation cycle changed at 2.4 (though not retroactively)
        # 2.3 -> removed_in: "2.5" + n for docs stub
        # 2.4 -> removed_in: "2.8" + n for docs stub
        Required('removed_in'): Any("2.2", "2.3", "2.4", "2.5", "2.8", "2.9", "2.10"),
        Required('why'): Any(*string_types),
        Required('alternative'): Any(*string_types),
        'removed': Any(True),
    }
    return Schema(
        deprecation_schema_dict,
        extra=PREVENT_EXTRA
    )

def doc_schema(module_name):
    deprecated_module = False

    if module_name.startswith('_'):
        module_name = module_name[1:]
        deprecated_module = True
    doc_schema_dict = {
        Required('module'): module_name,
        Required('short_description'): Any(*string_types),
        Required('description'): Any(list_string_types, *string_types),
        Required('version_added'): Any(float, *string_types),
        Required('author'): Any(None, list_string_types, *string_types),
        'notes': Any(None, list_string_types),
        'requirements': list_string_types,
        'todo': Any(None, list_string_types, *string_types),
        'options': Any(None, *list_dict_option_schema),
        'extends_documentation_fragment': Any(list_string_types, *string_types)
    }

    if deprecated_module:
        deprecation_required_scheme = {
            Required('deprecated'): Any(deprecation_schema()),
        }

        doc_schema_dict.update(deprecation_required_scheme)
    return Schema(
        doc_schema_dict,
        extra=PREVENT_EXTRA
    )

def metadata_1_0_schema(deprecated):
    valid_status = Any('stableinterface', 'preview', 'deprecated', 'removed')
    if deprecated:
        valid_status = Any('deprecated')

    return Schema(
        {
            Required('status'): [valid_status],
            Required('metadata_version'): '1.0',
            Required('supported_by'): Any('core', 'community', 'curated')
        }
    )

def metadata_1_1_schema(deprecated):
    valid_status = Any('stableinterface', 'preview', 'deprecated', 'removed')
    if deprecated:
        valid_status = Any('deprecated')

    return Schema(
        {
            Required('status'): [valid_status],
            Required('metadata_version'): '1.1',
            Required('supported_by'): Any('core', 'community', 'certified', 'network')
        }
    )

# Things to add soon
####################
# 1) Recursively validate `type: complex` fields
#    This will improve documentation, though require fair amount of module tidyup

# Possible Future Enhancements
##############################

# 1) Don't allow empty options for choices, aliases, etc
# 2) If type: bool ensure choices isn't set - perhaps use Exclusive
# 3) both version_added should be quoted floats

#  Tool that takes JSON and generates RETURN skeleton (needs to support complex structures)
<commit_msg>removed_in: 2.6 is valid (#40399)<commit_after># -*- coding: utf-8 -*-
#
# Copyright (C) 2015 Matt Martz <matt@sivel.net>
# Copyright (C) 2015 Rackspace US, Inc.
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

from voluptuous import PREVENT_EXTRA, Any, Required, Schema, Self
from ansible.module_utils.six import string_types
list_string_types = list(string_types)

suboption_schema = Schema(
    {
        Required('description'): Any(list_string_types, *string_types),
        'required': bool,
        'choices': list,
        'aliases': Any(list_string_types),
        'version_added': Any(float, *string_types),
        'default': Any(None, float, int, bool, list, dict, *string_types),
        # Note: Types are strings, not literal bools, such as True or False
        'type': Any(None, "bool"),
        # Recursive suboptions
        'suboptions': Any(None, *list({str_type: Self} for str_type in string_types)),
    },
    extra=PREVENT_EXTRA
)

# This generates list of dicts with keys from string_types and suboption_schema value
# for example in Python 3: {str: suboption_schema}
list_dict_suboption_schema = [{str_type: suboption_schema} for str_type in string_types]

option_schema = Schema(
    {
        Required('description'): Any(list_string_types, *string_types),
        'required': bool,
        'choices': list,
        'aliases': Any(list_string_types),
        'version_added': Any(float, *string_types),
        'default': Any(None, float, int, bool, list, dict, *string_types),
        'suboptions': Any(None, *list_dict_suboption_schema),
        # Note: Types are strings, not literal bools, such as True or False
        'type': Any(None, "bool")
    },
    extra=PREVENT_EXTRA
)

# This generates list of dicts with keys from string_types and option_schema value
# for example in Python 3: {str: option_schema}
list_dict_option_schema = [{str_type: option_schema} for str_type in string_types]

def return_schema(data):

    return_schema_dict = {
        Required('description'): Any(list_string_types, *string_types),
        Required('returned'): Any(*string_types),
        Required('type'): Any('string', 'list', 'boolean', 'dict', 'complex', 'bool', 'float', 'int', 'dictionary', 'str'),
        'version_added': Any(float, *string_types),
        'sample': Any(None, list, dict, int, float, *string_types),
        'example': Any(None, list, dict, int, float, *string_types)
    }
    if isinstance(data, dict):
        if 'type' in data and (data['type'] == 'complex'):
            # This will just check if the schema has a 'contains' value.
            # It won't recursively validate the contents of the 'contains' field
            additional_schema = {
                Required('contains'): Any(dict, list, *string_types)
            }
            return_schema_dict.update(additional_schema)

    return Schema(
        return_schema_dict,
        extra=PREVENT_EXTRA
    )

def deprecation_schema():

    deprecation_schema_dict = {
        # Only list branches that are deprecated or may have docs stubs in
        # Deprecation cycle changed at 2.4 (though not retroactively)
        # 2.3 -> removed_in: "2.5" + n for docs stub
        # 2.4 -> removed_in: "2.8" + n for docs stub
        Required('removed_in'): Any("2.2", "2.3", "2.4", "2.5", "2.6", "2.8", "2.9", "2.10"),
        Required('why'): Any(*string_types),
        Required('alternative'): Any(*string_types),
        'removed': Any(True),
    }
    return Schema(
        deprecation_schema_dict,
        extra=PREVENT_EXTRA
    )

def doc_schema(module_name):
    deprecated_module = False

    if module_name.startswith('_'):
        module_name = module_name[1:]
        deprecated_module = True
    doc_schema_dict = {
        Required('module'): module_name,
        Required('short_description'): Any(*string_types),
        Required('description'): Any(list_string_types, *string_types),
        Required('version_added'): Any(float, *string_types),
        Required('author'): Any(None, list_string_types, *string_types),
        'notes': Any(None, list_string_types),
        'requirements': list_string_types,
        'todo': Any(None, list_string_types, *string_types),
        'options': Any(None, *list_dict_option_schema),
        'extends_documentation_fragment': Any(list_string_types, *string_types)
    }

    if deprecated_module:
        deprecation_required_scheme = {
            Required('deprecated'): Any(deprecation_schema()),
        }

        doc_schema_dict.update(deprecation_required_scheme)
    return Schema(
        doc_schema_dict,
        extra=PREVENT_EXTRA
    )

def metadata_1_0_schema(deprecated):
    valid_status = Any('stableinterface', 'preview', 'deprecated', 'removed')
    if deprecated:
        valid_status = Any('deprecated')

    return Schema(
        {
            Required('status'): [valid_status],
            Required('metadata_version'): '1.0',
            Required('supported_by'): Any('core', 'community', 'curated')
        }
    )

def metadata_1_1_schema(deprecated):
    valid_status = Any('stableinterface', 'preview', 'deprecated', 'removed')
    if deprecated:
        valid_status = Any('deprecated')

    return Schema(
        {
            Required('status'): [valid_status],
            Required('metadata_version'): '1.1',
            Required('supported_by'): Any('core', 'community', 'certified', 'network')
        }
    )

# Things to add soon
####################
# 1) Recursively validate `type: complex` fields
#    This will improve documentation, though require fair amount of module tidyup

# Possible Future Enhancements
##############################

# 1) Don't allow empty options for choices, aliases, etc
# 2) If type: bool ensure choices isn't set - perhaps use Exclusive
# 3) both version_added should be quoted floats

#  Tool that takes JSON and generates RETURN skeleton (needs to support complex structures)
<|endoftext|>


<commit_before>from __future__ import absolute_import, print_function, unicode_literals
from builtins import dict, str
from networkx import MultiDiGraph

def im_json_to_graph(im_json):
    """Return networkx graph from Kappy's influence map JSON.

    Parameters
    ----------
    im_json : dict
        A JSON dict which contains an influence map generated by Kappy.

    Returns
    -------
    graph : networkx.MultiDiGraph
        A graph representing the influence map.
    """
    imap_data = im_json['influence map']['map']

    # Initialize the graph
    graph = MultiDiGraph()

    id_node_dict = {}
    # Add each node to the graph
    for node_dict in imap_data['nodes']:
        # There is always just one entry here with the node type e.g. "rule"
        # as key, and all the node data as the value
        node_type, node = list(node_dict.items())[0]
        # Add the node to the graph with its label and type
        attrs = {'fillcolor': '#b7d2ff' if node_type == 'rule' else '#cdffc9',
                 'shape': 'box' if node_type == 'rule' else 'oval',
                 'style': 'filled'}
        graph.add_node(node['label'], node_type=node_type, **attrs)
        # Save the key of the node to refer to it later
        new_key = '%s%s' % (node_type, node['id'])
        id_node_dict[new_key] = node['label']

    def add_edges(link_list, edge_sign):
        attrs = {'sign': edge_sign,
                 'color': 'green' if edge_sign == 1 else 'red',
                 'arrowhead': 'normal' if edge_sign == 1 else 'tee'}
        for link_dict in link_list:
            source = link_dict['source']
            for target_dict in link_dict['target map']:
                target = target_dict['target']
                src_id = '%s%s' % list(source.items())[0]
                tgt_id = '%s%s' % list(target.items())[0]
                graph.add_edge(id_node_dict[src_id], id_node_dict[tgt_id],
                               **attrs)

    # Add all the edges from the positive and negative influences
    add_edges(imap_data['wake-up map'], 1)
    add_edges(imap_data['inhibition map'], -1)

    return graph
<commit_msg>Implement basic contact map graph instantiation<commit_after>from __future__ import absolute_import, print_function, unicode_literals
from builtins import dict, str
from networkx import MultiDiGraph
from pygraphviz import AGraph

def im_json_to_graph(im_json):
    """Return networkx graph from Kappy's influence map JSON.

    Parameters
    ----------
    im_json : dict
        A JSON dict which contains an influence map generated by Kappy.

    Returns
    -------
    graph : networkx.MultiDiGraph
        A graph representing the influence map.
    """
    imap_data = im_json['influence map']['map']

    # Initialize the graph
    graph = MultiDiGraph()

    id_node_dict = {}
    # Add each node to the graph
    for node_dict in imap_data['nodes']:
        # There is always just one entry here with the node type e.g. "rule"
        # as key, and all the node data as the value
        node_type, node = list(node_dict.items())[0]
        # Add the node to the graph with its label and type
        attrs = {'fillcolor': '#b7d2ff' if node_type == 'rule' else '#cdffc9',
                 'shape': 'box' if node_type == 'rule' else 'oval',
                 'style': 'filled'}
        graph.add_node(node['label'], node_type=node_type, **attrs)
        # Save the key of the node to refer to it later
        new_key = '%s%s' % (node_type, node['id'])
        id_node_dict[new_key] = node['label']

    def add_edges(link_list, edge_sign):
        attrs = {'sign': edge_sign,
                 'color': 'green' if edge_sign == 1 else 'red',
                 'arrowhead': 'normal' if edge_sign == 1 else 'tee'}
        for link_dict in link_list:
            source = link_dict['source']
            for target_dict in link_dict['target map']:
                target = target_dict['target']
                src_id = '%s%s' % list(source.items())[0]
                tgt_id = '%s%s' % list(target.items())[0]
                graph.add_edge(id_node_dict[src_id], id_node_dict[tgt_id],
                               **attrs)

    # Add all the edges from the positive and negative influences
    add_edges(imap_data['wake-up map'], 1)
    add_edges(imap_data['inhibition map'], -1)

    return graph

def cm_json_to_graph(im_json):
    """Return pygraphviz Agraph from Kappy's contact map JSON.

    Parameters
    ----------
    im_json : dict
        A JSON dict which contains a contact map generated by Kappy.

    Returns
    -------
    graph : pygraphviz.Agraph
        A graph representing the contact map.
    """
    cmap_data = im_json['contact map']['map']

    # Initialize the graph
    graph = AGraph()

    # We need to build a map of sites to be able to reference them
    # from the port links
    site_map = {}
    # We also collect all the edges here
    edges = []
    for node_idx, node in enumerate(cmap_data):
        for site_idx, site in enumerate(node['node_sites']):
            # We generate a unique ID based on the parent node and the
            # specific site
            site_id = '%s/%s' % (node['node_type'], site['site_name'])
            site_map[(node_idx, site_idx)] = site_id
            # Each port link is an edge from the current site to the
            # specified site
            if not site['site_type'] or not site['site_type'][0] == 'port':
                continue
            for port_link in site['site_type'][1]['port_links']:
                edge = ((node_idx, site_idx), tuple(port_link))
                edges.append(edge)

    for source, target in edges:
        source_name = site_map[source]
        target_name = site_map[target]
        graph.add_edge(source_name, target_name)
    return graph
<|endoftext|>


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

__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"

"""
Verify the func --format=gnuplot option.
"""

import TestSCons_time

test = TestSCons_time.TestSCons_time(match = TestSCons_time.match_re,
                                     diff = TestSCons_time.diff_re)

try:
    import pstats
except ImportError:
    test.skip_test('No pstats module, skipping test.\n')

content = """\
def _main():
    pass
"""

test.profile_data('foo-000-0.prof', 'prof.py', '_main', content)
test.profile_data('foo-000-1.prof', 'prof.py', '_main', content)
test.profile_data('foo-000-2.prof', 'prof.py', '_main', content)

test.profile_data('foo-001-0.prof', 'prof.py', '_main', content)
test.profile_data('foo-001-1.prof', 'prof.py', '_main', content)
test.profile_data('foo-001-2.prof', 'prof.py', '_main', content)

expect_notitle = r"""set key bottom left
plot '-' title "Startup" with lines lt 1, \\
     '-' title "Full build" with lines lt 2, \\
     '-' title "Up-to-date build" with lines lt 3
# Startup
0 0.00[012]
1 0.00[012]
e
# Full build
0 0.00[012]
1 0.00[012]
e
# Up-to-date build
0 0.00[012]
1 0.00[012]
e
"""

expect_title = 'set title "TITLE"\n' + expect_notitle

test.run(arguments = 'func --fmt gnuplot', stdout=expect_notitle)

test.run(arguments = 'func --fmt=gnuplot --title TITLE', stdout=expect_title)

test.run(arguments = 'func --format gnuplot --title TITLE', stdout=expect_title)

test.run(arguments = 'func --format=gnuplot', stdout=expect_notitle)

test.pass_test()

# Local Variables:
# tab-width:4
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=4 shiftwidth=4:
<commit_msg>Fix time-sensitivity (< 0.002 second execution) in output format.<commit_after>#!/usr/bin/env python
#
# __COPYRIGHT__
#
# 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.
#

__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"

"""
Verify the func --format=gnuplot option.
"""

import TestSCons_time

test = TestSCons_time.TestSCons_time(match = TestSCons_time.match_re,
                                     diff = TestSCons_time.diff_re)

try:
    import pstats
except ImportError:
    test.skip_test('No pstats module, skipping test.\n')

content = """\
def _main():
    pass
"""

test.profile_data('foo-000-0.prof', 'prof.py', '_main', content)
test.profile_data('foo-000-1.prof', 'prof.py', '_main', content)
test.profile_data('foo-000-2.prof', 'prof.py', '_main', content)

test.profile_data('foo-001-0.prof', 'prof.py', '_main', content)
test.profile_data('foo-001-1.prof', 'prof.py', '_main', content)
test.profile_data('foo-001-2.prof', 'prof.py', '_main', content)

expect_notitle = r"""set key bottom left
plot '-' title "Startup" with lines lt 1, \\
     '-' title "Full build" with lines lt 2, \\
     '-' title "Up-to-date build" with lines lt 3
# Startup
0 \d.\d\d\d
1 \d.\d\d\d
e
# Full build
0 \d.\d\d\d
1 \d.\d\d\d
e
# Up-to-date build
0 \d.\d\d\d
1 \d.\d\d\d
e
"""

expect_title = 'set title "TITLE"\n' + expect_notitle

test.run(arguments = 'func --fmt gnuplot', stdout=expect_notitle)

test.run(arguments = 'func --fmt=gnuplot --title TITLE', stdout=expect_title)

test.run(arguments = 'func --format gnuplot --title TITLE', stdout=expect_title)

test.run(arguments = 'func --format=gnuplot', stdout=expect_notitle)

test.pass_test()

# Local Variables:
# tab-width:4
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=4 shiftwidth=4:
<|endoftext|>


<commit_before>import discord
import os
from datetime import datetime
from discord.ext import commands

from .utils.dataIO import dataIO
from .utils import checks

try: # check if BeautifulSoup4 is installed
    from bs4 import BeautifulSoup
    soupAvailable = True
except:
    soupAvailable = False

import aiohttp

class hangman:
    def __init__(self, bot):
        self.bot = bot
        self.path = "data/Fox-Cogs/hangman"
        self.file_path = "data/Fox-Cogs/hangman/hangman.json"
        self.the_data = dataIO.load_json(self.file_path)
        self.hangman = ( "","H","HA","HAN","HANG","HANGM","HANGMA","HANGMAN")

        '''self.hangman = (
        """
            _________
            |/
            |
            |
            |
            |
            |
            |___
            """,

        """
           _________
            |/   |
            |
            |
            |
            |
            |
            |___
            H""",

        """
           _________
            |/   |
            |   (_)
            |
            |
            |
            |
            |___
            HA""",

        """
           ________
            |/   |
            |   (_)
            |    |
            |    |
            |
            |
            |___
            HAN""",

        """
           _________
            |/   |
            |   (_)
            |   /|
            |    |
            |
            |
            |___
            HANG""",

        """
           _________
            |/   |
            |   (_)
            |   /|\
            |    |
            |
            |
            |___
            HANGM""",

        """
           ________
            |/   |
            |   (_)
            |   /|\
            |    |
            |   /
            |
            |___
            HANGMA""",

        """
           ________
            |/   |
            |   (_)
            |   /|\
            |    |
            |   / \
            |
            |___
            HANGMAN""")'''

    def save_data(self):
        dataIO.save_json(self.file_path, self.the_data)

    @commands.command(aliases=['h'], pass_context=True)
    async def hangman(self, ctx, guess : str=None):
        """Play a game of hangman against the bot!"""
        if guess is None:
            if self.the_data["running"] == True:
                await self.bot.say("Game of hangman is already running!\nEnter your guess!")
                """await self.bot.send_cmd_help(ctx)"""
            else:
                await self.bot.say("Starting a game of hangman!")
                await self._startgame()
                await self._printgame()

        else:
            await self.bot.say("A game of hangman is now stopping!")
            await self._stopgame()
        """
        #self.the_data["WOAH"]["knarly"] = "Biiiiiitch"
        if "Yeah dude" not in self.the_data:
            self.the_data["Yeah dude"]={}
        self.the_data["Yeah dude"]["knarly"]= {"ur lyin" : True,
                                               "kick-ass" : { "no way!!!" : "Biiiiiitch" },
                                               "created_at" : datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                                               }

        #self.the_data["Yeah dude"]["knarly"] = "ur lyin"
        #self.the_data["Yeah dude"]["knarly"]["kick-ass"]["no way!!!"] = "Biiiiiitch"
        self.save_data()
        """

    async def _startgame(self):
        self.the_data["running"] = True
        self.the_data["hangman"] = 0
        await self.save_data()

        #self._getphrase()
        #self._printgame()

    async def _stopgame(self):
        self.the_data["running"] = False
        await self.save_data()

    async def _getphrase(self):
        '''Get a new phrase for the game'''
        '''url = "https://www.playstationtrophies.org/forum/wheel-of-fortune-2012-/176009-wheel-fortune-answer-list.html"
        async with aiohttp.get(url) as response:
            soupObject = BeautifulSoup(await response.text(), "html.parser")
        try:
            online = soupObject.find(class_='home-stats').find('li').find('strong').get_text()
            await self.bot.say(online + ' players are playing this game at the moment')
        except:
            await self.bot.say("Couldn't load amount of players. No one is playing this game anymore or there's an error.")
        '''
    async def _guessletter(self):
        '''Checks the guess on a letter'''

    async def _printgame(self):
        '''Print the current state of game'''
        #await self.bot.say(self.hangman[the_data["hangman"]])
        #self.the_data["hangman"] += 1
        #await self.save_data()

def check_folders():
    if not os.path.exists("data/Fox-Cogs"):
        print("Creating data/Fox-Cogs folder...")
        os.makedirs("data/Fox-Cogs")

    if not os.path.exists("data/Fox-Cogs/hangman"):
        print("Creating data/Fox-Cogs/hangman folder...")
        os.makedirs("data/Fox-Cogs/hangman")

def check_files():
    if not dataIO.is_valid_json("data/Fox-Cogs/hangman/hangman.json"):
        dataIO.save_json("data/Fox-Cogs/hangman/hangman.json" ,{"running" : False, "hangman" : 0 })

def setup(bot):
    check_folders()
    check_files()
    if soupAvailable:
        bot.add_cog(hangman(bot))
    else:
        raise RuntimeError("You need to run `pip3 install beautifulsoup4`")
        <commit_msg>ERRORS<commit_after>import discord
import os
from datetime import datetime
from discord.ext import commands

from .utils.dataIO import dataIO
from .utils import checks

try: # check if BeautifulSoup4 is installed
    from bs4 import BeautifulSoup
    soupAvailable = True
except:
    soupAvailable = False

import aiohttp

class hangman:
    def __init__(self, bot):
        self.bot = bot
        self.path = "data/Fox-Cogs/hangman"
        self.file_path = "data/Fox-Cogs/hangman/hangman.json"
        self.the_data = dataIO.load_json(self.file_path)
        self.hangman = ( "","H","HA","HAN","HANG","HANGM","HANGMA","HANGMAN")
        raise RuntimeError("init error")
        '''self.hangman = (
        """
            _________
            |/
            |
            |
            |
            |
            |
            |___
            """,

        """
           _________
            |/   |
            |
            |
            |
            |
            |
            |___
            H""",

        """
           _________
            |/   |
            |   (_)
            |
            |
            |
            |
            |___
            HA""",

        """
           ________
            |/   |
            |   (_)
            |    |
            |    |
            |
            |
            |___
            HAN""",

        """
           _________
            |/   |
            |   (_)
            |   /|
            |    |
            |
            |
            |___
            HANG""",

        """
           _________
            |/   |
            |   (_)
            |   /|\
            |    |
            |
            |
            |___
            HANGM""",

        """
           ________
            |/   |
            |   (_)
            |   /|\
            |    |
            |   /
            |
            |___
            HANGMA""",

        """
           ________
            |/   |
            |   (_)
            |   /|\
            |    |
            |   / \
            |
            |___
            HANGMAN""")'''

    def save_data(self):
        dataIO.save_json(self.file_path, self.the_data)

    @commands.command(aliases=['h'], pass_context=True)
    async def hangman(self, ctx, guess : str=None):
        """Play a game of hangman against the bot!"""
        if guess is None:
            if self.the_data["running"] == True:
                await self.bot.say("Game of hangman is already running!\nEnter your guess!")
                """await self.bot.send_cmd_help(ctx)"""
            else:
                raise RuntimeError("starting error")
                await self.bot.say("Starting a game of hangman!")
                await self._startgame()
                await self._printgame()

        else:
            raise RuntimeError("stopping error")
            await self.bot.say("A game of hangman is now stopping!")
            await self._stopgame()
        """
        #self.the_data["WOAH"]["knarly"] = "Biiiiiitch"
        if "Yeah dude" not in self.the_data:
            self.the_data["Yeah dude"]={}
        self.the_data["Yeah dude"]["knarly"]= {"ur lyin" : True,
                                               "kick-ass" : { "no way!!!" : "Biiiiiitch" },
                                               "created_at" : datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                                               }

        #self.the_data["Yeah dude"]["knarly"] = "ur lyin"
        #self.the_data["Yeah dude"]["knarly"]["kick-ass"]["no way!!!"] = "Biiiiiitch"
        self.save_data()
        """

    async def _startgame(self):
        self.the_data["running"] = True
        self.the_data["hangman"] = 0
        await self.save_data()

        #self._getphrase()
        #self._printgame()

    async def _stopgame(self):
        self.the_data["running"] = False
        await self.save_data()

    async def _getphrase(self):
        '''Get a new phrase for the game'''
        '''url = "https://www.playstationtrophies.org/forum/wheel-of-fortune-2012-/176009-wheel-fortune-answer-list.html"
        async with aiohttp.get(url) as response:
            soupObject = BeautifulSoup(await response.text(), "html.parser")
        try:
            online = soupObject.find(class_='home-stats').find('li').find('strong').get_text()
            await self.bot.say(online + ' players are playing this game at the moment')
        except:
            await self.bot.say("Couldn't load amount of players. No one is playing this game anymore or there's an error.")
        '''
    async def _guessletter(self):
        '''Checks the guess on a letter'''

    async def _printgame(self):
        '''Print the current state of game'''
        raise RuntimeError("print error")
        #await self.bot.say(self.hangman[the_data["hangman"]])
        #self.the_data["hangman"] += 1
        #await self.save_data()

def check_folders():
    if not os.path.exists("data/Fox-Cogs"):
        print("Creating data/Fox-Cogs folder...")
        os.makedirs("data/Fox-Cogs")

    if not os.path.exists("data/Fox-Cogs/hangman"):
        print("Creating data/Fox-Cogs/hangman folder...")
        os.makedirs("data/Fox-Cogs/hangman")

def check_files():
    if not dataIO.is_valid_json("data/Fox-Cogs/hangman/hangman.json"):
        dataIO.save_json("data/Fox-Cogs/hangman/hangman.json" ,{"running" : False, "hangman" : 0 })

def setup(bot):
    check_folders()
    check_files()
    if soupAvailable:
        bot.add_cog(hangman(bot))
    else:
        raise RuntimeError("You need to run `pip3 install beautifulsoup4`")
        <|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# Generated by Django 1.11.15 on 2019-04-17 19:51

import os
import uuid
from django.db import migrations, models
from django.conf import settings

class Migration(migrations.Migration):

    dependencies = [("models", "5967_related_resource_map_card_feature_editing")]

    operations = [
        migrations.RunSQL(
            """
            update d_data_types set defaultconfig = jsonb '{"dateFormat":"YYYY-MM-DD"}' where datatype = 'date';
            update nodes n set config = c.config from cards_x_nodes_x_widgets c where n.nodeid = c.nodeid and n.datatype = 'date';
            update nodes set config = config::jsonb - 'label' where datatype = 'date';
            update nodes set config = config::jsonb - 'maxDate' where datatype = 'date';
            update nodes set config = config::jsonb - 'minDate' where datatype = 'date';
            update nodes set config = config::jsonb - 'viewMode' where datatype = 'date';
            update nodes set config = config::jsonb - 'placeholder' where datatype = 'date';
            update nodes set config = config::jsonb - 'defaultValue' where datatype = 'date';
            update widgets set defaultconfig = defaultconfig::jsonb - 'dateFormat' where widgetid = '10000000-0000-0000-0000-000000000004';
            """,
            """
            update d_data_types set defaultconfig = null where datatype = 'date';
            update nodes set config = null where datatype = 'date';
            update widgets set defaultconfig = jsonb_set(defaultconfig, '{dateFormat}', '"YYYY-MM-DD"') where widgetid = '10000000-0000-0000-0000-000000000004';
            """,
        )
    ]
<commit_msg>lints<commit_after># -*- coding: utf-8 -*-
# Generated by Django 1.11.15 on 2019-04-17 19:51

import os
import uuid
from django.db import migrations, models
from django.conf import settings

class Migration(migrations.Migration):

    dependencies = [("models", "5967_related_resource_map_card_feature_editing")]

    operations = [
        migrations.RunSQL(
            """
            update d_data_types set defaultconfig = jsonb '{"dateFormat":"YYYY-MM-DD"}' where datatype = 'date';
            update nodes n set config = c.config from cards_x_nodes_x_widgets c where n.nodeid = c.nodeid and n.datatype = 'date';
            update nodes set config = config::jsonb - 'label' where datatype = 'date';
            update nodes set config = config::jsonb - 'maxDate' where datatype = 'date';
            update nodes set config = config::jsonb - 'minDate' where datatype = 'date';
            update nodes set config = config::jsonb - 'viewMode' where datatype = 'date';
            update nodes set config = config::jsonb - 'placeholder' where datatype = 'date';
            update nodes set config = config::jsonb - 'defaultValue' where datatype = 'date';
            update widgets set defaultconfig = defaultconfig::jsonb - 'dateFormat' where widgetid = '10000000-0000-0000-0000-000000000004';
            """,
            """
            update d_data_types set defaultconfig = null where datatype = 'date';
            update nodes set config = null where datatype = 'date';
            update widgets set defaultconfig = jsonb_set(defaultconfig, '{dateFormat}', '"YYYY-MM-DD"')
            where widgetid = '10000000-0000-0000-0000-000000000004';
            """,
        )
    ]
<|endoftext|>


<commit_before>from project.models import EOI
from reports.exports.excel.base import BaseXLSXExporter

class ProjectDetailsXLSLExporter(BaseXLSXExporter):

    def get_display_name(self):
        return f'{self.queryset.count()} Project(s) Information Report'

    def fill_worksheet(self):
        header_format = self.workbook.add_format({
            'bold': True,
            'text_wrap': True,
            'border': 1,
            'bg_color': '#3195EE',
            'align': 'center',
            'valign': 'vcenter',
            'font_color': '#FFFFFF'
        })

        header = [
            'ID',
            'Project Name',
            'Type',
            'Agency',
            'Location(s)',
            'Posted',
            'Application Deadline',
            'Notification of results',
            'Estimated start date',
            'Estimated end date',
            'Focal Point(s)',
        ]
        worksheet = self.workbook.add_worksheet('Project Details Report')

        current_row = 0

        for column, header_text in enumerate(header):
            worksheet.write(current_row, column, header_text, header_format)
            worksheet.set_column(column, column, len(header_text) + 5)

        current_row += 1

        eoi: EOI
        for eoi in self.queryset:
            location_names = "\n".join(set([
                l.admin_level_1.country_name for l in eoi.locations.all()
            ]))
            focal_points = "\n".join(set([
                f"{fp.fullname} ({fp.email})" for fp in eoi.focal_points.all()
            ]))

            worksheet.write_row(current_row, 0, (
                eoi.pk,
                eoi.title,
                eoi.get_display_type_display(),
                eoi.agency.name,
                location_names,
                eoi.published_timestamp,
                eoi.deadline_date,
                eoi.notif_results_date,
                eoi.start_date,
                eoi.end_date,
                focal_points,
            ))
            current_row += 1
<commit_msg>Add remaining project details #1241<commit_after>from project.models import EOI
from reports.exports.excel.base import BaseXLSXExporter

class ProjectDetailsXLSLExporter(BaseXLSXExporter):

    def get_display_name(self):
        return f'{self.queryset.count()} Project(s) Information Report'

    def fill_worksheet(self):
        header_format = self.workbook.add_format({
            'bold': True,
            'text_wrap': True,
            'border': 1,
            'bg_color': '#3195EE',
            'align': 'center',
            'valign': 'vcenter',
            'font_color': '#FFFFFF'
        })

        header = [
            'ID',
            'Project Name',
            'Type',
            'Agency',
            'Location(s)',
            'Posted',
            'Application Deadline',
            'Notification of results',
            'Estimated start date',
            'Estimated end date',
            'Focal Point(s)',
            'Specialization(s)',
            'Project Background',
            'Expected Results',
            'Other information (optional)',
        ]
        worksheet = self.workbook.add_worksheet('Project Details Report')

        current_row = 0

        for column, header_text in enumerate(header):
            worksheet.write(current_row, column, header_text, header_format)
            worksheet.set_column(column, column, len(header_text) + 5)

        current_row += 1

        eoi: EOI
        for eoi in self.queryset:
            location_names = "\n".join(set([
                f"{l.admin_level_1.name} ({l.admin_level_1.country_name})" for l in eoi.locations.all()
            ]))
            focal_points = "\n".join(set([
                f"{fp.fullname} ({fp.email})" for fp in eoi.focal_points.all()
            ]))
            specializations = "\n".join(set([
                f"{s.name} ({s.category.name})" for s in eoi.specializations.all()
            ]))

            worksheet.write_row(current_row, 0, (
                eoi.pk,
                eoi.title,
                eoi.get_display_type_display(),
                eoi.agency.name,
                location_names,
                eoi.published_timestamp,
                eoi.deadline_date,
                eoi.notif_results_date,
                eoi.start_date,
                eoi.end_date,
                focal_points,
                specializations,
                eoi.description,
                eoi.goal,
                eoi.other_information,
            ))
            current_row += 1
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# pylint: disable=too-many-public-methods

"""
Tests for the flowmap
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals

import unittest

from spreadflow_core.flow import Flowmap
from spreadflow_core.component import PortCollection

class _StaticPortCollection(PortCollection):
    """
    Static test-only port collection.
    """
    def __init__(self, ins=None, outs=None):
        self._ins = ins or []
        self._outs = outs or []

    @property
    def ins(self):
        return self._ins

    @property
    def outs(self):
        # As per the port-collection contract, output ports must be
        # returned in reverse order (default port last).
        return list(reversed(self._outs))

class FlowmapTestCase(unittest.TestCase):
    """
    Tests for the Flowmap class.
    """

    def test_empty(self):
        """
        Empty flowmap compiles to empty list.
        """
        flowmap = Flowmap()
        links = flowmap.compile()
        self.assertEqual(list(links), [])

    def test_one_input_one_output(self):
        """
        One input port can be connected to one output port.
        """
        port_in = lambda item: None
        port_out = object()

        flowmap = Flowmap()
        flowmap.connections.append((port_out, port_in))

        expected_links = set([(port_out, port_in)])

        links = flowmap.compile()
        self.assertEqual(set(links), expected_links)

    def test_one_input_many_output(self):
        """
        One input port can be connected to multiple output ports.
        """
        port_in = lambda item: None
        port_out_1 = object()
        port_out_2 = object()

        flowmap = Flowmap()
        flowmap.connections.append((port_out_1, port_in))
        flowmap.connections.append((port_out_2, port_in))

        expected_links = set([(port_out_1, port_in), (port_out_2, port_in)])

        links = flowmap.compile()
        self.assertEqual(set(links), expected_links)

    def test_port_alias(self):
        """
        Ports may have aliases.
        """
        port_in = lambda item: None
        port_out = object()

        flowmap = Flowmap()
        flowmap.connections.append(("port_out_alias", "port_in_alias"))
        flowmap.aliasmap["port_in_alias"] = port_in
        flowmap.aliasmap["port_out_alias"] = port_out

        expected_links = set([(port_out, port_in)])

        links = flowmap.compile()
        self.assertEqual(set(links), expected_links)

    def test_port_collection(self):
        """
        Default ports are used when adding port collections.
        """

        upstream_out_1 = object()
        upstream_out_2 = object()
        upstream = _StaticPortCollection(outs=[upstream_out_1, upstream_out_2])

        downstream_in_1 = lambda item: None
        downstream_in_2 = lambda item: None
        downstream = _StaticPortCollection(ins=[downstream_in_1, downstream_in_2])

        flowmap = Flowmap()
        flowmap.connections.append((upstream, downstream))

        expected_links = set([(upstream_out_1, downstream_in_1)])

        links = flowmap.compile()
        self.assertEqual(set(links), expected_links)

    def test_input_not_callable(self):
        """
        Input ports must be callable.
        """

        port_in = object()
        port_out = object()

        flowmap = Flowmap()
        flowmap.connections.append((port_out, port_in))

        self.assertRaises(RuntimeError, flowmap.compile)

    def test_output_duplicate(self):
        """
        Input ports must be callable.
        """

        port_in_1 = lambda item: None
        port_in_2 = lambda item: None
        port_out = object()

        flowmap = Flowmap()
        flowmap.connections.append((port_out, port_in_1))
        flowmap.connections.append((port_out, port_in_2))

        self.assertRaises(RuntimeError, flowmap.compile)
<commit_msg>Do not use PortCollection directly, instead use ComponentBase<commit_after># -*- coding: utf-8 -*-
# pylint: disable=too-many-public-methods

"""
Tests for the flowmap
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals

import unittest

from spreadflow_core.flow import Flowmap
from spreadflow_core.component import ComponentBase

class _StaticComponent(ComponentBase):
    """
    Static test-only port collection.
    """
    def __init__(self, ins=None, outs=None):
        self._ins = ins or []
        self._outs = outs or []

    @property
    def ins(self):
        return self._ins

    @property
    def outs(self):
        # As per the port-collection contract, output ports must be
        # returned in reverse order (default port last).
        return list(reversed(self._outs))

class FlowmapTestCase(unittest.TestCase):
    """
    Tests for the Flowmap class.
    """

    def test_empty(self):
        """
        Empty flowmap compiles to empty list.
        """
        flowmap = Flowmap()
        links = flowmap.compile()
        self.assertEqual(list(links), [])

    def test_one_input_one_output(self):
        """
        One input port can be connected to one output port.
        """
        port_in = lambda item: None
        port_out = object()

        flowmap = Flowmap()
        flowmap.connections.append((port_out, port_in))

        expected_links = set([(port_out, port_in)])

        links = flowmap.compile()
        self.assertEqual(set(links), expected_links)

    def test_one_input_many_output(self):
        """
        One input port can be connected to multiple output ports.
        """
        port_in = lambda item: None
        port_out_1 = object()
        port_out_2 = object()

        flowmap = Flowmap()
        flowmap.connections.append((port_out_1, port_in))
        flowmap.connections.append((port_out_2, port_in))

        expected_links = set([(port_out_1, port_in), (port_out_2, port_in)])

        links = flowmap.compile()
        self.assertEqual(set(links), expected_links)

    def test_port_alias(self):
        """
        Ports may have aliases.
        """
        port_in = lambda item: None
        port_out = object()

        flowmap = Flowmap()
        flowmap.connections.append(("port_out_alias", "port_in_alias"))
        flowmap.aliasmap["port_in_alias"] = port_in
        flowmap.aliasmap["port_out_alias"] = port_out

        expected_links = set([(port_out, port_in)])

        links = flowmap.compile()
        self.assertEqual(set(links), expected_links)

    def test_port_collection(self):
        """
        Default ports are used when adding port collections.
        """

        upstream_out_1 = object()
        upstream_out_2 = object()
        upstream = _StaticComponent(outs=[upstream_out_1, upstream_out_2])

        downstream_in_1 = lambda item: None
        downstream_in_2 = lambda item: None
        downstream = _StaticComponent(ins=[downstream_in_1, downstream_in_2])

        flowmap = Flowmap()
        flowmap.connections.append((upstream, downstream))

        expected_links = set([(upstream_out_1, downstream_in_1)])

        links = flowmap.compile()
        self.assertEqual(set(links), expected_links)

    def test_input_not_callable(self):
        """
        Input ports must be callable.
        """

        port_in = object()
        port_out = object()

        flowmap = Flowmap()
        flowmap.connections.append((port_out, port_in))

        self.assertRaises(RuntimeError, flowmap.compile)

    def test_output_duplicate(self):
        """
        Input ports must be callable.
        """

        port_in_1 = lambda item: None
        port_in_2 = lambda item: None
        port_out = object()

        flowmap = Flowmap()
        flowmap.connections.append((port_out, port_in_1))
        flowmap.connections.append((port_out, port_in_2))

        self.assertRaises(RuntimeError, flowmap.compile)
<|endoftext|>