<commit_before>#########
# Copyright (c) 2016 GigaSpaces Technologies Ltd. All rights reserved
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
#  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  * See the License for the specific language governing permissions and
#  * limitations under the License.

from flask import request
from flask_security import current_user

from cloudify._compat import text_type
from cloudify.models_states import VisibilityState
from cloudify.cryptography_utils import encrypt, decrypt

from ... import utils
from .. import rest_decorators, rest_utils
from ..responses_v3 import SecretsListResponse
from manager_rest.security import SecuredResource
from manager_rest.security.authorization import authorize
from manager_rest.storage import models, get_storage_manager
from manager_rest.resource_manager import get_resource_manager
from manager_rest.manager_exceptions import (ConflictError,
                                             ForbiddenError,
                                             IllegalActionError)

class SecretsKey(SecuredResource):
    @authorize('secret_get')
    @rest_decorators.marshal_with(models.Secret)
    def get(self, key):
        """
        Get secret by key
        """
        rest_utils.validate_inputs({'key': key})
        secret = get_storage_manager().get(models.Secret, key)
        secret_dict = secret.to_dict()
        if secret_dict['is_hidden_value'] and not \
                rest_utils.is_hidden_value_permitted(secret):
            # Hide the value of the secret
            secret_dict['value'] = ''
        else:
            # Returns the decrypted value
            secret_dict['value'] = decrypt(secret.value)
        return secret_dict

    @authorize('secret_create')
    @rest_decorators.marshal_with(models.Secret)
    def put(self, key, **kwargs):
        """
        Create a new secret
        """
        request_dict = rest_utils.get_json_and_verify_params({
            'value': {
                'type': text_type,
            },
            'update_if_exists': {
                'optional': True,
            }
        })
        value = request_dict['value']
        update_if_exists = rest_utils.verify_and_convert_bool(
            'update_if_exists',
            request_dict.get('update_if_exists', False),
        )
        rest_utils.validate_inputs({'key': key})

        sm = get_storage_manager()
        timestamp = utils.get_formatted_timestamp()
        try:
            new_secret = models.Secret(
                id=key,
                value=value,
                created_at=timestamp,
                updated_at=timestamp,
            )
            return sm.put(new_secret)
        except ConflictError:
            secret = sm.get(models.Secret, key)
            if secret and update_if_exists:
                secret.value = value
                secret.updated_at = timestamp
                return sm.update(secret, validate_global=True)
            raise

    @authorize('secret_update')
    @rest_decorators.marshal_with(models.Secret)
    def patch(self, key):
        """
        Update an existing secret
        """
        rest_utils.validate_inputs({'key': key})
        if not request.json:
            raise IllegalActionError('Update a secret request must include at '
                                     'least one parameter to update')
        secret = get_storage_manager().get(models.Secret, key)
        self._validate_secret_modification_permitted(secret)
        self._update_is_hidden_value(secret)
        self._update_visibility(secret)
        self._update_value(secret)
        secret.updated_at = utils.get_formatted_timestamp()
        return get_storage_manager().update(secret, validate_global=True)

    @authorize('secret_delete')
    def delete(self, key):
        """
        Delete a secret
        """
        rest_utils.validate_inputs({'key': key})
        storage_manager = get_storage_manager()
        secret = storage_manager.get(models.Secret, key)
        self._validate_secret_modification_permitted(secret)
        storage_manager.delete(secret, validate_global=True)
        return None, 204

    def _validate_secret_modification_permitted(self, secret):
        if secret.is_hidden_value and \
                not rest_utils.is_hidden_value_permitted(secret):
            raise ForbiddenError(
                'User `{0}` is not permitted to modify the hidden value '
                'secret `{1}`'.format(current_user.username, secret.key)
            )

    def _update_is_hidden_value(self, secret):
        is_hidden_value = request.json.get('is_hidden_value')
        if is_hidden_value is None:
            return
        is_hidden_value = rest_utils.verify_and_convert_bool(
            'is_hidden_value',
            is_hidden_value
        )
        # Only the creator of the secret and the admins can change a secret
        # to be hidden value
        if not rest_utils.is_hidden_value_permitted(secret):
            raise ForbiddenError(
                'User `{0}` is not permitted to modify the secret `{1}` '
                'to be hidden value'.format(current_user.username, secret.key)
            )
        secret.is_hidden_value = is_hidden_value

    def _update_visibility(self, secret):
        visibility = rest_utils.get_visibility_parameter(
            optional=True,
            valid_values=VisibilityState.STATES,
        )
        if visibility:
            get_resource_manager().validate_visibility_value(
                models.Secret,
                secret,
                visibility
            )
            secret.visibility = visibility

    def _update_value(self, secret):
        request_dict = rest_utils.get_json_and_verify_params({
            'value': {'type': text_type, 'optional': True}
        })
        value = request_dict.get('value')
        if value:
            secret.value = encrypt(value)

class Secrets(SecuredResource):
    @authorize('secret_list')
    @rest_decorators.marshal_with(SecretsListResponse)
    @rest_decorators.create_filters(models.Secret)
    @rest_decorators.paginate
    @rest_decorators.sortable(models.Secret)
    @rest_decorators.all_tenants
    @rest_decorators.search('id')
    def get(self, _include=None, filters=None, pagination=None, sort=None,
            all_tenants=None, search=None, **kwargs):
        """
        List secrets
        """
        get_all_results = rest_utils.verify_and_convert_bool(
            '_get_all_results',
            request.args.get('_get_all_results', False)
        )
        return get_storage_manager().list(
            models.Secret,
            include=_include,
            filters=filters,
            substr_filters=search,
            pagination=pagination,
            sort=sort,
            all_tenants=all_tenants,
            get_all_results=get_all_results
        )
<commit_msg>RD-3631 cfy deployments set-owner implementation (#3377)<commit_after>#########
# Copyright (c) 2016 GigaSpaces Technologies Ltd. All rights reserved
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
#  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  * See the License for the specific language governing permissions and
#  * limitations under the License.

from flask import request
from flask_security import current_user

from cloudify._compat import text_type
from cloudify.models_states import VisibilityState
from cloudify.cryptography_utils import encrypt, decrypt

from ... import utils
from .. import rest_decorators, rest_utils
from ..responses_v3 import SecretsListResponse
from manager_rest.security import SecuredResource
from manager_rest.security.authorization import authorize
from manager_rest.storage import models, get_storage_manager
from manager_rest.resource_manager import get_resource_manager
from manager_rest.manager_exceptions import (ConflictError,
                                             ForbiddenError,
                                             IllegalActionError)

class SecretsKey(SecuredResource):
    @authorize('secret_get')
    @rest_decorators.marshal_with(models.Secret)
    def get(self, key):
        """
        Get secret by key
        """
        rest_utils.validate_inputs({'key': key})
        secret = get_storage_manager().get(models.Secret, key)
        secret_dict = secret.to_dict()
        if secret_dict['is_hidden_value'] and not \
                rest_utils.is_hidden_value_permitted(secret):
            # Hide the value of the secret
            secret_dict['value'] = ''
        else:
            # Returns the decrypted value
            secret_dict['value'] = decrypt(secret.value)
        return secret_dict

    @authorize('secret_create')
    @rest_decorators.marshal_with(models.Secret)
    def put(self, key, **kwargs):
        """
        Create a new secret
        """
        request_dict = rest_utils.get_json_and_verify_params({
            'value': {
                'type': text_type,
            },
            'update_if_exists': {
                'optional': True,
            }
        })
        value = request_dict['value']
        update_if_exists = rest_utils.verify_and_convert_bool(
            'update_if_exists',
            request_dict.get('update_if_exists', False),
        )
        rest_utils.validate_inputs({'key': key})

        sm = get_storage_manager()
        timestamp = utils.get_formatted_timestamp()
        try:
            new_secret = models.Secret(
                id=key,
                value=value,
                created_at=timestamp,
                updated_at=timestamp,
            )
            return sm.put(new_secret)
        except ConflictError:
            secret = sm.get(models.Secret, key)
            if secret and update_if_exists:
                secret.value = value
                secret.updated_at = timestamp
                return sm.update(secret, validate_global=True)
            raise

    @authorize('secret_update')
    @rest_decorators.marshal_with(models.Secret)
    def patch(self, key):
        """
        Update an existing secret
        """
        rest_utils.validate_inputs({'key': key})
        if not request.json:
            raise IllegalActionError('Update a secret request must include at '
                                     'least one parameter to update')
        secret = get_storage_manager().get(models.Secret, key)
        self._validate_secret_modification_permitted(secret)
        self._update_is_hidden_value(secret)
        self._update_visibility(secret)
        self._update_value(secret)
        self._update_owner(secret)
        secret.updated_at = utils.get_formatted_timestamp()
        return get_storage_manager().update(secret, validate_global=True)

    @authorize('secret_delete')
    def delete(self, key):
        """
        Delete a secret
        """
        rest_utils.validate_inputs({'key': key})
        storage_manager = get_storage_manager()
        secret = storage_manager.get(models.Secret, key)
        self._validate_secret_modification_permitted(secret)
        storage_manager.delete(secret, validate_global=True)
        return None, 204

    def _validate_secret_modification_permitted(self, secret):
        if secret.is_hidden_value and \
                not rest_utils.is_hidden_value_permitted(secret):
            raise ForbiddenError(
                'User `{0}` is not permitted to modify the hidden value '
                'secret `{1}`'.format(current_user.username, secret.key)
            )

    def _update_is_hidden_value(self, secret):
        is_hidden_value = request.json.get('is_hidden_value')
        if is_hidden_value is None:
            return
        is_hidden_value = rest_utils.verify_and_convert_bool(
            'is_hidden_value',
            is_hidden_value
        )
        # Only the creator of the secret and the admins can change a secret
        # to be hidden value
        if not rest_utils.is_hidden_value_permitted(secret):
            raise ForbiddenError(
                'User `{0}` is not permitted to modify the secret `{1}` '
                'to be hidden value'.format(current_user.username, secret.key)
            )
        secret.is_hidden_value = is_hidden_value

    def _update_visibility(self, secret):
        visibility = rest_utils.get_visibility_parameter(
            optional=True,
            valid_values=VisibilityState.STATES,
        )
        if visibility:
            get_resource_manager().validate_visibility_value(
                models.Secret,
                secret,
                visibility
            )
            secret.visibility = visibility

    def _update_value(self, secret):
        request_dict = rest_utils.get_json_and_verify_params({
            'value': {'type': text_type, 'optional': True}
        })
        value = request_dict.get('value')
        if value:
            secret.value = encrypt(value)

    def _update_owner(self, secret):
        request_dict = rest_utils.get_json_and_verify_params({
            'creator': {'type': text_type, 'optional': True}
        })
        creator_username = request_dict.get('creator')
        if not creator_username:
            return
        creator = rest_utils.valid_user(request_dict.get('creator'))
        if creator:
            secret.creator = creator

class Secrets(SecuredResource):
    @authorize('secret_list')
    @rest_decorators.marshal_with(SecretsListResponse)
    @rest_decorators.create_filters(models.Secret)
    @rest_decorators.paginate
    @rest_decorators.sortable(models.Secret)
    @rest_decorators.all_tenants
    @rest_decorators.search('id')
    def get(self, _include=None, filters=None, pagination=None, sort=None,
            all_tenants=None, search=None, **kwargs):
        """
        List secrets
        """
        get_all_results = rest_utils.verify_and_convert_bool(
            '_get_all_results',
            request.args.get('_get_all_results', False)
        )
        return get_storage_manager().list(
            models.Secret,
            include=_include,
            filters=filters,
            substr_filters=search,
            pagination=pagination,
            sort=sort,
            all_tenants=all_tenants,
            get_all_results=get_all_results
        )
<|endoftext|>


<commit_before>from django.conf.urls import patterns, include, url
from django.contrib import admin
from .views import home_view

urlpatterns = patterns(
    url(r'^admin/', include(admin.site.urls)),
    url(r'^$', home_view, name='homepage'),
    url(r'^accounts/', include('registration.backends.default.urls')),
    url(r'^profile/', include('cnh_profile.urls')),
)
<commit_msg>admin<commit_after>from django.conf.urls import patterns, include, url
from django.contrib import admin
from .views import home_view

urlpatterns = patterns(
    '',
    url(r'^admin/', include(admin.site.urls)),
    url(r'^$', home_view, name='homepage'),
    url(r'^accounts/', include('registration.backends.default.urls')),
    url(r'^profile/', include('cnh_profile.urls')),
)
<|endoftext|>


<commit_before>import sublime
import sublime_plugin

from .edit import Edit
from .vim import Vim

try:
    v = v.close()
except (NameError, AttributeError):
    pass

class ActualKeypress(sublime_plugin.TextCommand):
    def run(self, edit, key):
        global v
        if v:
            v.press(key)

class ActualListener(sublime_plugin.EventListener):
    def on_selection_modified(self, view):
        pass # print(view.id())

    def on_close(self, view):
        if view == v.view:
            v.close()

def update(vim):
    mode = vim.mode
    view = vim.view
    if mode in 'iR':
        return

    if mode in 'Vv\x16':
        def select():
            vr, vc = vim.visual
            start = view.text_point(vr - 1, vc - 1)
            end = view.text_point(vim.row - 1, vim.col - 1)
            if mode == 'V':
                # visual line mode
                if start == end:
                    pos = view.line(start)
                    start, end = pos.a, pos.b
                elif start > end:
                    start = view.line(start).b
                    end = view.line(end).a
                else:
                    start = view.line(start).a
                    end = view.line(end).b
            sel = view.sel()
            sel.clear()
            sel.add(sublime.Region(start, end))

        Edit.defer(view, select)
        return
    else:
        def select():
            pos = view.text_point(vim.row-1, vim.col-1)
            sel = view.sel()
            sel.clear()
            sel.add(sublime.Region(pos, pos))

        Edit.defer(view, select)

def plugin_loaded():
    global v

    output = sublime.active_window().new_file()
    output.set_read_only(True)
    output.set_scratch(True)
    output.set_name('Vim Monitor')
    output.settings().set('actual_intercept', True)
    output.settings().set('actual_mode', True)

    view = sublime.active_window().new_file()
    view.set_name('Vim')

    view.settings().set('actual_intercept', True)
    view.settings().set('actual_mode', True)
    v = Vim(view, monitor=output, callback=update)
<commit_msg>implement visual block mode selection<commit_after>import sublime
import sublime_plugin

from .edit import Edit
from .vim import Vim

try:
    v = v.close()
except (NameError, AttributeError):
    pass

class ActualKeypress(sublime_plugin.TextCommand):
    def run(self, edit, key):
        global v
        if v:
            v.press(key)

class ActualListener(sublime_plugin.EventListener):
    def on_selection_modified(self, view):
        pass # print(view.id())

    def on_close(self, view):
        if view == v.view:
            v.close()

def update(vim):
    mode = vim.mode
    view = vim.view
    if mode in 'iR':
        return

    if mode in ('V', 'v', '^V'):
        def select():
            vr, vc = vim.visual
            sel = view.sel()
            sel.clear()

            if mode == '^V':
                # visual block mode
                left = min(vc, vim.col) - 1
                right = max(vc, vim.col) - 1
                top = min(vr, vim.row) - 1
                bot = max(vr, vim.row) - 1

                for i in range(top, bot + 1):
                    line = view.line(view.text_point(i, 0))
                    _, end = view.rowcol(line.b)
                    if left <= end and right <= end:
                        a = view.text_point(i, left)
                        b = view.text_point(i, right)
                        sel.add(sublime.Region(a, b))
                return

            start = view.text_point(vr - 1, vc - 1)
            end = view.text_point(vim.row - 1, vim.col - 1)
            if mode == 'V':
                # visual line mode
                if start == end:
                    pos = view.line(start)
                    start, end = pos.a, pos.b
                elif start > end:
                    start = view.line(start).b
                    end = view.line(end).a
                else:
                    start = view.line(start).a
                    end = view.line(end).b

            sel.add(sublime.Region(start, end))

        Edit.defer(view, select)
        return
    else:
        def select():
            pos = view.text_point(vim.row-1, vim.col-1)
            sel = view.sel()
            sel.clear()
            sel.add(sublime.Region(pos, pos))

        Edit.defer(view, select)

def plugin_loaded():
    global v

    output = sublime.active_window().new_file()
    output.set_read_only(True)
    output.set_scratch(True)
    output.set_name('Vim Monitor')
    output.settings().set('actual_intercept', True)
    output.settings().set('actual_mode', True)

    view = sublime.active_window().new_file()
    view.set_name('Vim')

    view.settings().set('actual_intercept', True)
    view.settings().set('actual_mode', True)
    v = Vim(view, monitor=output, callback=update)
<|endoftext|>


<commit_before># Copyright (C) 2014 Universidad Politecnica de Madrid
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import os
import logging

from django import shortcuts
from django.conf import settings
from django import forms
from django.core.urlresolvers import reverse

from horizon import exceptions
from horizon import forms
from horizon import messages
from openstack_dashboard import api
from openstack_dashboard import fiware_api
from openstack_dashboard.dashboards.idm import forms as idm_forms

LOG = logging.getLogger('idm_logger')
AVATAR_SMALL = settings.MEDIA_ROOT+"/"+"OrganizationAvatar/small/"
AVATAR_MEDIUM = settings.MEDIA_ROOT+"/"+"OrganizationAvatar/medium/"
AVATAR_ORIGINAL = settings.MEDIA_ROOT+"/"+"OrganizationAvatar/original/"

GENERIC_ERROR_MESSAGE = 'An error ocurred. Please try again later.'

class RemoveOrgForm(forms.SelfHandlingForm):
    orgID = forms.CharField(label=("ID"), widget=forms.HiddenInput())
    title = 'Remove from Organization'

    def handle(self, request, data):
        user = request.user.id
        project = data['orgID']
        member_role = fiware_api.keystone.get_member_role(request)
        api.keystone.remove_tenant_user_role(request, project=project,
                                             user=user, role=member_role)
        messages.success(request, ("You removed yourself from the organization successfully."))
        response = shortcuts.redirect('horizon:idm:organizations:detail', data['orgID'])
        return response

class CreateOrganizationForm(forms.SelfHandlingForm):
    name = forms.CharField(label=("Name"), max_length=64, required=True)
    description = forms.CharField(
        label=("Description"),
        widget=forms.widgets.Textarea(attrs={'rows':4, 'cols':40}),
        required=True)

    def clean_name(self):
        """ Validate that the name is not already in use."""
        org_name = self.cleaned_data['name']
        try:
            all_organizations = fiware_api.keystone.project_list(self.request)
            names_in_use = [org.name for org
                             in all_organizations]
            if org_name in names_in_use:
                raise forms.ValidationError(
                    ("An organization with that name already exists."),
                    code='invalid')
            return org_name
        except Exception:
            exceptions.handle(self.request,
                              GENERIC_ERROR_MESSAGE,
                              ignore=True)

    def handle(self, request, data):
        # Create organization
        default_domain = api.keystone.get_default_domain(request)
        try:
            self.object = fiware_api.keystone.project_create(
                request,
                name=data['name'],
                description=data['description'],
                enabled=True,
                domain=default_domain,
                website='')

        except Exception:
            exceptions.handle(request,
                              GENERIC_ERROR_MESSAGE,
                              ignore=True)
            return False

        # Set organization and user id
        organization_id = self.object.id
        user_id = request.user.id

        LOG.debug('Organization %s created', organization_id)

        # Grant purchaser in all default apps
        default_apps = fiware_api.keystone.get_fiware_default_apps(
            self.request)
        purchaser_role = fiware_api.keystone.get_purchaser_role(
            self.request)
        try:
            for app in default_apps:
                fiware_api.keystone.add_role_to_organization(
                    self.request,
                    purchaser_role.id,
                    organization_id,
                    app.id)
                LOG.debug('Granted role %s in app %s', purchaser_role.name, app.name)
        except Exception as e:
            exceptions.handle(self.request,
                redirect=reverse('horizon:idm:organizations:index'))
            return False

        # Find owner role id
        try:
            owner_role = fiware_api.keystone.get_owner_role(self.request)
            if owner_role is None:
                msg = ('Could not find owner role in Keystone')
                LOG.debug(msg)
                raise exceptions.NotFound(msg)
        except Exception as e:
            exceptions.handle(self.request,
                redirect=reverse('horizon:idm:organizations:index'))
            return False
        try:
            api.keystone.add_tenant_user_role(request,
                                              project=organization_id,
                                              user=user_id,
                                              role=owner_role.id)
            LOG.debug('Added user %s and organization %s to role %s',
                user_id, organization_id, owner_role.id)
        except Exception:
            exceptions.handle(
                request,
                ('Failed to add {0} organization to list').format(
                    data['name']))
            return False

        response = shortcuts.redirect('switch_tenants', organization_id)
        return response

class InfoForm(forms.SelfHandlingForm):
    orgID = forms.CharField(label=("ID"), widget=forms.HiddenInput())
    name = forms.CharField(label=("Name"), max_length=64, required=True)
    description = forms.CharField(
        label=("Description"),
        widget=forms.widgets.Textarea(attrs={'rows':4, 'cols':40}),
        required=True)
    website = forms.URLField(label=("Website"), required=False)
    title = 'Information'

    def handle(self, request, data):
        try:
            fiware_api.keystone.project_update(
                request,
                data['orgID'],
                name=data['name'],
                description=data['description'],
                website=data['website'])

            LOG.debug('Organization %s updated', data['orgID'])
            messages.success(request,
                ("Organization updated successfully."))
        except Exception:
            messages.error(request,
                ("An error occurred, try again later."))

        return shortcuts.redirect(
            'horizon:idm:organizations:detail', data['orgID'])

class AvatarForm(forms.SelfHandlingForm, idm_forms.ImageCropMixin):
    orgID = forms.CharField(label=("ID"), widget=forms.HiddenInput())
    image = forms.ImageField(required=False)
    title = 'Avatar Update'

    def handle(self, request, data):
        if request.FILES:
            image = request.FILES['image']
            output_img = self.crop(image)

            small = 25, 25, 'small'
            medium = 36, 36, 'medium'
            original = 100, 100, 'original'
            meta = [original, medium, small]
            for meta in meta:
                size = meta[0], meta[1]
                img_type = meta[2]
                output_img.thumbnail(size)
                img = 'OrganizationAvatar/' + img_type + "/" + self.data['orgID']
                output_img.save(settings.MEDIA_ROOT + "/" + img, 'JPEG')

                if img_type == 'small':
                    fiware_api.keystone.project_update(request, data['orgID'], img_small=img)
                elif img_type == 'medium':
                    fiware_api.keystone.project_update(request, data['orgID'], img_medium=img)
                else:
                    fiware_api.keystone.project_update(request, data['orgID'], img_original=img)

            LOG.debug('Organization {0} image updated'.format(data['orgID']))
            messages.success(request, ("Organization updated successfully."))

        response = shortcuts.redirect('horizon:idm:organizations:detail', data['orgID'])
        return response

class CancelForm(forms.SelfHandlingForm):
    orgID = forms.CharField(label=("ID"), widget=forms.HiddenInput())
    title = 'Cancel'

    def handle(self, request, data, organization):
        if getattr(organization, 'is_cloud_project', False):
            messages.error(request, ("Your cloud organization can't be deleted."))
            response = shortcuts.redirect('horizon:idm:organizations:index')
            return response

        image = getattr(organization, 'img_original', '')
        if "OrganizationAvatar" in image:
            os.remove(AVATAR_SMALL + organization.id)
            os.remove(AVATAR_MEDIUM + organization.id)
            os.remove(AVATAR_ORIGINAL + organization.id)
            LOG.debug('%s deleted', image)

        fiware_api.keystone.project_delete(request, organization)
        LOG.info('Organization %s deleted', organization.id)

        messages.success(request, ("Organization deleted successfully."))
        response = shortcuts.redirect('horizon:idm:organizations:index')
        return response

<commit_msg>use idm account to grant pruchaser in store app<commit_after># Copyright (C) 2014 Universidad Politecnica de Madrid
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import os
import logging

from django import shortcuts
from django.conf import settings
from django import forms
from django.core.urlresolvers import reverse

from horizon import exceptions
from horizon import forms
from horizon import messages
from openstack_dashboard import api
from openstack_dashboard import fiware_api
from openstack_dashboard.dashboards.idm import forms as idm_forms

LOG = logging.getLogger('idm_logger')
AVATAR_SMALL = settings.MEDIA_ROOT+"/"+"OrganizationAvatar/small/"
AVATAR_MEDIUM = settings.MEDIA_ROOT+"/"+"OrganizationAvatar/medium/"
AVATAR_ORIGINAL = settings.MEDIA_ROOT+"/"+"OrganizationAvatar/original/"

GENERIC_ERROR_MESSAGE = 'An error ocurred. Please try again later.'

class RemoveOrgForm(forms.SelfHandlingForm):
    orgID = forms.CharField(label=("ID"), widget=forms.HiddenInput())
    title = 'Remove from Organization'

    def handle(self, request, data):
        user = request.user.id
        project = data['orgID']
        member_role = fiware_api.keystone.get_member_role(request)
        api.keystone.remove_tenant_user_role(request, project=project,
                                             user=user, role=member_role)
        messages.success(request, ("You removed yourself from the organization successfully."))
        response = shortcuts.redirect('horizon:idm:organizations:detail', data['orgID'])
        return response

class CreateOrganizationForm(forms.SelfHandlingForm):
    name = forms.CharField(label=("Name"), max_length=64, required=True)
    description = forms.CharField(
        label=("Description"),
        widget=forms.widgets.Textarea(attrs={'rows':4, 'cols':40}),
        required=True)

    def clean_name(self):
        """ Validate that the name is not already in use."""
        org_name = self.cleaned_data['name']
        try:
            all_organizations = fiware_api.keystone.project_list(self.request)
            names_in_use = [org.name for org
                             in all_organizations]
            if org_name in names_in_use:
                raise forms.ValidationError(
                    ("An organization with that name already exists."),
                    code='invalid')
            return org_name
        except Exception:
            exceptions.handle(self.request,
                              GENERIC_ERROR_MESSAGE,
                              ignore=True)

    def handle(self, request, data):
        # Create organization
        default_domain = api.keystone.get_default_domain(request)
        try:
            self.object = fiware_api.keystone.project_create(
                request,
                name=data['name'],
                description=data['description'],
                enabled=True,
                domain=default_domain,
                website='')

        except Exception:
            exceptions.handle(request,
                              GENERIC_ERROR_MESSAGE,
                              ignore=True)
            return False

        # Set organization and user id
        organization_id = self.object.id
        user_id = request.user.id

        LOG.debug('Organization %s created', organization_id)

        # Grant purchaser in all default apps
        default_apps = fiware_api.keystone.get_fiware_default_apps(
            self.request)
        purchaser_role = fiware_api.keystone.get_purchaser_role(
            self.request)
        try:
            for app in default_apps:
                fiware_api.keystone.add_role_to_organization(
                    self.request,
                    purchaser_role.id,
                    organization_id,
                    app.id,
                    use_idm_account=True)
                LOG.debug('Granted role %s in app %s', purchaser_role.name, app.name)
        except Exception as e:
            exceptions.handle(self.request,
                redirect=reverse('horizon:idm:organizations:index'))
            return False

        # Find owner role id
        try:
            owner_role = fiware_api.keystone.get_owner_role(self.request)
            if owner_role is None:
                msg = ('Could not find owner role in Keystone')
                LOG.debug(msg)
                raise exceptions.NotFound(msg)
        except Exception as e:
            exceptions.handle(self.request,
                redirect=reverse('horizon:idm:organizations:index'))
            return False
        try:
            api.keystone.add_tenant_user_role(request,
                                              project=organization_id,
                                              user=user_id,
                                              role=owner_role.id)
            LOG.debug('Added user %s and organization %s to role %s',
                user_id, organization_id, owner_role.id)
        except Exception:
            exceptions.handle(
                request,
                ('Failed to add {0} organization to list').format(
                    data['name']))
            return False

        response = shortcuts.redirect('switch_tenants', organization_id)
        return response

class InfoForm(forms.SelfHandlingForm):
    orgID = forms.CharField(label=("ID"), widget=forms.HiddenInput())
    name = forms.CharField(label=("Name"), max_length=64, required=True)
    description = forms.CharField(
        label=("Description"),
        widget=forms.widgets.Textarea(attrs={'rows':4, 'cols':40}),
        required=True)
    website = forms.URLField(label=("Website"), required=False)
    title = 'Information'

    def handle(self, request, data):
        try:
            fiware_api.keystone.project_update(
                request,
                data['orgID'],
                name=data['name'],
                description=data['description'],
                website=data['website'])

            LOG.debug('Organization %s updated', data['orgID'])
            messages.success(request,
                ("Organization updated successfully."))
        except Exception:
            messages.error(request,
                ("An error occurred, try again later."))

        return shortcuts.redirect(
            'horizon:idm:organizations:detail', data['orgID'])

class AvatarForm(forms.SelfHandlingForm, idm_forms.ImageCropMixin):
    orgID = forms.CharField(label=("ID"), widget=forms.HiddenInput())
    image = forms.ImageField(required=False)
    title = 'Avatar Update'

    def handle(self, request, data):
        if request.FILES:
            image = request.FILES['image']
            output_img = self.crop(image)

            small = 25, 25, 'small'
            medium = 36, 36, 'medium'
            original = 100, 100, 'original'
            meta = [original, medium, small]
            for meta in meta:
                size = meta[0], meta[1]
                img_type = meta[2]
                output_img.thumbnail(size)
                img = 'OrganizationAvatar/' + img_type + "/" + self.data['orgID']
                output_img.save(settings.MEDIA_ROOT + "/" + img, 'JPEG')

                if img_type == 'small':
                    fiware_api.keystone.project_update(request, data['orgID'], img_small=img)
                elif img_type == 'medium':
                    fiware_api.keystone.project_update(request, data['orgID'], img_medium=img)
                else:
                    fiware_api.keystone.project_update(request, data['orgID'], img_original=img)

            LOG.debug('Organization {0} image updated'.format(data['orgID']))
            messages.success(request, ("Organization updated successfully."))

        response = shortcuts.redirect('horizon:idm:organizations:detail', data['orgID'])
        return response

class CancelForm(forms.SelfHandlingForm):
    orgID = forms.CharField(label=("ID"), widget=forms.HiddenInput())
    title = 'Cancel'

    def handle(self, request, data, organization):
        if getattr(organization, 'is_cloud_project', False):
            messages.error(request, ("Your cloud organization can't be deleted."))
            response = shortcuts.redirect('horizon:idm:organizations:index')
            return response

        image = getattr(organization, 'img_original', '')
        if "OrganizationAvatar" in image:
            os.remove(AVATAR_SMALL + organization.id)
            os.remove(AVATAR_MEDIUM + organization.id)
            os.remove(AVATAR_ORIGINAL + organization.id)
            LOG.debug('%s deleted', image)

        fiware_api.keystone.project_delete(request, organization)
        LOG.info('Organization %s deleted', organization.id)

        messages.success(request, ("Organization deleted successfully."))
        response = shortcuts.redirect('horizon:idm:organizations:index')
        return response

<|endoftext|>


<commit_before># Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# http://www.sphinx-doc.org/en/master/config

# -- Path setup --------------------------------------------------------------

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))

# ReadtheDocs-specific items
autodoc_mock_imports = ['pyworkout']
master_doc = 'index'

# -- Project information -----------------------------------------------------

project = 'pyworkout-toolkit'
copyright = '2019, David Liu'
author = 'David Liu'

# -- General configuration ---------------------------------------------------

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ["sphinx.ext.autodoc"
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']

# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
#
#  html_theme = 'alabaster'

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".

html_static_path = ['_static']

# html_theme = "sphinx_rtd_theme"
# html_theme_path = ["_themes", ]
<commit_msg>fixing path and mocks for readthedocs<commit_after># Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# http://www.sphinx-doc.org/en/master/config

# -- Path setup --------------------------------------------------------------

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath('.'))

# ReadtheDocs-specific items
autodoc_mock_imports = ['numpy','pandas','lxml']
master_doc = 'index'

# -- Project information -----------------------------------------------------

project = 'pyworkout-toolkit'
copyright = '2019, David Liu'
author = 'David Liu'

# -- General configuration ---------------------------------------------------

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ["sphinx.ext.autodoc"
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']

# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
#
#  html_theme = 'alabaster'

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".

html_static_path = ['_static']

# html_theme = "sphinx_rtd_theme"
# html_theme_path = ["_themes", ]
<|endoftext|>


<commit_before>#  Copyright 2008-2011 Nokia Siemens Networks Oyj
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

import wx

class _BoxSizer(wx.BoxSizer):

    def __init__(self):
        wx.BoxSizer.__init__(self, self.direction)

    def add(self, component):
        self.Add(component)

    def add_with_padding(self, component, padding):
        self.Add(component, flag=wx.ALL, border=padding)

    def add_expanding(self, component):
        self.Add(component, 1, wx.EXPAND)

class VerticalSizer(_BoxSizer):
    direction = wx.VERTICAL

class HorizontalSizer(_BoxSizer):
    direction = wx.HORIZONTAL

    def add_to_end(self, component):
        self.Add(component, flag=wx.ALIGN_RIGHT)

<commit_msg>sizers: default value for padding<commit_after>#  Copyright 2008-2011 Nokia Siemens Networks Oyj
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

import wx

class _BoxSizer(wx.BoxSizer):

    def __init__(self):
        wx.BoxSizer.__init__(self, self.direction)

    def add(self, component):
        self.Add(component)

    def add_with_padding(self, component, padding=5):
        self.Add(component, flag=wx.ALL, border=padding)

    def add_expanding(self, component):
        self.Add(component, 1, wx.EXPAND)

class VerticalSizer(_BoxSizer):
    direction = wx.VERTICAL

class HorizontalSizer(_BoxSizer):
    direction = wx.HORIZONTAL

    def add_to_end(self, component):
        self.Add(component, flag=wx.ALIGN_RIGHT)

<|endoftext|>


<commit_before>
import discord

import asyncio
import chess
import chess.pgn
import chess.svg
import chess.uci
import datetime
import re
# import requests
from wand.image import Image

import clients

class chess_match(chess.Board):

	def initialize(self, client, text_channel, white_player, black_player):
		self.bot = client
		self.text_channel = text_channel
		self.white_player = white_player
		self.black_player = black_player
		self.chess_engine = chess.uci.popen_engine("bin/stockfish_9_x64.exe")
		#self.chess_engine = chess.uci.popen_engine("bin/stockfish_9_x64_popcnt.exe")
		self.chess_engine.uci()
		self.match_message = None
		self.match_embed = None
		self.generated_move = asyncio.Event()
		self.best_move = None
		self.ponder = None
		self.task = self.bot.loop.create_task(self.match_task())

	def make_move(self, move):
		try:
			self.push_san(move)
		except ValueError:
			try:
				self.push_uci(move)
			except ValueError:
				return False
		return True

	def valid_move(self, move):
		try:
			self.parse_san(move)
		except ValueError:
			try:
				self.parse_uci(move)
			except ValueError:
				return False
		return True

	async def match_task(self):
		self.match_message = await self.bot.send_embed(self.text_channel, "Loading..")
		await self.update_match_embed()
		while True:
			player = [self.black_player, self.white_player][int(self.turn)]
			if player == self.bot.user:
				await self.match_message.edit(embed = self.match_embed.set_footer(text = "I'm thinking.."))
				self.chess_engine.position(self)
				self.chess_engine.go(movetime = 2000, async_callback = self.process_chess_engine_command)
				await self.generated_move.wait()
				self.generated_move.clear()
				self.push(self.best_move)
				await self.update_match_embed(footer_text = "I moved {}".format(self.best_move))
			else:
				message = await self.bot.wait_for("message", check = lambda msg: msg.author == player and msg.channel == self.text_channel and self.valid_move(msg.content))
				await self.match_message.edit(embed = self.match_embed.set_footer(text = "Processing move.."))
				self.make_move(message.content)
				footer_text = discord.Embed.Empty if self.is_game_over() else "It is {}'s ({}'s) turn to move".format(["black", "white"][int(self.turn)], [self.black_player, self.white_player][int(self.turn)])
				await self.update_match_embed(footer_text = footer_text)
				await self.bot.attempt_delete_message(message)

	async def update_match_embed(self, *, flipped = None, footer_text = discord.Embed.Empty):
		if flipped is None: flipped = not self.turn
		# svg = self._repr_svg_()
		svg = chess.svg.board(self, lastmove = self.peek() if self.move_stack else None, check = self.king(self.turn) if self.is_check() else None, flipped = flipped)
		svg = svg.replace("y=\"390\"", "y=\"395\"")
		with open(clients.data_path + "/temp/chess_board.svg", 'w') as image:
			print(svg, file = image)
		with Image(filename = clients.data_path + "/temp/chess_board.svg") as img:
			img.format = "png"
			img.save(filename = clients.data_path + "/temp/chess_board.png")
		# asyncio.sleep(0.2) # necessary?, wasn't even awaited
		if not self.match_embed:
			self.match_embed = discord.Embed(color = clients.bot_color)
		'''
		with open(clients.data_path + "/temp/chess_board.png", "rb") as image:
			request = requests.post("http://uploads.im/api", files = {"upload": image})
			# import aiohttp
			# data = aiohttp.helpers.FormData()
			# data.add_field("upload", image, filename = "chess_board.png")
			# async with clients.aiohttp_session.post("http://uploads.im/api", data = data) as resp:
				# data = await resp.text()
		try:
			data = request.json()
		except:
			print(request.text)
			return
		if data["status_code"] == 403:
			await self.bot.send_embed(self.text_channel, ":no_entry: Error: {}".format(data["status_txt"]))
			return
		# self.match_embed.set_image(url = self.bot.imgur_client.upload_from_path(clients.data_path + "/temp/chess_board.png")["link"])
		self.match_embed.set_image(url = data["data"]["img_url"])
		'''
		cache_channel = self.bot.get_channel(clients.cache_channel_id)
		image_message = await cache_channel.send(file = discord.File(clients.data_path + "/temp/chess_board.png"))
		self.match_embed.set_image(url = image_message.attachments[0].url)
		self.match_embed.set_footer(text = footer_text)
		chess_pgn = chess.pgn.Game.from_board(self)
		chess_pgn.headers["Site"] = "Discord"
		chess_pgn.headers["Date"] = datetime.datetime.utcnow().strftime("%Y.%m.%d")
		chess_pgn.headers["White"] = self.white_player.mention
		chess_pgn.headers["Black"] = self.black_player.mention
		self.match_embed.description = str(chess_pgn)
		if not self.match_message:
			self.match_message = await self.text_channel.send(embed = self.match_embed)
		else:
			await self.match_message.edit(embed = self.match_embed)

	async def new_match_embed(self, *, flipped = None, footer_text = None):
		if flipped is None: flipped = not self.turn
		if footer_text is None: footer_text = discord.Embed.Empty if self.is_game_over() else "It's {}'s ({}'s) turn to move".format(["black", "white"][int(self.turn)], [self.black_player, self.white_player][int(self.turn)])
		if self.match_message: await self.match_message.delete()
		self.match_message = None
		await self.update_match_embed(flipped = flipped, footer_text = footer_text)

	def process_chess_engine_command(self, command):
		self.best_move, self.ponder = command.result()
		self.bot.loop.call_soon_threadsafe(self.generated_move.set)

<commit_msg>Removed chess module now unnecessary import<commit_after>
import discord

import asyncio
import chess
import chess.pgn
import chess.svg
import chess.uci
import datetime
from wand.image import Image

import clients

class chess_match(chess.Board):

	def initialize(self, client, text_channel, white_player, black_player):
		self.bot = client
		self.text_channel = text_channel
		self.white_player = white_player
		self.black_player = black_player
		self.chess_engine = chess.uci.popen_engine("bin/stockfish_9_x64.exe")
		#self.chess_engine = chess.uci.popen_engine("bin/stockfish_9_x64_popcnt.exe")
		self.chess_engine.uci()
		self.match_message = None
		self.match_embed = None
		self.generated_move = asyncio.Event()
		self.best_move = None
		self.ponder = None
		self.task = self.bot.loop.create_task(self.match_task())

	def make_move(self, move):
		try:
			self.push_san(move)
		except ValueError:
			try:
				self.push_uci(move)
			except ValueError:
				return False
		return True

	def valid_move(self, move):
		try:
			self.parse_san(move)
		except ValueError:
			try:
				self.parse_uci(move)
			except ValueError:
				return False
		return True

	async def match_task(self):
		self.match_message = await self.bot.send_embed(self.text_channel, "Loading..")
		await self.update_match_embed()
		while True:
			player = [self.black_player, self.white_player][int(self.turn)]
			if player == self.bot.user:
				await self.match_message.edit(embed = self.match_embed.set_footer(text = "I'm thinking.."))
				self.chess_engine.position(self)
				self.chess_engine.go(movetime = 2000, async_callback = self.process_chess_engine_command)
				await self.generated_move.wait()
				self.generated_move.clear()
				self.push(self.best_move)
				await self.update_match_embed(footer_text = "I moved {}".format(self.best_move))
			else:
				message = await self.bot.wait_for("message", check = lambda msg: msg.author == player and msg.channel == self.text_channel and self.valid_move(msg.content))
				await self.match_message.edit(embed = self.match_embed.set_footer(text = "Processing move.."))
				self.make_move(message.content)
				footer_text = discord.Embed.Empty if self.is_game_over() else "It is {}'s ({}'s) turn to move".format(["black", "white"][int(self.turn)], [self.black_player, self.white_player][int(self.turn)])
				await self.update_match_embed(footer_text = footer_text)
				await self.bot.attempt_delete_message(message)

	async def update_match_embed(self, *, flipped = None, footer_text = discord.Embed.Empty):
		if flipped is None: flipped = not self.turn
		# svg = self._repr_svg_()
		svg = chess.svg.board(self, lastmove = self.peek() if self.move_stack else None, check = self.king(self.turn) if self.is_check() else None, flipped = flipped)
		svg = svg.replace("y=\"390\"", "y=\"395\"")
		with open(clients.data_path + "/temp/chess_board.svg", 'w') as image:
			print(svg, file = image)
		with Image(filename = clients.data_path + "/temp/chess_board.svg") as img:
			img.format = "png"
			img.save(filename = clients.data_path + "/temp/chess_board.png")
		# asyncio.sleep(0.2) # necessary?, wasn't even awaited
		if not self.match_embed:
			self.match_embed = discord.Embed(color = clients.bot_color)
		# TODO: Upload into embed + delete and re-send to update?
		'''
		self.match_embed.set_image(url = self.bot.imgur_client.upload_from_path(clients.data_path + "/temp/chess_board.png")["link"])
		self.match_embed.set_image(url = data["data"]["img_url"])
		'''
		cache_channel = self.bot.get_channel(clients.cache_channel_id)
		image_message = await cache_channel.send(file = discord.File(clients.data_path + "/temp/chess_board.png"))
		self.match_embed.set_image(url = image_message.attachments[0].url)
		self.match_embed.set_footer(text = footer_text)
		chess_pgn = chess.pgn.Game.from_board(self)
		chess_pgn.headers["Site"] = "Discord"
		chess_pgn.headers["Date"] = datetime.datetime.utcnow().strftime("%Y.%m.%d")
		chess_pgn.headers["White"] = self.white_player.mention
		chess_pgn.headers["Black"] = self.black_player.mention
		self.match_embed.description = str(chess_pgn)
		if not self.match_message:
			self.match_message = await self.text_channel.send(embed = self.match_embed)
		else:
			await self.match_message.edit(embed = self.match_embed)

	async def new_match_embed(self, *, flipped = None, footer_text = None):
		if flipped is None: flipped = not self.turn
		if footer_text is None: footer_text = discord.Embed.Empty if self.is_game_over() else "It's {}'s ({}'s) turn to move".format(["black", "white"][int(self.turn)], [self.black_player, self.white_player][int(self.turn)])
		if self.match_message: await self.match_message.delete()
		self.match_message = None
		await self.update_match_embed(flipped = flipped, footer_text = footer_text)

	def process_chess_engine_command(self, command):
		self.best_move, self.ponder = command.result()
		self.bot.loop.call_soon_threadsafe(self.generated_move.set)

<|endoftext|>


<commit_before>import numpy as np

from pax import plugin, utils

class BasicProperties(plugin.TransformPlugin):
    """Computes basic peak properies such as area and hit time spread ("width")
    """

    def startup(self):
        self.last_top_ch = np.max(np.array(self.config['channels_top']))

    def transform_event(self, event):

        for peak in event.peaks:
            # Compute the area per pmt and saturation count
            peak.n_saturated_per_channel = np.zeros(event.n_channels, dtype=np.int16)
            for s in peak.hits:
                ch = s.channel
                peak.area_per_channel[ch] += s.area
                peak.n_saturated_per_channel[ch] += s.n_saturated

            # Compute the total area and saturation count
            peak.area = np.sum(peak.area_per_channel)
            peak.n_saturated = np.sum(peak.n_saturated_per_channel)

            # Compute top fraction
            peak.area_fraction_top = np.sum(peak.area_per_channel[:self.last_top_ch + 1]) / peak.area

            # Compute timing quantities
            times = [s.center for s in peak.hits]
            peak.hit_time_mean, peak.hit_time_std = utils.weighted_mean_variance(times,
                                                                                [s.area for s in peak.hits])
            peak.hit_time_std **= 0.5  # Convert variance to std

            # Compute mean amplitude / noise
            try:
                peak.mean_amplitude_to_noise = np.average([hit.height / hit.noise_sigma for hit in peak.hits],
                                                          weights=[hit.area for hit in peak.hits])
            except ZeroDivisionError:
                self.log.warning('One of the hits in %s peak %d-%d has 0 noise sigma... strange!'
                                 'This should only happen in extremely rare cases, '
                                 'simulated data or with very strange settings' % (peak.detector,
                                                                                peak.left, peak.right))

        return event

class SumWaveformProperties(plugin.TransformPlugin):
    """Computes properties based on the hits-only sum waveform"""

    def startup(self):
        self.wv_field_len = int(self.config['peak_waveform_length'] / self.config['sample_duration']) + 1
        if not self.wv_field_len % 2:
            raise ValueError('peak_waveform_length must be an even multiple of the sample size')

    def transform_event(self, event):
        dt = event.sample_duration
        field_length = self.wv_field_len
        for peak in event.peaks:
            peak.sum_waveform = np.zeros(field_length, dtype=peak.sum_waveform.dtype)
            peak.sum_waveform_top = np.zeros(field_length, dtype=peak.sum_waveform.dtype)

            # Get the waveform and compute some properties
            w = event.get_sum_waveform(peak.detector).samples[peak.left:peak.right + 1]
            peak.center_time = (peak.left + np.average(np.arange(len(w)), weights=w)) * dt
            cog_idx = int(round(peak.center_time / dt)) - peak.left
            max_idx = np.argmax(w)
            peak.index_of_maximum = peak.left + max_idx
            peak.height = w[max_idx]
            peak.range_20p_area = range_of_fraction_of_area(w, center=cog_idx, fraction=0.2) * dt
            peak.range_50p_area = range_of_fraction_of_area(w, center=cog_idx, fraction=0.5) * dt
            peak.range_90p_area = range_of_fraction_of_area(w, center=cog_idx, fraction=0.9) * dt

            # Store the waveform; for tpc also store the top waveform
            put_w_in_center_of_field(w, peak.sum_waveform, cog_idx)
            if peak.detector == 'tpc':
                put_w_in_center_of_field(event.get_sum_waveform('tpc_top').samples[peak.left:peak.right + 1],
                                         peak.sum_waveform_top, cog_idx)

        return event

def range_of_fraction_of_area(w, center, fraction):
    """Compute range of peaks that includes fraction of area, moving symmetrically outward from center (index in w).
    Returns number of samples included. Fractional part is determined as follows:
     - If we can only move in one direction: the fractional part of the sample which takes us over the desired fraction
     - If we can move in both directions, and one of the samples left or right would be enough to take us over
       the desired fraction: the needed fraction of that sample.
     - ... if both samples left and right are needed to take us over the desired fraction: the highest sample is fully
      included, then the other fractionally.
    This function is a pretty low-level algorithm, so it could probably be numba'd
    """
    total_area = w.sum()
    area_todo = total_area * fraction   # Area to still include

    # Edge case where center sample would already take us over area_todo
    if w[center] > area_todo:
        return area_todo / w[center]

    left = float(center)       # Last sample index left of maximum already included
    right = float(center)      # Last sample index right of maximum already included
    area_todo -= w[center]

    while True:
        if left == 0:
            # Move only righward
            fraction_of_todo = w[right + 1] / area_todo
            if fraction_of_todo > 1:
                right += fraction_of_todo
                break
            right += 1
            area_todo -= w[right]
        elif right == len(w) - 1:
            # Move only leftward
            fraction_of_todo = w[left - 1] / area_todo
            if fraction_of_todo > 1:
                left -= fraction_of_todo
                break
            left -= 1
            area_todo -= w[left]
        else:
            # Move in both directions
            fraction_of_todo = (w[right + 1] + w[left - 1]) / area_todo
            if fraction_of_todo > 1:
                # This time we go over threshold!
                # Is the highest sample enough? Then use just a fraction of that.
                fraction_of_todo = max(w[right + 1], w[left - 1]) / area_todo
                if fraction_of_todo > 1:
                    left -= fraction_of_todo      # doesn't matter if we add to left or right, only difference matters
                    break
                # We need both samples, so add the highest sample whole + a fraction of the lowest one
                left -= 1 + min(w[right+1], w[left - 1])/area_todo
                break
            right += 1
            left -= 1
            area_todo -= w[left] + w[right]

    return right - left + 1

def put_w_in_center_of_field(w, field, center_index):
    """Stores (part of) the array w in a fixed length array field, with center_index in field's center.
    Assumes field has odd length.
    """
    # TODO: Needs tests!
    field_length = len(field)
    if not field_length % 2:
        raise ValueError("put_w_in_center_of_field requires an odd field length (so center is clear)")
    field_center = int(field_length/2) + 1

    left_overhang = center_index - field_center
    if left_overhang > 0:
        # Chop off the left overhang
        w = w[left_overhang:]
        center_index = field_center

    right_overhang = len(w) - field_length + (field_center - center_index)
    if right_overhang > 0:
        # Chop off any remaining right overhang
        w = w[:len(w)-right_overhang]

    start_idx = field_center - center_index
    field[start_idx:start_idx + len(w)] = w

class HitpatternSpread(plugin.TransformPlugin):
    """Computes the weighted root mean square deviation of the top and bottom hitpattern for each peak
    """

    def startup(self):

        # Grab PMT numbers and x, y locations in each array
        self.pmts = {}
        self.locations = {}
        for array in ('top', 'bottom'):
            self.pmts[array] = self.config['channels_%s' % array]
            self.locations[array] = {}
            for dim in ('x', 'y'):
                self.locations[array][dim] = np.array([self.config['pmt_locations'][ch][dim]
                                                       for ch in self.pmts[array]])

    def transform_event(self, event):

        for peak in event.peaks:

            # No point in computing this for veto peaks
            if peak.detector != 'tpc':
                continue

            for array in ('top', 'bottom'):

                hitpattern = peak.area_per_channel[self.pmts[array]]

                if np.all(hitpattern == 0.0):
                    # Empty hitpatterns will give error in np.average
                    continue

                weighted_var = 0
                for dim in ('x', 'y'):
                    _, wv = utils.weighted_mean_variance(self.locations[array][dim],
                                                         weights=hitpattern)
                    weighted_var += wv

                setattr(peak, '%s_hitpattern_spread' % array, np.sqrt(weighted_var))

        return event
<commit_msg>range_XXp_area: bug in fractional sample, numba jit for speed<commit_after>import numpy as np
import numba

from pax import plugin, utils

class BasicProperties(plugin.TransformPlugin):
    """Computes basic peak properies such as area and hit time spread ("width")
    """

    def startup(self):
        self.last_top_ch = np.max(np.array(self.config['channels_top']))

    def transform_event(self, event):

        for peak in event.peaks:
            # Compute the area per pmt and saturation count
            peak.n_saturated_per_channel = np.zeros(event.n_channels, dtype=np.int16)
            for s in peak.hits:
                ch = s.channel
                peak.area_per_channel[ch] += s.area
                peak.n_saturated_per_channel[ch] += s.n_saturated

            # Compute the total area and saturation count
            peak.area = np.sum(peak.area_per_channel)
            peak.n_saturated = np.sum(peak.n_saturated_per_channel)

            # Compute top fraction
            peak.area_fraction_top = np.sum(peak.area_per_channel[:self.last_top_ch + 1]) / peak.area

            # Compute timing quantities
            times = [s.center for s in peak.hits]
            peak.hit_time_mean, peak.hit_time_std = utils.weighted_mean_variance(times,
                                                                                [s.area for s in peak.hits])
            peak.hit_time_std **= 0.5  # Convert variance to std

            # Compute mean amplitude / noise
            try:
                peak.mean_amplitude_to_noise = np.average([hit.height / hit.noise_sigma for hit in peak.hits],
                                                          weights=[hit.area for hit in peak.hits])
            except ZeroDivisionError:
                self.log.warning('One of the hits in %s peak %d-%d has 0 noise sigma... strange!'
                                 'This should only happen in extremely rare cases, '
                                 'simulated data or with very strange settings' % (peak.detector,
                                                                                peak.left, peak.right))

        return event

class SumWaveformProperties(plugin.TransformPlugin):
    """Computes properties based on the hits-only sum waveform"""

    def startup(self):
        self.wv_field_len = int(self.config['peak_waveform_length'] / self.config['sample_duration']) + 1
        if not self.wv_field_len % 2:
            raise ValueError('peak_waveform_length must be an even multiple of the sample size')

    def transform_event(self, event):
        dt = event.sample_duration
        field_length = self.wv_field_len
        for peak in event.peaks:
            peak.sum_waveform = np.zeros(field_length, dtype=peak.sum_waveform.dtype)
            peak.sum_waveform_top = np.zeros(field_length, dtype=peak.sum_waveform.dtype)

            # Get the waveform and compute some properties
            w = event.get_sum_waveform(peak.detector).samples[peak.left:peak.right + 1]
            peak.center_time = (peak.left + np.average(np.arange(len(w)), weights=w)) * dt
            cog_idx = int(round(peak.center_time / dt)) - peak.left
            max_idx = np.argmax(w)
            peak.index_of_maximum = peak.left + max_idx
            peak.height = w[max_idx]
            peak.range_20p_area = range_of_fraction_of_area(w, center=cog_idx, fraction=0.2) * dt
            peak.range_50p_area = range_of_fraction_of_area(w, center=cog_idx, fraction=0.5) * dt
            peak.range_90p_area = range_of_fraction_of_area(w, center=cog_idx, fraction=0.9) * dt

            # Store the waveform; for tpc also store the top waveform
            put_w_in_center_of_field(w, peak.sum_waveform, cog_idx)
            if peak.detector == 'tpc':
                put_w_in_center_of_field(event.get_sum_waveform('tpc_top').samples[peak.left:peak.right + 1],
                                         peak.sum_waveform_top, cog_idx)

        return event

@numba.jit(nopython=True)
def range_of_fraction_of_area(w, center, fraction):
    """Compute range of peaks that includes fraction of area, moving symmetrically outward from center (index in w).
    Returns number of samples included. Fractional part is determined as follows:
     - If we can only move in one direction: the fractional part of the sample which takes us over the desired fraction
     - If we can move in both directions, and one of the samples left or right would be enough to take us over
       the desired fraction: the needed fraction of that sample.
     - ... if both samples left and right are needed to take us over the desired fraction: the highest sample is fully
      included, then the other fractionally.
    This function is a pretty low-level algorithm, so it could probably be numba'd
    """
    total_area = w.sum()
    area_todo = total_area * fraction   # Area to still include

    # Edge case where center sample would already take us over area_todo
    if w[center] > area_todo:
        return area_todo / w[center]

    left = int(center)       # Last sample index left of maximum already included
    right = int(center)      # Last sample index right of maximum already included
    area_todo -= w[center]
    extra_width = 0.0        # Fractional amount of last sample to add.

    while True:
        if left == 0:
            # Move only righward
            fraction_of_todo = w[right + 1] / area_todo
            if fraction_of_todo > 1:
                extra_width = 1 / fraction_of_todo
                break
            right += 1
            area_todo -= w[right]
        elif right == len(w) - 1:
            # Move only leftward
            fraction_of_todo = w[left - 1] / area_todo
            if fraction_of_todo > 1:
                extra_width = 1 / fraction_of_todo
                break
            left -= 1
            area_todo -= w[left]
        else:
            # Move in both directions
            fraction_of_todo = (w[right + 1] + w[left - 1]) / area_todo
            if fraction_of_todo > 1:
                # This time we go over threshold!
                # Is the highest sample enough? Then use just a fraction of that.
                fraction_of_todo = max(w[right + 1], w[left - 1]) / area_todo
                if fraction_of_todo > 1:
                    extra_width = 1 / fraction_of_todo      # doesn't matter if we add to left or right, only difference matters
                    break
                # We need both samples, so add the highest sample whole + a fraction of the lowest one
                extra_width = 1 + min(w[right+1], w[left - 1])/area_todo
                break
            right += 1
            left -= 1
            area_todo -= w[left] + w[right]

    return right - left + 1 + extra_width

def put_w_in_center_of_field(w, field, center_index):
    """Stores (part of) the array w in a fixed length array field, with center_index in field's center.
    Assumes field has odd length.
    """
    # TODO: Needs tests!
    field_length = len(field)
    if not field_length % 2:
        raise ValueError("put_w_in_center_of_field requires an odd field length (so center is clear)")
    field_center = int(field_length/2) + 1

    left_overhang = center_index - field_center
    if left_overhang > 0:
        # Chop off the left overhang
        w = w[left_overhang:]
        center_index = field_center

    right_overhang = len(w) - field_length + (field_center - center_index)
    if right_overhang > 0:
        # Chop off any remaining right overhang
        w = w[:len(w)-right_overhang]

    start_idx = field_center - center_index
    field[start_idx:start_idx + len(w)] = w

class HitpatternSpread(plugin.TransformPlugin):
    """Computes the weighted root mean square deviation of the top and bottom hitpattern for each peak
    """

    def startup(self):

        # Grab PMT numbers and x, y locations in each array
        self.pmts = {}
        self.locations = {}
        for array in ('top', 'bottom'):
            self.pmts[array] = self.config['channels_%s' % array]
            self.locations[array] = {}
            for dim in ('x', 'y'):
                self.locations[array][dim] = np.array([self.config['pmt_locations'][ch][dim]
                                                       for ch in self.pmts[array]])

    def transform_event(self, event):

        for peak in event.peaks:

            # No point in computing this for veto peaks
            if peak.detector != 'tpc':
                continue

            for array in ('top', 'bottom'):

                hitpattern = peak.area_per_channel[self.pmts[array]]

                if np.all(hitpattern == 0.0):
                    # Empty hitpatterns will give error in np.average
                    continue

                weighted_var = 0
                for dim in ('x', 'y'):
                    _, wv = utils.weighted_mean_variance(self.locations[array][dim],
                                                         weights=hitpattern)
                    weighted_var += wv

                setattr(peak, '%s_hitpattern_spread' % array, np.sqrt(weighted_var))

        return event
<|endoftext|>


<commit_before>import os
import uvloop
from aiohttp import web
import aiohttp_session
from kubernetes_asyncio import client, config
import logging
from hailtop.auth import async_get_userinfo
from gear import configure_logging, setup_aiohttp_session

uvloop.install()

configure_logging()
log = logging.getLogger('router-resolver')

app = web.Application()
setup_aiohttp_session(app)

routes = web.RouteTableDef()

@routes.get('/auth/{namespace}')
async def auth(request):
    app = request.app
    k8s_client = app['k8s_client']
    namespace = request.match_info['namespace']

    headers = {}
    if 'X-Hail-Internal-Authorization' in request.headers:
        headers['Authorization'] = request.headers['X-Hail-Internal-Authorization']
    elif 'Authorization' in request.headers:
        headers['Authorization'] = request.headers['Authorization']
    else:
        session = await aiohttp_session.get_session(request)
        session_id = session.get('session_id')
        if not session_id:
            raise web.HTTPUnauthorized()
        headers['Authorization'] = f'Bearer {session_id}'

    userdata = await async_get_userinfo(headers=headers)
    if userdata['is_developer'] != 1:
        raise web.HTTPUnauthorized()

    try:
        router = await k8s_client.read_namespaced_service('router', namespace)
    except client.rest.ApiException as err:
        if err.status == 404:
            return web.Response(status=403)
        raise
    ports = router.spec.ports
    assert len(ports) == 1
    port = ports[0].port
    if port == 80:
        scheme = 'http'
    else:
        assert port == 443
        scheme = 'https'
    return web.Response(status=200,
                        headers={
                            'X-Router-IP': router.spec.cluster_ip,
                            'X-Router-Scheme': scheme})

@routes.get('/router-scheme/{namespace}')
async def router_scheme(request):
    app = request.app
    k8s_client = app['k8s_client']
    namespace = request.match_info['namespace']

    try:
        router = await k8s_client.read_namespaced_service('router', namespace)
    except client.rest.ApiException as err:
        if err.status == 404:
            return web.Response(status=403)
        raise
    ports = router.spec.ports
    assert len(ports) == 1
    port = ports[0].port
    if port == 80:
        scheme = 'http'
    else:
        assert port == 443
        scheme = 'https'
    return web.Response(status=200,
                        headers={
                            'X-Router-Scheme': scheme})

app.add_routes(routes)

async def on_startup(app):
    if 'BATCH_USE_KUBE_CONFIG' in os.environ:
        await config.load_kube_config()
    else:
        config.load_incluster_config()
    app['k8s_client'] = client.CoreV1Api()

app.on_startup.append(on_startup)

web.run_app(app, host='0.0.0.0', port=5000)
<commit_msg>[router-resolver] unauthorized also means not developer (#8583)<commit_after>import os
import uvloop
import aiohttp
from aiohttp import web
import aiohttp_session
from kubernetes_asyncio import client, config
import logging
from hailtop.auth import async_get_userinfo
from gear import configure_logging, setup_aiohttp_session

uvloop.install()

configure_logging()
log = logging.getLogger('router-resolver')

app = web.Application()
setup_aiohttp_session(app)

routes = web.RouteTableDef()

@routes.get('/auth/{namespace}')
async def auth(request):
    app = request.app
    k8s_client = app['k8s_client']
    namespace = request.match_info['namespace']

    headers = {}
    if 'X-Hail-Internal-Authorization' in request.headers:
        headers['Authorization'] = request.headers['X-Hail-Internal-Authorization']
    elif 'Authorization' in request.headers:
        headers['Authorization'] = request.headers['Authorization']
    else:
        session = await aiohttp_session.get_session(request)
        session_id = session.get('session_id')
        if not session_id:
            raise web.HTTPUnauthorized()
        headers['Authorization'] = f'Bearer {session_id}'

    is_developer = False
    try:
        userdata = await async_get_userinfo(headers=headers)
        is_developer = userdata['is_developer'] == 1
    except aiohttp.client_exceptions.ClientResponseError as err:
        assert err.status == 401, err

    if not is_developer:
        raise web.HTTPUnauthorized()

    try:
        router = await k8s_client.read_namespaced_service('router', namespace)
    except client.rest.ApiException as err:
        if err.status == 404:
            return web.Response(status=403)
        raise
    ports = router.spec.ports
    assert len(ports) == 1
    port = ports[0].port
    if port == 80:
        scheme = 'http'
    else:
        assert port == 443
        scheme = 'https'
    return web.Response(status=200,
                        headers={
                            'X-Router-IP': router.spec.cluster_ip,
                            'X-Router-Scheme': scheme})

@routes.get('/router-scheme/{namespace}')
async def router_scheme(request):
    app = request.app
    k8s_client = app['k8s_client']
    namespace = request.match_info['namespace']

    try:
        router = await k8s_client.read_namespaced_service('router', namespace)
    except client.rest.ApiException as err:
        if err.status == 404:
            return web.Response(status=403)
        raise
    ports = router.spec.ports
    assert len(ports) == 1
    port = ports[0].port
    if port == 80:
        scheme = 'http'
    else:
        assert port == 443
        scheme = 'https'
    return web.Response(status=200,
                        headers={
                            'X-Router-Scheme': scheme})

app.add_routes(routes)

async def on_startup(app):
    if 'BATCH_USE_KUBE_CONFIG' in os.environ:
        await config.load_kube_config()
    else:
        config.load_incluster_config()
    app['k8s_client'] = client.CoreV1Api()

app.on_startup.append(on_startup)

web.run_app(app, host='0.0.0.0', port=5000)
<|endoftext|>