<commit_before># vim: tabstop=4 shiftwidth=4 softtabstop=4

#
#    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 heat.common import exception
from heat.db.sqlalchemy import api as db_api
from heat.engine import clients
from heat.engine import resource
from heat.engine import scheduler
from heat.engine.resources import nova_utils
from heat.engine.resources.neutron import neutron

if clients.neutronclient is not None:
    from neutronclient.common.exceptions import NeutronClientException

class HealthMonitor(neutron.NeutronResource):
    """
    A resource for managing health monitors for load balancers in Neutron.
    """

    properties_schema = {
        'delay': {
            'Type': 'Integer', 'Required': True,
            'Description': _('The minimum time in seconds between regular '
                             'connections of the member.')},
        'type': {
            'Type': 'String', 'Required': True,
            'AllowedValues': ['PING', 'TCP', 'HTTP', 'HTTPS'],
            'Description': _('One of predefined health monitor types.')},
        'max_retries': {
            'Type': 'Integer', 'Required': True,
            'Description': _('Number of permissible connection failures before'
                             ' changing the member status to INACTIVE.')},
        'timeout': {
            'Type': 'Integer', 'Required': True,
            'Description': _('Maximum number of seconds for a monitor to '
                             'wait for a connection to be established before '
                             'it times out.')},
        'admin_state_up': {
            'Default': True, 'Type': 'Boolean',
            'Description': _('The administrative state of the health '
                             'monitor.')},
        'http_method': {
            'Type': 'String',
            'Description': _('The HTTP method used for requests by the '
                             'monitor of type HTTP.')},
        'expected_codes': {
            'Type': 'String',
            'Description': _('The list of HTTP status codes expected in '
                             'response from the member to declare it '
                             'healthy.')},
        'url_path': {
            'Type': 'String',
            'Description': _('The HTTP path used in the HTTP request used '
                             'by the monitor to test a member health.')},
    }

    update_allowed_keys = ('Properties',)
    update_allowed_properties = ('delay', 'max_retries', 'timeout',
                                 'admin_state_up', 'http_method',
                                 'expected_codes', 'url_path')

    attributes_schema = {
        'admin_state_up': _('The administrative state of this health '
                            'monitor.'),
        'delay': _('The minimum time in seconds between regular connections '
                   'of the member.'),
        'expected_codes': _('The list of HTTP status codes expected in '
                            'response from the member to declare it healthy.'),
        'http_method': _('The HTTP method used for requests by the monitor of '
                         'type HTTP.'),
        'id': _('Unique identifier for this health monitor.'),
        'max_retries': _('Number of permissible connection failures before '
                         'changing the member status to INACTIVE.'),
        'timeout': _('Maximum number of seconds for a monitor to wait for a '
                     'connection to be established before it times out.'),
        'type': _('One of predefined health monitor types.'),
        'url_path': _('The HTTP path used in the HTTP request used by the '
                      'monitor to test a member health.'),
        'tenant_id': _('Tenant owning the health monitor.'),
    }

    def handle_create(self):
        properties = self.prepare_properties(
            self.properties,
            self.physical_resource_name())
        health_monitor = self.neutron().create_health_monitor(
            {'health_monitor': properties})['health_monitor']
        self.resource_id_set(health_monitor['id'])

    def _show_resource(self):
        return self.neutron().show_health_monitor(
            self.resource_id)['health_monitor']

    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
        if prop_diff:
            self.neutron().update_health_monitor(
                self.resource_id, {'health_monitor': prop_diff})

    def handle_delete(self):
        try:
            self.neutron().delete_health_monitor(self.resource_id)
        except NeutronClientException as ex:
            if ex.status_code != 404:
                raise ex
        else:
            return scheduler.TaskRunner(self._confirm_delete)()

class Pool(neutron.NeutronResource):
    """
    A resource for managing load balancer pools in Neutron.
    """

    vip_schema = {
        'name': {
            'Type': 'String',
            'Description': _('Name of the vip.')},
        'description': {
            'Type': 'String',
            'Description': _('Description of the vip.')},
        'address': {
            'Type': 'String',
            'Description': _('IP address of the vip.')},
        'connection_limit': {
            'Type': 'Integer',
            'Description': _('The maximum number of connections per second '
                             'allowed for the vip.')},
        'protocol_port': {
            'Type': 'Integer', 'Required': True,
            'Description': _('TCP port on which to listen for client traffic '
                             'that is associated with the vip address.')},
        'admin_state_up': {
            'Default': True, 'Type': 'Boolean',
            'Description': _('The administrative state of this vip.')}
    }

    properties_schema = {
        'protocol': {
            'Type': 'String', 'Required': True,
            'AllowedValues': ['TCP', 'HTTP', 'HTTPS'],
            'Description': _('Protocol for balancing.')},
        'subnet_id': {
            'Type': 'String', 'Required': True,
            'Description': _('The subnet on which the members of the pool '
                             'will be located.')},
        'lb_method': {
            'Type': 'String', 'Required': True,
            'AllowedValues': ['ROUND_ROBIN', 'LEAST_CONNECTIONS',
                              'SOURCE_IP'],
            'Description': _('The algorithm used to distribute load between '
                             'the members of the pool.')},
        'name': {
            'Type': 'String',
            'Description': _('Name of the pool.')},
        'description': {
            'Type': 'String',
            'Description': _('Description of the pool.')},
        'admin_state_up': {
            'Default': True, 'Type': 'Boolean',
            'Description': _('The administrative state of this pool.')},
        'vip': {
            'Type': 'Map', 'Schema': vip_schema, 'Required': True,
            'Description': _('IP address and port of the pool.')},
        'monitors': {
            'Type': 'List',
            'Description': _('List of health monitors associated with the '
                             'pool.')},
    }

    update_allowed_keys = ('Properties',)
    update_allowed_properties = ('description', 'admin_state_up', 'lb_method',
                                 'monitors')

    attributes_schema = {
        'admin_state_up': _('The administrative state of this pool.'),
        'id': _('Unique identifier for this pool.'),
        'name': _('Name of the pool.'),
        'protocol': _('Protocol to balance.'),
        'subnet_id': _('The subnet on which the members of the pool '
                       'will be located.'),
        'lb_method': _('The algorithm used to distribute load between the '
                       'members of the pool.'),
        'description': _('Description of the pool.'),
        'tenant_id': _('Tenant owning the pool.'),
        'vip': _('Vip associated with the pool.'),
    }

    def handle_create(self):
        properties = self.prepare_properties(
            self.properties,
            self.physical_resource_name())
        vip_properties = properties.pop('vip')
        monitors = properties.pop('monitors', [])
        client = self.neutron()
        pool = client.create_pool({'pool': properties})['pool']
        self.resource_id_set(pool['id'])

        for monitor in monitors:
            client.associate_health_monitor(
                pool['id'], {'health_monitor': {'id': monitor}})

        vip_arguments = self.prepare_properties(
            vip_properties,
            '%s.vip' % (self.name,))
        vip_arguments['protocol'] = self.properties['protocol']
        vip_arguments['subnet_id'] = self.properties['subnet_id']
        vip_arguments['pool_id'] = pool['id']
        vip = client.create_vip({'vip': vip_arguments})['vip']

        self.metadata = {'vip': vip['id']}

    def _show_resource(self):
        return self.neutron().show_pool(self.resource_id)['pool']

    def check_create_complete(self, data):
        attributes = self._show_resource()
        if attributes['status'] == 'PENDING_CREATE':
            return False
        elif attributes['status'] == 'ACTIVE':
            vip_attributes = self.neutron().show_vip(
                self.metadata['vip'])['vip']
            if vip_attributes['status'] == 'PENDING_CREATE':
                return False
            elif vip_attributes['status'] == 'ACTIVE':
                return True
            raise exception.Error(
                'neutron reported unexpected vip resource[%s] status[%s]' %
                (vip_attributes['name'], vip_attributes['status']))
        raise exception.Error(
            'neutron report unexpected pool resource[%s] status[%s]' %
            (attributes['name'], attributes['status']))

    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
        if prop_diff:
            client = self.neutron()
            monitors = set(prop_diff.pop('monitors', []))
            if monitors:
                old_monitors = set(self.t['Properties']['monitors'])
                for monitor in old_monitors - monitors:
                    client.disassociate_health_monitor(
                        self.resource_id, {'health_monitor': {'id': monitor}})
                for monitor in monitors - old_monitors:
                    client.associate_health_monitor(
                        self.resource_id, {'health_monitor': {'id': monitor}})

            if prop_diff:
                client.update_pool(self.resource_id, {'pool': prop_diff})

    def _resolve_attribute(self, name):
        if name == 'vip':
            return self.neutron().show_vip(self.metadata['vip'])['vip']
        return super(Pool, self)._resolve_attribute(name)

    def _confirm_vip_delete(self):
        client = self.neutron()
        while True:
            try:
                yield
                client.show_vip(self.metadata['vip'])
            except NeutronClientException as ex:
                if ex.status_code != 404:
                    raise ex
                break
        self._delete_pool()

    def _delete_pool(self):
        try:
            self.neutron().delete_pool(self.resource_id)
        except NeutronClientException as ex:
            if ex.status_code != 404:
                raise ex
        else:
            return scheduler.TaskRunner(self._confirm_delete)()

    def handle_delete(self):
        if self.metadata:
            try:
                self.neutron().delete_vip(self.metadata['vip'])
            except NeutronClientException as ex:
                if ex.status_code != 404:
                    raise ex
                self._delete_pool()
            else:
                return scheduler.TaskRunner(self._confirm_vip_delete)()
        else:
            self._delete_pool()

class LoadBalancer(resource.Resource):
    """
    A resource to link a neutron pool with servers.
    """

    properties_schema = {
        'pool_id': {
            'Type': 'String', 'Required': True,
            'Description': _('The ID of the load balancing pool.')},
        'protocol_port': {
            'Type': 'Integer', 'Required': True,
            'Description': _('Port number on which the servers are '
                             'running on the members.')},
        'members': {
            'Type': 'List',
            'Description': _('The list of Nova server IDs load balanced.')},
    }

    update_allowed_keys = ('Properties',)

    update_allowed_properties = ('members',)

    def handle_create(self):
        pool = self.properties['pool_id']
        client = self.neutron()
        nova_client = self.nova()
        protocol_port = self.properties['protocol_port']
        for member in self.properties['members']:
            address = nova_utils.server_to_ipaddress(nova_client, member)
            lb_member = client.create_member({
                'member': {
                    'pool_id': pool,
                    'address': address,
                    'protocol_port': protocol_port}})['member']
            db_api.resource_data_set(self, member, lb_member['id'])

    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
        if 'members' in prop_diff:
            members = set(prop_diff['members'])
            old_members = set(self.t['Properties'].get('members', []))
            client = self.neutron()
            for member in old_members - members:
                member_id = db_api.resource_data_get(self, member)
                try:
                    client.delete_member(member_id)
                except NeutronClientException as ex:
                    if ex.status_code != 404:
                        raise ex
                db_api.resource_data_delete(self, member)
            pool = self.properties['pool_id']
            nova_client = self.nova()
            protocol_port = self.properties['protocol_port']
            for member in members - old_members:
                address = nova_utils.server_to_ipaddress(nova_client, member)
                lb_member = client.create_member({
                    'member': {
                        'pool_id': pool,
                        'address': address,
                        'protocol_port': protocol_port}})['member']
                db_api.resource_data_set(self, member, lb_member['id'])

    def handle_delete(self):
        client = self.neutron()
        for member in self.properties['members']:
            member_id = db_api.resource_data_get(self, member)
            try:
                client.delete_member(member_id)
            except NeutronClientException as ex:
                if ex.status_code != 404:
                    raise ex
            db_api.resource_data_delete(self, member)

def resource_mapping():
    if clients.neutronclient is None:
        return {}

    return {
        'OS::Neutron::HealthMonitor': HealthMonitor,
        'OS::Neutron::Pool': Pool,
        'OS::Neutron::LoadBalancer': LoadBalancer,
    }
<commit_msg>Remove Neutron load balancer resources id attributes<commit_after># vim: tabstop=4 shiftwidth=4 softtabstop=4

#
#    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 heat.common import exception
from heat.db.sqlalchemy import api as db_api
from heat.engine import clients
from heat.engine import resource
from heat.engine import scheduler
from heat.engine.resources import nova_utils
from heat.engine.resources.neutron import neutron

if clients.neutronclient is not None:
    from neutronclient.common.exceptions import NeutronClientException

class HealthMonitor(neutron.NeutronResource):
    """
    A resource for managing health monitors for load balancers in Neutron.
    """

    properties_schema = {
        'delay': {
            'Type': 'Integer', 'Required': True,
            'Description': _('The minimum time in seconds between regular '
                             'connections of the member.')},
        'type': {
            'Type': 'String', 'Required': True,
            'AllowedValues': ['PING', 'TCP', 'HTTP', 'HTTPS'],
            'Description': _('One of predefined health monitor types.')},
        'max_retries': {
            'Type': 'Integer', 'Required': True,
            'Description': _('Number of permissible connection failures before'
                             ' changing the member status to INACTIVE.')},
        'timeout': {
            'Type': 'Integer', 'Required': True,
            'Description': _('Maximum number of seconds for a monitor to '
                             'wait for a connection to be established before '
                             'it times out.')},
        'admin_state_up': {
            'Default': True, 'Type': 'Boolean',
            'Description': _('The administrative state of the health '
                             'monitor.')},
        'http_method': {
            'Type': 'String',
            'Description': _('The HTTP method used for requests by the '
                             'monitor of type HTTP.')},
        'expected_codes': {
            'Type': 'String',
            'Description': _('The list of HTTP status codes expected in '
                             'response from the member to declare it '
                             'healthy.')},
        'url_path': {
            'Type': 'String',
            'Description': _('The HTTP path used in the HTTP request used '
                             'by the monitor to test a member health.')},
    }

    update_allowed_keys = ('Properties',)
    update_allowed_properties = ('delay', 'max_retries', 'timeout',
                                 'admin_state_up', 'http_method',
                                 'expected_codes', 'url_path')

    attributes_schema = {
        'admin_state_up': _('The administrative state of this health '
                            'monitor.'),
        'delay': _('The minimum time in seconds between regular connections '
                   'of the member.'),
        'expected_codes': _('The list of HTTP status codes expected in '
                            'response from the member to declare it healthy.'),
        'http_method': _('The HTTP method used for requests by the monitor of '
                         'type HTTP.'),
        'max_retries': _('Number of permissible connection failures before '
                         'changing the member status to INACTIVE.'),
        'timeout': _('Maximum number of seconds for a monitor to wait for a '
                     'connection to be established before it times out.'),
        'type': _('One of predefined health monitor types.'),
        'url_path': _('The HTTP path used in the HTTP request used by the '
                      'monitor to test a member health.'),
        'tenant_id': _('Tenant owning the health monitor.'),
    }

    def handle_create(self):
        properties = self.prepare_properties(
            self.properties,
            self.physical_resource_name())
        health_monitor = self.neutron().create_health_monitor(
            {'health_monitor': properties})['health_monitor']
        self.resource_id_set(health_monitor['id'])

    def _show_resource(self):
        return self.neutron().show_health_monitor(
            self.resource_id)['health_monitor']

    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
        if prop_diff:
            self.neutron().update_health_monitor(
                self.resource_id, {'health_monitor': prop_diff})

    def handle_delete(self):
        try:
            self.neutron().delete_health_monitor(self.resource_id)
        except NeutronClientException as ex:
            if ex.status_code != 404:
                raise ex
        else:
            return scheduler.TaskRunner(self._confirm_delete)()

class Pool(neutron.NeutronResource):
    """
    A resource for managing load balancer pools in Neutron.
    """

    vip_schema = {
        'name': {
            'Type': 'String',
            'Description': _('Name of the vip.')},
        'description': {
            'Type': 'String',
            'Description': _('Description of the vip.')},
        'address': {
            'Type': 'String',
            'Description': _('IP address of the vip.')},
        'connection_limit': {
            'Type': 'Integer',
            'Description': _('The maximum number of connections per second '
                             'allowed for the vip.')},
        'protocol_port': {
            'Type': 'Integer', 'Required': True,
            'Description': _('TCP port on which to listen for client traffic '
                             'that is associated with the vip address.')},
        'admin_state_up': {
            'Default': True, 'Type': 'Boolean',
            'Description': _('The administrative state of this vip.')}
    }

    properties_schema = {
        'protocol': {
            'Type': 'String', 'Required': True,
            'AllowedValues': ['TCP', 'HTTP', 'HTTPS'],
            'Description': _('Protocol for balancing.')},
        'subnet_id': {
            'Type': 'String', 'Required': True,
            'Description': _('The subnet on which the members of the pool '
                             'will be located.')},
        'lb_method': {
            'Type': 'String', 'Required': True,
            'AllowedValues': ['ROUND_ROBIN', 'LEAST_CONNECTIONS',
                              'SOURCE_IP'],
            'Description': _('The algorithm used to distribute load between '
                             'the members of the pool.')},
        'name': {
            'Type': 'String',
            'Description': _('Name of the pool.')},
        'description': {
            'Type': 'String',
            'Description': _('Description of the pool.')},
        'admin_state_up': {
            'Default': True, 'Type': 'Boolean',
            'Description': _('The administrative state of this pool.')},
        'vip': {
            'Type': 'Map', 'Schema': vip_schema, 'Required': True,
            'Description': _('IP address and port of the pool.')},
        'monitors': {
            'Type': 'List',
            'Description': _('List of health monitors associated with the '
                             'pool.')},
    }

    update_allowed_keys = ('Properties',)
    update_allowed_properties = ('description', 'admin_state_up', 'lb_method',
                                 'monitors')

    attributes_schema = {
        'admin_state_up': _('The administrative state of this pool.'),
        'name': _('Name of the pool.'),
        'protocol': _('Protocol to balance.'),
        'subnet_id': _('The subnet on which the members of the pool '
                       'will be located.'),
        'lb_method': _('The algorithm used to distribute load between the '
                       'members of the pool.'),
        'description': _('Description of the pool.'),
        'tenant_id': _('Tenant owning the pool.'),
        'vip': _('Vip associated with the pool.'),
    }

    def handle_create(self):
        properties = self.prepare_properties(
            self.properties,
            self.physical_resource_name())
        vip_properties = properties.pop('vip')
        monitors = properties.pop('monitors', [])
        client = self.neutron()
        pool = client.create_pool({'pool': properties})['pool']
        self.resource_id_set(pool['id'])

        for monitor in monitors:
            client.associate_health_monitor(
                pool['id'], {'health_monitor': {'id': monitor}})

        vip_arguments = self.prepare_properties(
            vip_properties,
            '%s.vip' % (self.name,))
        vip_arguments['protocol'] = self.properties['protocol']
        vip_arguments['subnet_id'] = self.properties['subnet_id']
        vip_arguments['pool_id'] = pool['id']
        vip = client.create_vip({'vip': vip_arguments})['vip']

        self.metadata = {'vip': vip['id']}

    def _show_resource(self):
        return self.neutron().show_pool(self.resource_id)['pool']

    def check_create_complete(self, data):
        attributes = self._show_resource()
        if attributes['status'] == 'PENDING_CREATE':
            return False
        elif attributes['status'] == 'ACTIVE':
            vip_attributes = self.neutron().show_vip(
                self.metadata['vip'])['vip']
            if vip_attributes['status'] == 'PENDING_CREATE':
                return False
            elif vip_attributes['status'] == 'ACTIVE':
                return True
            raise exception.Error(
                'neutron reported unexpected vip resource[%s] status[%s]' %
                (vip_attributes['name'], vip_attributes['status']))
        raise exception.Error(
            'neutron report unexpected pool resource[%s] status[%s]' %
            (attributes['name'], attributes['status']))

    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
        if prop_diff:
            client = self.neutron()
            monitors = set(prop_diff.pop('monitors', []))
            if monitors:
                old_monitors = set(self.t['Properties']['monitors'])
                for monitor in old_monitors - monitors:
                    client.disassociate_health_monitor(
                        self.resource_id, {'health_monitor': {'id': monitor}})
                for monitor in monitors - old_monitors:
                    client.associate_health_monitor(
                        self.resource_id, {'health_monitor': {'id': monitor}})

            if prop_diff:
                client.update_pool(self.resource_id, {'pool': prop_diff})

    def _resolve_attribute(self, name):
        if name == 'vip':
            return self.neutron().show_vip(self.metadata['vip'])['vip']
        return super(Pool, self)._resolve_attribute(name)

    def _confirm_vip_delete(self):
        client = self.neutron()
        while True:
            try:
                yield
                client.show_vip(self.metadata['vip'])
            except NeutronClientException as ex:
                if ex.status_code != 404:
                    raise ex
                break
        self._delete_pool()

    def _delete_pool(self):
        try:
            self.neutron().delete_pool(self.resource_id)
        except NeutronClientException as ex:
            if ex.status_code != 404:
                raise ex
        else:
            return scheduler.TaskRunner(self._confirm_delete)()

    def handle_delete(self):
        if self.metadata:
            try:
                self.neutron().delete_vip(self.metadata['vip'])
            except NeutronClientException as ex:
                if ex.status_code != 404:
                    raise ex
                self._delete_pool()
            else:
                return scheduler.TaskRunner(self._confirm_vip_delete)()
        else:
            self._delete_pool()

class LoadBalancer(resource.Resource):
    """
    A resource to link a neutron pool with servers.
    """

    properties_schema = {
        'pool_id': {
            'Type': 'String', 'Required': True,
            'Description': _('The ID of the load balancing pool.')},
        'protocol_port': {
            'Type': 'Integer', 'Required': True,
            'Description': _('Port number on which the servers are '
                             'running on the members.')},
        'members': {
            'Type': 'List',
            'Description': _('The list of Nova server IDs load balanced.')},
    }

    update_allowed_keys = ('Properties',)

    update_allowed_properties = ('members',)

    def handle_create(self):
        pool = self.properties['pool_id']
        client = self.neutron()
        nova_client = self.nova()
        protocol_port = self.properties['protocol_port']
        for member in self.properties['members']:
            address = nova_utils.server_to_ipaddress(nova_client, member)
            lb_member = client.create_member({
                'member': {
                    'pool_id': pool,
                    'address': address,
                    'protocol_port': protocol_port}})['member']
            db_api.resource_data_set(self, member, lb_member['id'])

    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
        if 'members' in prop_diff:
            members = set(prop_diff['members'])
            old_members = set(self.t['Properties'].get('members', []))
            client = self.neutron()
            for member in old_members - members:
                member_id = db_api.resource_data_get(self, member)
                try:
                    client.delete_member(member_id)
                except NeutronClientException as ex:
                    if ex.status_code != 404:
                        raise ex
                db_api.resource_data_delete(self, member)
            pool = self.properties['pool_id']
            nova_client = self.nova()
            protocol_port = self.properties['protocol_port']
            for member in members - old_members:
                address = nova_utils.server_to_ipaddress(nova_client, member)
                lb_member = client.create_member({
                    'member': {
                        'pool_id': pool,
                        'address': address,
                        'protocol_port': protocol_port}})['member']
                db_api.resource_data_set(self, member, lb_member['id'])

    def handle_delete(self):
        client = self.neutron()
        for member in self.properties['members']:
            member_id = db_api.resource_data_get(self, member)
            try:
                client.delete_member(member_id)
            except NeutronClientException as ex:
                if ex.status_code != 404:
                    raise ex
            db_api.resource_data_delete(self, member)

def resource_mapping():
    if clients.neutronclient is None:
        return {}

    return {
        'OS::Neutron::HealthMonitor': HealthMonitor,
        'OS::Neutron::Pool': Pool,
        'OS::Neutron::LoadBalancer': LoadBalancer,
    }
<|endoftext|>


<commit_before>"""
This program is designed for the 2*2 "coordination" game
payoff = np.array([[4,0],[3,2]]) # all players share the same payoff matrix
"""

from __future__ import division
import matplotlib.pyplot as plt
import numpy as np
import random

class Player:
	def __init__(self):
		self.init_action()

	def init_action(self):
		actions = [0,1]
		self.action = random.choice(actions) # the initial action is randomly chosen.

class ellison22_coordination(Player): #This class "inherits" the class "Player" defined above
	def __init__(self,actions=[0,1],p=1/3,N=10,n=1):
		self.players = [Player() for i in range(N)]	#"players" is a list consisting of "player"
		self.p = p
		self.N = N
		self.n = n
		self.actions = actions
	"""
	<Arguments>
	p = 1/3 #If the proportion of players taking 1 exceeds this,other players are better off to take 1
	N = 10 # the number of players
	n = 1 # the number of neighbors on one side.it is 2 in total when n = 1
	actions = [0,1]		#this is 2*2 game and there are strategy 0 and 1
	"""

	def show_action_profile(self):
		print [self.players[i].action for i in range(self.N)]

	def update_rational(self): # function used when a player is "rational"
		# pick a player which can change the action
		d = random.choice(range(self.N))
		nei_numbers = [] # contains the number assigned to each neighbor
		nei_numbers_with_large_small = [i for i in range( -self.n , self.n+1)] # contains the chosen player,may contain inappropriate numbers
		del nei_numbers_with_large_small[self.n] #delete the chosen player

		for i in nei_numbers_with_large_small:
			if i < 0:
				i = i + self.N

			if i >= self.N:
				i = i - self.N

			nei_numbers.append(i)

		nei_action = [self.players[i].action for i in nei_numbers] # neighbors' action profile

		if sum(nei_action) > self.p:   # determine the action so that it is the best response to the action profile of the community
			self.players[d].action = 1
		else:
			self.players[d].action = 0

	def update_irrational(self): # function used when a player is "irrational"
		d = random.choice(range(self.N))
		self.players[d].action = random.choice(self.actions) # action is randomly chosen because he is irrational

	def play(self,X=10000,epsilon=0.01): # X is the number of repetition.epsilon is the possibility of a player getting "irrational"
		self.show_action_profile() #show the initial action profile
		for i in range(X):
			if random.uniform(0,1) > epsilon:
				self.update_rational() #the argument "update_rational" takes is the list "players" the function "play" takes.
			else:    # it is confusing because the same name is used for both.I should make it clearer
				self.update_irrational()

		self.show_action_profile() # show the action profile at the end of the game

	def reset(self): # after using "play" you wanna use this to initialize the action profile
		for i in self.players:
			i.init_action()

	def draw_histogram(self,X=100,epsilon=0.01): # draws a histogram about the state dynamics during the game.
 		state_list =[] # "state" is the number of players taking 1 devided by N
		action_profile = [self.players[i].action for i in range(self.N)]
		state_list.append(sum(action_profile) / float(self.N)) #added the initial state

		for i in range(X):
			if random.uniform(0,1) > epsilon:
				self.update_rational()
			else:
				self.update_irrational()

			action_profile = [self.players[i].action for i in range(self.N)]
			state_list.append(sum(action_profile) / float(self.N))

		fig, ax = plt.subplots()
		ax.hist(state_list)

		plt.show()

	def draw_graph(self,X=100,epsilon=0.01): #draws a graph which represents the state dynamics during the game
		state_list =[] # "state" is the number of players taking 1 devided by N
		action_profile = [self.players[i].action for i in range(self.N)]
		state_list.append(sum(action_profile) / float(self.N)) #added the initial state

		for i in range(X):
			if random.uniform(0,1) > epsilon:
				self.update_rational()
			else:
				self.update_irrational()

			action_profile = [self.players[i].action for i in range(self.N)]
			state_list.append(sum(action_profile) / float(self.N))

		fig, ax = plt.subplots()
		ax.plot(state_list,label='state')
		ax.legend(bbox_to_anchor=(1.05, 0), loc='best', borderaxespad=0)

		plt.show()
		<commit_msg>設定変更。tab直っているかの試験<commit_after>"""
This program is designed for the 2*2 "coordination" game
payoff = np.array([[4,0],[3,2]]) # all players share the same payoff matrix
"""

from __future__ import division
import matplotlib.pyplot as plt
import numpy as np
import random

class Player:
	def __init__(self):
		self.init_action()

	def init_action(self):
		actions = [0,1]
		self.action = random.choice(actions) # the initial action is randomly chosen.

class ellison22_coordination(Player): #This class "inherits" the class "Player" defined above
	def __init__(self,p=1/3,N=10,n=1):
		self.players = [Player() for i in range(N)]	#"players" is a list consisting of "player"
		self.p = p
		self.N = N
		self.n = n
		self.actions = [0,1]
	"""
	<Arguments>
	p = 1/3 #If the proportion of players taking 1 exceeds this,other players are better off to take 1
	N = 10 # the number of players
	n = 1 # the number of neighbors on one side.it is 2 in total when n = 1
	"""

	def show_action_profile(self):
		print [self.players[i].action for i in range(self.N)]

	def update_rational(self): # function used when a player is "rational"
		# pick a player which can change the action
		d = random.choice(range(self.N))
		nei_numbers = [] # contains the number assigned to each neighbor
		nei_numbers_with_large_small = [i for i in range( -self.n , self.n+1)] # contains the chosen player,may contain inappropriate numbers
		del nei_numbers_with_large_small[self.n] #delete the chosen player

		for i in nei_numbers_with_large_small:
			if i < 0:
				i = i + self.N

			if i >= self.N:
				i = i - self.N

			nei_numbers.append(i)

		nei_action = [self.players[i].action for i in nei_numbers] # neighbors' action profile

		if sum(nei_action) > self.p:   # determine the action so that it is the best response to the action profile of the community
			self.players[d].action = 1
		else:
			self.players[d].action = 0

	def update_irrational(self): # function used when a player is "irrational"
		d = random.choice(range(self.N))
		self.players[d].action = random.choice(self.actions) # action is randomly chosen because he is irrational

	def play(self,X=10000,epsilon=0.01): # X is the number of repetition.epsilon is the possibility of a player getting "irrational"
		self.show_action_profile() #show the initial action profile
		for i in range(X):
			if random.uniform(0,1) > epsilon:
				self.update_rational() #the argument "update_rational" takes is the list "players" the function "play" takes.
			else:    # it is confusing because the same name is used for both.I should make it clearer
				self.update_irrational()

		self.show_action_profile() # show the action profile at the end of the game

	def reset(self): # after using "play" you wanna use this to initialize the action profile
		for i in self.players:
			i.init_action()

	def draw_histogram(self,X=100,epsilon=0.01): # draws a histogram about the state dynamics during the game.
 		state_list =[] # "state" is the number of players taking 1 devided by N
		action_profile = [self.players[i].action for i in range(self.N)]
		state_list.append(sum(action_profile) / float(self.N)) #added the initial state

		for i in range(X):
			if random.uniform(0,1) > epsilon:
				self.update_rational()
			else:
				self.update_irrational()

			action_profile = [self.players[i].action for i in range(self.N)]
			state_list.append(sum(action_profile) / float(self.N))

		fig, ax = plt.subplots()
		ax.hist(state_list)

		plt.show()

	def draw_graph(self,X=100,epsilon=0.01): #draws a graph which represents the state dynamics during the game
		state_list =[] # "state" is the number of players taking 1 devided by N
		action_profile = [self.players[i].action for i in range(self.N)]
		state_list.append(sum(action_profile) / float(self.N)) #added the initial state

		for i in range(X):
			if random.uniform(0,1) > epsilon:
				self.update_rational()
			else:
				self.update_irrational()

			action_profile = [self.players[i].action for i in range(self.N)]
			state_list.append(sum(action_profile) / float(self.N))

		fig, ax = plt.subplots()
		ax.plot(state_list,label='state')
		ax.legend(bbox_to_anchor=(1.05, 0), loc='best', borderaxespad=0)

		plt.show()
		<|endoftext|>


<commit_before>from __future__ import print_function

import tst
import sys
import os

from urlparse import urlparse

from tst.colors import *
from tst.utils import cprint
from tst.utils import _assert
from tst.utils import is_posix_filename
from tst.utils import data2json
from tst.jsonfile import JsonFile

def main():
    assert sys.argv[0].endswith('tst') and sys.argv[1] == 'checkout'

    # parse user arguments
    args = sys.argv[2:]
    site, key, target_dir, overwrite = process_args(args)

    checkout(site, key, target_dir, overwrite)

def syntax_help():
    return LRED + "This is not a tst directory.\n" + RESET +\
           "Usage: tst checkout <key>[@<site>] [<directory>]\n"\
           "       tst checkout <url> [<directory>]\n\n"\
           "   or: tst checkout\n"\
           "       (inside a tst directory)"\

def process_args(args):
    _assert(0 <= len(args) <= 3, syntax_help())

    # process overwrite argument
    YES = ["--yes", "-y"]
    overwrite = any(yes in args for yes in YES)
    args = [e for e in args if e not in YES]

    # add default args
    if len(args) == 0:
        ## no args: use current directory
        cwd = os.getcwd()
        _assert(tst.dirtype(cwd) == "assignment", "This directory is not a tst activity")
        args.append(os.path.basename(cwd))
        args.append(".")

    elif len(args) == 1 and os.path.isdir(args[0]):
        ## single directory as arg: make sure is a checkout
        checkout_file = args[0] + "/.tst/assignment.json"
        _assert(os.path.exists(checkout_file), "Directory %s has no checkout info\n%sTry: tst checkout key <new-directory>" % (args[0], RESET))
        tst_object = JsonFile(checkout_file)
        _assert("key" in tst_object, "Checkout corrupted: missing key")
        _assert("site" in tst_object, "Checkout corrupted: missing site")
        args = ["%s@%s" % (tst_object["key"], tst_object["site"]), args[0]]

    data = { "destdir": args[1] if len(args) > 1 else None }

    key_or_url = args[0]
    url = urlparse(key_or_url)
    _assert(not url.fragment, "Fragments not supported in url")
    _assert(not url.username, "Usernames not supported in url")
    _assert(not url.password, "Passwords not supported in url")

    if url.scheme == 'http':
        # key_or_url == "http://.../key"
        path, key = url.path.rsplit("/", 1) if "/" in url.path else (url.path, '')
        data["url"] = "%s://%s%s" % (url.scheme, url.netloc, path)
        data["site"] = None
        data["key"] = key

    elif is_posix_filename(key_or_url, extra_chars="@"):
        num_ats = key_or_url.count("@")
        if num_ats == 0:
            # key_or_url == "key"
            data["url"] = None
            data["site"] = "_DEFAULT"
            data["key"] = key_or_url

        elif num_ats == 1:
            # key_or_url == "key@site"
            key, sitename = key_or_url.split("@")
            data["url"] = None
            data["site"] = sitename
            data["key"] = key
    else:
        _assert(False, "Unrecognized key/url")

    # get site based either on sitename or url
    assert data['site'] is None or data['url'] is None
    site = tst.get_site(name=data['site']) if data['site'] else tst.get_site(url=url)
    _assert(site and site.url, "No site/url identified. Check your config.yaml")

    return site, data['key'], data['destdir'], overwrite

def existing_files(basedir, files):
    filenames = []
    for f in files:
        fullname = "%s/%s" % (basedir, f['name'])
        if os.path.exists(fullname):
            filenames.append(fullname)

    return filenames

def checkout(site, key, target_dir, overwrite):
    """checkout tst object from site/collection"""

    def is_valid_dir(dirtype):
        return dirtype in [None, "assignment"]

    # fetch tst object
    cprint(LGREEN, "Fetching %s from %s" % (key, site.name or site.url))
    tst_object = site.get(key) or site.get_directory(key)
    _assert(tst_object, "Cannot checkout %s from site %s (%s)" % (key, site.name, str(site.last_error)))

    # set destination directory
    destdir = target_dir or tst_object.get('dirname') or tst_object.get('name') or key
    if not target_dir:
        cprint(YELLOW, "Directory argument not found")
        cprint(RESET, "(You can add directory as an additional argument)")
        while True:
            destdir = raw_input("Provide directory name (default %s): " % destdir) or key
            if is_posix_filename(destdir): break
            cprint(YELLOW, "Invalid portable posix filename: '%s'" % destdir)

    _assert(not os.path.exists(destdir) or (os.path.isdir(destdir) and is_valid_dir(tst.dirtype(destdir))), "Invalid target directory: %s" % destdir)

    # check whether files exist
    old_files = existing_files(destdir, tst_object['files'])
    if old_files and not overwrite:
        cprint(YELLOW, "If you proceed, these files will be overwriten")
        for fn in old_files:
            cprint(LCYAN, fn)

        cprint(YELLOW, "Proceed (y/n)? ", end="")
        if raw_input() != "y":
            cprint(LRED, "Aborting check out")
            sys.exit(1)

    # save files
    saved = tst.save_files(tst_object['files'], destdir)
    cprint(LBLUE, "%d files saved to %s%s%s directory" % (saved, LCYAN, destdir, LBLUE))
    if len(tst_object['files']) > saved:
        cprint(YELLOW, "%d files were NOT saved" % (len(tst_object['files']) - saved))

    internal = [{
        "name": ".tst/assignment.json",
        "content": data2json({
            "kind": "assignment",
            "site": site.name,
            "key": key,
            "iid": tst_object.get('iid'),
        })
    }]
    tst.save_files(internal, destdir, verbose=False)
<commit_msg>Make checkout add user info in .tst dir<commit_after>from __future__ import print_function

import tst
import sys
import os

from urlparse import urlparse

from tst.colors import *
from tst.utils import cprint
from tst.utils import _assert
from tst.utils import is_posix_filename
from tst.utils import data2json
from tst.jsonfile import JsonFile

def main():
    assert sys.argv[0].endswith('tst') and sys.argv[1] == 'checkout'

    # parse user arguments
    args = sys.argv[2:]
    site, key, target_dir, overwrite = process_args(args)

    checkout(site, key, target_dir, overwrite)

def syntax_help():
    return LRED + "This is not a tst directory.\n" + RESET +\
           "Usage: tst checkout <key>[@<site>] [<directory>]\n"\
           "       tst checkout <url> [<directory>]\n\n"\
           "   or: tst checkout\n"\
           "       (inside a tst directory)"\

def process_args(args):
    _assert(0 <= len(args) <= 3, syntax_help())

    # process overwrite argument
    YES = ["--yes", "-y"]
    overwrite = any(yes in args for yes in YES)
    args = [e for e in args if e not in YES]

    # add default args
    if len(args) == 0:
        ## no args: use current directory
        cwd = os.getcwd()
        _assert(tst.dirtype(cwd) == "assignment", "This directory is not a tst activity")
        args.append(os.path.basename(cwd))
        args.append(".")

    elif len(args) == 1 and os.path.isdir(args[0]):
        ## single directory as arg: make sure is a checkout
        checkout_file = args[0] + "/.tst/assignment.json"
        _assert(os.path.exists(checkout_file), "Directory %s has no checkout info\n%sTry: tst checkout key <new-directory>" % (args[0], RESET))
        tst_object = JsonFile(checkout_file)
        _assert("key" in tst_object, "Checkout corrupted: missing key")
        _assert("site" in tst_object, "Checkout corrupted: missing site")
        args = ["%s@%s" % (tst_object["key"], tst_object["site"]), args[0]]

    data = { "destdir": args[1] if len(args) > 1 else None }

    key_or_url = args[0]
    url = urlparse(key_or_url)
    _assert(not url.fragment, "Fragments not supported in url")
    _assert(not url.username, "Usernames not supported in url")
    _assert(not url.password, "Passwords not supported in url")

    if url.scheme == 'http':
        # key_or_url == "http://.../key"
        path, key = url.path.rsplit("/", 1) if "/" in url.path else (url.path, '')
        data["url"] = "%s://%s%s" % (url.scheme, url.netloc, path)
        data["site"] = None
        data["key"] = key

    elif is_posix_filename(key_or_url, extra_chars="@"):
        num_ats = key_or_url.count("@")
        if num_ats == 0:
            # key_or_url == "key"
            data["url"] = None
            data["site"] = "_DEFAULT"
            data["key"] = key_or_url

        elif num_ats == 1:
            # key_or_url == "key@site"
            key, sitename = key_or_url.split("@")
            data["url"] = None
            data["site"] = sitename
            data["key"] = key
    else:
        _assert(False, "Unrecognized key/url")

    # get site based either on sitename or url
    assert data['site'] is None or data['url'] is None
    site = tst.get_site(name=data['site']) if data['site'] else tst.get_site(url=url)
    _assert(site and site.url, "No site/url identified. Check your config.yaml")

    return site, data['key'], data['destdir'], overwrite

def existing_files(basedir, files):
    filenames = []
    for f in files:
        fullname = "%s/%s" % (basedir, f['name'])
        if os.path.exists(fullname):
            filenames.append(fullname)

    return filenames

def checkout(site, key, target_dir, overwrite):
    """checkout tst object from site/collection"""

    def is_valid_dir(dirtype):
        return dirtype in [None, "assignment"]

    # fetch tst object
    cprint(LGREEN, "Fetching %s from %s" % (key, site.name or site.url))
    tst_object = site.get(key) or site.get_directory(key)
    _assert(tst_object, "Cannot checkout %s from site %s (%s)" % (key, site.name, str(site.last_error)))

    # set destination directory
    destdir = target_dir or tst_object.get('dirname') or tst_object.get('name') or key
    if not target_dir:
        cprint(YELLOW, "Directory argument not found")
        cprint(RESET, "(You can add directory as an additional argument)")
        while True:
            destdir = raw_input("Provide directory name (default %s): " % destdir) or key
            if is_posix_filename(destdir): break
            cprint(YELLOW, "Invalid portable posix filename: '%s'" % destdir)

    _assert(not os.path.exists(destdir) or (os.path.isdir(destdir) and is_valid_dir(tst.dirtype(destdir))), "Invalid target directory: %s" % destdir)

    # check whether files exist
    old_files = existing_files(destdir, tst_object['files'])
    if old_files and not overwrite:
        cprint(YELLOW, "If you proceed, these files will be overwriten")
        for fn in old_files:
            cprint(LCYAN, fn)

        cprint(YELLOW, "Proceed (y/n)? ", end="")
        if raw_input() != "y":
            cprint(LRED, "Aborting check out")
            sys.exit(1)

    # save files
    saved = tst.save_files(tst_object['files'], destdir)
    cprint(LBLUE, "%d files saved to %s%s%s directory" % (saved, LCYAN, destdir, LBLUE))
    if len(tst_object['files']) > saved:
        cprint(YELLOW, "%d files were NOT saved" % (len(tst_object['files']) - saved))

    internal = [{
        "name": ".tst/assignment.json",
        "content": data2json({
            "kind": "assignment",
            "site": site.name,
            "key": key,
            "iid": tst_object.get('iid'),
            "user": tst_object.get('user'),
        })
    }]
    print(tst_object.keys())
    tst.save_files(internal, destdir, verbose=False)
<|endoftext|>


<commit_before>import re
import logging
import os
from collections import defaultdict

from django.core.files import File
from nexus import NexusReader
from ete2 import Tree
from ete2.coretype.tree import TreeError
from dplace_app.models import Society, LanguageTree, Language, LanguageTreeLabels, LanguageTreeLabelsSequence
from dplace_app.tree import update_newick
from util import csv_dict_reader

def tree_names(name_dir):
    sequences = []
    for fname in os.listdir(name_dir):
        if fname.startswith('phylogeny'): #save all csv files as phylogeny_name_etc.csv
            res = _tree_names(fname.split('_')[1], csv_dict_reader(os.path.join(name_dir,fname)), sequences)
    LanguageTreeLabelsSequence.objects.bulk_create(sequences)
    return len(sequences)

def _tree_names(tree_name, items, label_sequences):
    try:
        tree = LanguageTree.objects.get(name=tree_name+'.trees')
    except:
        return False

    try:
        newick = Tree(tree.newick_string, format=1)
    except TreeError:
        return False

    for item in items:
        name_on_tip = item['Name_on_tree_tip']
        xd_ids = [i.strip() for i in item['xd_id'].split(',')]
        society_ids = [i.strip() for i in item['soc_id'].split(',')]
        order = item['fixed_order']

        if not xd_ids: # pragma: no cover
            continue

        label, created = LanguageTreeLabels.objects.get_or_create(
            languageTree=tree,
            label=name_on_tip
        )

        tree.taxa.add(label)
        for society in Society.objects.all().filter(xd_id__in=xd_ids):
            try:
                f_order = len(society_ids) - society_ids.index(society.ext_id) - 1
            except:
                f_order = 0
            label_sequences.append(
                LanguageTreeLabelsSequence(
                    society=society,
                    labels=label,
                    fixed_order=f_order
                )
            )
    tree.save()
    return True

def load_trees(tree_dir, verbose=False):
    l_by_iso, l_by_glotto, l_by_name = \
        defaultdict(list), defaultdict(list), defaultdict(list)

    for lang in Language.objects.all().select_related('iso_code'):
        if lang.iso_code:
            l_by_iso[lang.iso_code.iso_code].append(lang)
        l_by_glotto[lang.glotto_code].append(lang)
        l_by_name[lang.name].append(lang)

    def get_language(taxon_name):
        if taxon_name in l_by_iso:
            return l_by_iso[taxon_name]
        if taxon_name in l_by_glotto:
            return l_by_glotto[taxon_name]
        if taxon_name in l_by_name:
            return l_by_name[taxon_name]

    count = 0
    for fname in os.listdir(tree_dir):
        if fname.endswith('.trees'):
            if _load_tree(os.path.join(tree_dir, fname), get_language):
                count += 1
    return count

def _load_tree(file_name, get_language, verbose=False):
    # make a tree if not exists. Use the name of the tree
    tree, created = LanguageTree.objects.get_or_create(
        name=os.path.basename(file_name)
    )
    if not created:
        return False

    with open(file_name, 'r') as f:
        tree.file = File(f)
        tree.save()

    # now add languages to the tree
    reader = NexusReader(file_name)
    # Remove '[&R]' from newick string
    reader.trees.detranslate()
    newick = re.sub(r'\[.*?\]', '', reader.trees.trees[0])
    try:
        newick = newick[newick.index('=') + 1:]
    except ValueError:  # pragma: no cover
        newick = newick

    if verbose:  # pragma: no cover
        logging.info("Formatting newick string %s" % (newick))

    tree.newick_string = str(newick)
    if 'global' not in file_name and'glotto' not in file_name:
        tree.save()
        return True

    # phylogeny taxa require reading of CSV mapping files, glottolog trees do not
    for taxon_name in reader.trees.taxa:
        if taxon_name is '1':
            continue  # pragma: no cover
        languages = get_language(taxon_name)
        if not languages:
            continue

        for l in languages:
            society = Society.objects.filter(language=l)
            label, created = LanguageTreeLabels.objects.get_or_create(
                languageTree=tree,
                label=taxon_name,
                language=l
            )
            for s in society:
                LanguageTreeLabelsSequence.objects.get_or_create(
                    society=s,
                    labels=label,
                    fixed_order=0
                )
            tree.taxa.add(label)
    tree.save()
    return True

def prune_trees():
    labels = LanguageTreeLabels.objects.all()
    count = 0
    for t in LanguageTree.objects.order_by('name').all():
        if update_newick(t, labels):
            count += 1
            t.save()
    return count
<commit_msg>don't prune global tree<commit_after>import re
import logging
import os
from collections import defaultdict

from django.core.files import File
from nexus import NexusReader
from ete2 import Tree
from ete2.coretype.tree import TreeError
from dplace_app.models import Society, LanguageTree, Language, LanguageTreeLabels, LanguageTreeLabelsSequence
from dplace_app.tree import update_newick
from util import csv_dict_reader

def tree_names(name_dir):
    sequences = []
    for fname in os.listdir(name_dir):
        if fname.startswith('phylogeny'): #save all csv files as phylogeny_name_etc.csv
            res = _tree_names(fname.split('_')[1], csv_dict_reader(os.path.join(name_dir,fname)), sequences)
    LanguageTreeLabelsSequence.objects.bulk_create(sequences)
    return len(sequences)

def _tree_names(tree_name, items, label_sequences):
    try:
        tree = LanguageTree.objects.get(name=tree_name+'.trees')
    except:
        return False

    try:
        newick = Tree(tree.newick_string, format=1)
    except TreeError:
        return False

    for item in items:
        name_on_tip = item['Name_on_tree_tip']
        xd_ids = [i.strip() for i in item['xd_id'].split(',')]
        society_ids = [i.strip() for i in item['soc_id'].split(',')]
        order = item['fixed_order']

        if not xd_ids: # pragma: no cover
            continue

        label, created = LanguageTreeLabels.objects.get_or_create(
            languageTree=tree,
            label=name_on_tip
        )

        tree.taxa.add(label)
        for society in Society.objects.all().filter(xd_id__in=xd_ids):
            try:
                f_order = len(society_ids) - society_ids.index(society.ext_id) - 1
            except:
                f_order = 0
            label_sequences.append(
                LanguageTreeLabelsSequence(
                    society=society,
                    labels=label,
                    fixed_order=f_order
                )
            )
    tree.save()
    return True

def load_trees(tree_dir, verbose=False):
    l_by_iso, l_by_glotto, l_by_name = \
        defaultdict(list), defaultdict(list), defaultdict(list)

    for lang in Language.objects.all().select_related('iso_code'):
        if lang.iso_code:
            l_by_iso[lang.iso_code.iso_code].append(lang)
        l_by_glotto[lang.glotto_code].append(lang)
        l_by_name[lang.name].append(lang)

    def get_language(taxon_name):
        if taxon_name in l_by_iso:
            return l_by_iso[taxon_name]
        if taxon_name in l_by_glotto:
            return l_by_glotto[taxon_name]
        if taxon_name in l_by_name:
            return l_by_name[taxon_name]

    count = 0
    for fname in os.listdir(tree_dir):
        if fname.endswith('.trees'):
            if _load_tree(os.path.join(tree_dir, fname), get_language):
                count += 1
    return count

def _load_tree(file_name, get_language, verbose=False):
    # make a tree if not exists. Use the name of the tree
    tree, created = LanguageTree.objects.get_or_create(
        name=os.path.basename(file_name)
    )
    if not created:
        return False

    with open(file_name, 'r') as f:
        tree.file = File(f)
        tree.save()

    # now add languages to the tree
    reader = NexusReader(file_name)
    # Remove '[&R]' from newick string
    reader.trees.detranslate()
    newick = re.sub(r'\[.*?\]', '', reader.trees.trees[0])
    try:
        newick = newick[newick.index('=') + 1:]
    except ValueError:  # pragma: no cover
        newick = newick

    if verbose:  # pragma: no cover
        logging.info("Formatting newick string %s" % (newick))

    tree.newick_string = str(newick)
    if 'global' not in file_name and'glotto' not in file_name:
        tree.save()
        return True

    # phylogeny taxa require reading of CSV mapping files, glottolog trees do not
    for taxon_name in reader.trees.taxa:
        if taxon_name is '1':
            continue  # pragma: no cover
        languages = get_language(taxon_name)
        if not languages:
            continue

        for l in languages:
            society = Society.objects.filter(language=l)
            label, created = LanguageTreeLabels.objects.get_or_create(
                languageTree=tree,
                label=taxon_name,
                language=l
            )
            for s in society:
                LanguageTreeLabelsSequence.objects.get_or_create(
                    society=s,
                    labels=label,
                    fixed_order=0
                )
            tree.taxa.add(label)
    tree.save()
    return True

def prune_trees():
    labels = LanguageTreeLabels.objects.all()
    count = 0
    for t in LanguageTree.objects.order_by('name').all():
        if not t.name.startswith('global'):
            if update_newick(t, labels):
                count += 1
                t.save()
    return count
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
#!/usr/bin/env python
# author: bambooom
'''
MyDiary Web Application
Open web browser and access http://omoocpy.sinaapp.com/
You can read the old diary and input new diary
'''
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

from bottle import Bottle, request, route, run, template
import sae
import sae.kvdb
from time import localtime, strftime
import hashlib
import urllib2
import xml.etree.ElementTree as ET

@app.route('/wechat')
def check_signature():
	'''
	wechat access verification
	'''
	token = "bambooom2bpythonic"
	signature = request.GET.get('signature',None)
	timestamp = request.GET.get('timestamp',None)
	nonce = request.GET.get('nonce',None)
	echostr = request.GET.get('echostr',None)
	L = [token,timestamp,nonce]
	L.sort()
	s=L[0]+L[1]+L[2]
	if hashlib.sha1(s).hexdigest() == signature:
		return echostr
	else:
		return None

app = Bottle()
kv = sae.kvdb.Client()

def read_diary_all():
	log = []
	for i in list(kv.get_by_prefix("key#")):
		log.append(i[1])
	return log

def write_diary(newdiary,tags,count):
	# key must be str()
	countkey = "key#" + str(count)
	edit_time = strftime("%Y %b %d %H:%M:%S", localtime())
	diary = {'time':edit_time,'diary':newdiary,'tags':tags}
	kv.set(countkey,diary)

@app.route('/')
def start():
	diarylog = read_diary_all()
	return template("diarysae", diarylog=diarylog)

@app.route('/', method='POST')
def input_new():
	count = len(read_diary_all())
	newdiary = unicode(request.forms.get('newdiary'),'utf-8')
	tags = unicode(request.forms.get('tags'),'utf-8')
	write_diary(newdiary,tags,count)
	diarylog = read_diary_all()
	return template("diarysae", diarylog=diarylog)

@app.route('/', method='DELETE')
def delete():
	temp = kv.getkeys_by_prefix("key#")
	for i in temp:
		kv.delete(i)

application = sae.create_wsgi_app(app)
<commit_msg>try parse xml function<commit_after># -*- coding: utf-8 -*-
#!/usr/bin/env python
# author: bambooom
'''
MyDiary Web Application
Open web browser and access http://omoocpy.sinaapp.com/
You can read the old diary and input new diary
'''
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

from bottle import Bottle, request, route, run, template
import sae
import sae.kvdb
from time import localtime, strftime
import hashlib
import urllib2
import xml.etree.ElementTree as ET

app = Bottle()
kv = sae.kvdb.Client()

@app.route('/wechat')
def check_signature():
	'''
	wechat access verification
	'''
	token = "bambooom2bpythonic"
	signature = request.GET.get('signature',None)
	timestamp = request.GET.get('timestamp',None)
	nonce = request.GET.get('nonce',None)
	echostr = request.GET.get('echostr',None)
	L = [token,timestamp,nonce]
	L.sort()
	s=L[0]+L[1]+L[2]
	if hashlib.sha1(s).hexdigest() == signature:
		return echostr
	else:
		return None

def parse_xml_msg(recv_xml):
	#recv_xml = request.body.read()
	root = ET.fromstring(recv_xml)
	for child in root:
		print child.tag
		print child.text

recv_xml = '''
<xml>
 <ToUserName><![CDATA[bambooom]]></ToUserName>
 <FromUserName><![CDATA[omoocpy]]></FromUserName>
 <CreateTime>20151120</CreateTime>
 <MsgType><![CDATA[text]]></MsgType>
 <Content><![CDATA[WTF]]></Content>
 <MsgId>hdsicwecewew2233333</MsgId>
 </xml>
 '''

parse_xml_msg(recv_xml)

def read_diary_all():
	log = []
	for i in list(kv.get_by_prefix("key#")):
		log.append(i[1])
	return log

def write_diary(newdiary,tags,count):
	# key must be str()
	countkey = "key#" + str(count)
	edit_time = strftime("%Y %b %d %H:%M:%S", localtime())
	diary = {'time':edit_time,'diary':newdiary,'tags':tags}
	kv.set(countkey,diary)

@app.route('/')
def start():
	diarylog = read_diary_all()
	return template("diarysae", diarylog=diarylog)

@app.route('/', method='POST')
def input_new():
	count = len(read_diary_all())
	newdiary = unicode(request.forms.get('newdiary'),'utf-8')
	tags = unicode(request.forms.get('tags'),'utf-8')
	write_diary(newdiary,tags,count)
	diarylog = read_diary_all()
	return template("diarysae", diarylog=diarylog)

@app.route('/', method='DELETE')
def delete():
	temp = kv.getkeys_by_prefix("key#")
	for i in temp:
		kv.delete(i)

#application = sae.create_wsgi_app(app)
<|endoftext|>


<commit_before>#!/usr/bin/python
# Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""A tool to run the v8 tests.

  For a list of command-line options, call this script with '--help'.
"""

import optparse
import sys

from common import chromium_utils

def main():
  if sys.platform in ('win32', 'cygwin'):
    default_platform = 'win'
  elif sys.platform.startswith('darwin'):
    default_platform = 'mac'
  elif sys.platform == 'linux2':
    default_platform = 'linux'
  else:
    default_platform = None

  option_parser = optparse.OptionParser()

  option_parser.add_option('', '--testname',
                           default=None,
                           help='The test to run'
                                '[default: %default]')
  option_parser.add_option('', '--target',
                           default='debug',
                           help='build target (Debug, Release) '
                                '[default: %default]')
  option_parser.add_option('', '--arch',
                           default='ia32',
                           help='Architecture (ia32, x64, arm) '
                                '[default: ia32]')
  option_parser.add_option('', '--build-dir',
                           default='v8/obj',
                           metavar='DIR',
                           help='directory in which build was run '
                                '[default: %default]')
  option_parser.add_option('', '--platform',
                           default=default_platform,
                           help='specify platform [default: %%default]')
  option_parser.add_option('', '--shard_count',
                           default=1,
                           help='Specify shard count [default: %%default]')
  option_parser.add_option('', '--shard_run',
                           default=1,
                           help='Specify shard count [default: %%default]')
  option_parser.add_option('--shell_flags',
                           default=None,
                           help="Specify shell flags passed tools/test.py")
  option_parser.add_option('--isolates',
                           default=None,
                           help="Run isolates tests")

  options, args = option_parser.parse_args()
  if args:
    option_parser.error('Unsupported arguments: %s' % args)

  simultaneous = '-j8'
  if options.platform in ('win' 'arm'):
    simultaneous = '-j1'

  if options.testname == 'leak':
    cmd = ['python', 'tools/test.py', '--no-build', '--mode',
           'debug', '--progress', 'verbose', '--timeout', '180',
           '--time', '-Snapshot=on', '--special-command',
           '"@ --nopreallocate-message-memory"',
           '--valgrind', 'mjsunit/leakcheck',
           'mjsunit/regress/regress-1134697', 'mjsunit/number-tostring-small']
  elif options.testname == 'presubmit':
    cmd = ['python', 'tools/presubmit.py']
  else:
    cmd = ['python', 'tools/test.py',
           simultaneous,
           '--progress=verbose',
           '--no-build',
           '--arch=' + options.arch,
           '--mode=' + options.target]
    if options.testname:
      cmd.extend([options.testname])
    if options.testname == 'mozilla':
      # Mozilla tests requires a number of tests to timeout, set it a bit lower.
      cmd.extend(['--timeout=120'])
    elif options.arch == 'arm':
      cmd.extend(['--timeout=600'])
    else:
      cmd.extend(['--timeout=180'])
    if options.isolates:
      cmd.extend(['--isolates'])
    if options.shell_flags:
      cmd.extend(["--special-command", options.shell_flags.replace("\"", "")])

  if options.shard_count > 1:
    cmd.extend(['--shard-count', options.shard_count,
                '--shard-run', options.shard_run])

  return chromium_utils.RunCommand(cmd)

if __name__ == '__main__':
  sys.exit(main())
<commit_msg>Change default timeout on v8 slaves to 200 seconds.<commit_after>#!/usr/bin/python
# Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""A tool to run the v8 tests.

  For a list of command-line options, call this script with '--help'.
"""

import optparse
import sys

from common import chromium_utils

def main():
  if sys.platform in ('win32', 'cygwin'):
    default_platform = 'win'
  elif sys.platform.startswith('darwin'):
    default_platform = 'mac'
  elif sys.platform == 'linux2':
    default_platform = 'linux'
  else:
    default_platform = None

  option_parser = optparse.OptionParser()

  option_parser.add_option('', '--testname',
                           default=None,
                           help='The test to run'
                                '[default: %default]')
  option_parser.add_option('', '--target',
                           default='debug',
                           help='build target (Debug, Release) '
                                '[default: %default]')
  option_parser.add_option('', '--arch',
                           default='ia32',
                           help='Architecture (ia32, x64, arm) '
                                '[default: ia32]')
  option_parser.add_option('', '--build-dir',
                           default='v8/obj',
                           metavar='DIR',
                           help='directory in which build was run '
                                '[default: %default]')
  option_parser.add_option('', '--platform',
                           default=default_platform,
                           help='specify platform [default: %%default]')
  option_parser.add_option('', '--shard_count',
                           default=1,
                           help='Specify shard count [default: %%default]')
  option_parser.add_option('', '--shard_run',
                           default=1,
                           help='Specify shard count [default: %%default]')
  option_parser.add_option('--shell_flags',
                           default=None,
                           help="Specify shell flags passed tools/test.py")
  option_parser.add_option('--isolates',
                           default=None,
                           help="Run isolates tests")

  options, args = option_parser.parse_args()
  if args:
    option_parser.error('Unsupported arguments: %s' % args)

  simultaneous = '-j8'
  if options.platform in ('win' 'arm'):
    simultaneous = '-j1'

  if options.testname == 'leak':
    cmd = ['python', 'tools/test.py', '--no-build', '--mode',
           'debug', '--progress', 'verbose', '--timeout', '180',
           '--time', '-Snapshot=on', '--special-command',
           '"@ --nopreallocate-message-memory"',
           '--valgrind', 'mjsunit/leakcheck',
           'mjsunit/regress/regress-1134697', 'mjsunit/number-tostring-small']
  elif options.testname == 'presubmit':
    cmd = ['python', 'tools/presubmit.py']
  else:
    cmd = ['python', 'tools/test.py',
           simultaneous,
           '--progress=verbose',
           '--no-build',
           '--arch=' + options.arch,
           '--mode=' + options.target]
    if options.testname:
      cmd.extend([options.testname])
    if options.testname == 'mozilla':
      # Mozilla tests requires a number of tests to timeout, set it a bit lower.
      cmd.extend(['--timeout=120'])
    elif options.arch == 'arm':
      cmd.extend(['--timeout=600'])
    else:
      cmd.extend(['--timeout=200'])
    if options.isolates:
      cmd.extend(['--isolates'])
    if options.shell_flags:
      cmd.extend(["--special-command", options.shell_flags.replace("\"", "")])

  if options.shard_count > 1:
    cmd.extend(['--shard-count', options.shard_count,
                '--shard-run', options.shard_run])

  return chromium_utils.RunCommand(cmd)

if __name__ == '__main__':
  sys.exit(main())
<|endoftext|>


<commit_before>import contextlib
import ntpath
import os
import posixpath
import shutil
import sys
import tempfile

PY3 = sys.version_info[0] == 3

if PY3:
    unicode = str
else:
    unicode = unicode
backend_types = (unicode, bytes)

def supports_unicode_filenames(lib):
    # Python is bugged; lib.supports_unicode_filenames is wrong
    return lib is ntpath

class AbstractPath(object):
    def _to_backend(self, p):
        """Converts something to the correct path representation.

        If given a Path, this will simply unpack it, if it's the correct type.
        If given the correct backend, it will return that.
        If given bytes for unicode of unicode for bytes, it will encode/decode
        with a reasonable encoding. Note that these operations can raise
        UnicodeError!
        """
        if isinstance(p, self._cmp_base):
            return p.path
        elif isinstance(p, self._backend):
            return p
        elif self._backend is unicode and isinstance(p, bytes):
            return p.decode(self._encoding)
        elif self._backend is bytes and isinstance(p, unicode):
            return p.encode(self._encoding,
                            'surrogateescape' if PY3 else 'strict')
        else:
            raise TypeError("Can't construct a %s from %r" % (
                            self.__class__.__name__, type(p)))

    def __init__(self, *parts):
        if self._lib is None:  # pragma: no cover
            raise RuntimeError("Can't create an AbstractPath directly!")
        self._backend = (unicode if supports_unicode_filenames(self._lib)
                         else bytes)
        self._sep = self._lib.sep
        if self._backend is unicode and isinstance(self._sep, bytes):
            self._sep = self._sep.decode('ascii')
        elif self._backend is bytes and isinstance(self._sep, unicode):
            self._sep = self._sep.encode('ascii')
        self.path = self._lib.normpath(
                self._lib.join(*[self._to_backend(p) for p in parts]))

    def __div__(self, other):
        return self.__class__(self, other)
    __truediv__ = __div__

    def __eq__(self, other):
        return (self._lib.normcase(self.path) ==
                self._lib.normcase(self._to_backend(other)))

    def __ne__(self, other):
        return not self.__eq__(other)

    def __hash__(self):
        return hash(self.path)

    def __repr__(self):
        if self._backend is unicode:
            s = repr(self.path)
            if PY3:
                s = s.encode('ascii', 'backslashreplace').decode('ascii')
            if s[0] != 'u':
                s = 'u' + s
        else:
            s = repr(self.path)
            if s[0] != 'b':
                s = 'b' + s
        # Returns WindowsPath(u'C:\\somedir') or PosixPath(b'/tmp')
        # It always puts the prefix (nobody uses Python 3.2 anyway)
        return '%s(%s)' % (self.__class__.__name__, s)

    def __bytes__(self):
        if self._backend is unicode:
            return self.path.encode(self._encoding, 'replace')
        else:
            return self.path

    def __unicode__(self):
        if self._backend is bytes:
            return self.path.decode(self._encoding, 'replace')
        else:
            return self.path

    if PY3:
        __str__ = __unicode__
    else:
        __str__ = __bytes__

    def expand_user(self):
        return self.__class__(self._lib.expanduser(self.path))

    def expand_vars(self):
        return self.__class__(self._lib.expandvars(self.path))

    @property
    def parent(self):
        p = self._lib.dirname(self.path)
        p = self.__class__(p)
        return p

    @property
    def name(self):
        return self._lib.basename(self.path)

    @property
    def unicodename(self):
        n = self._lib.basename(self.path)
        if self._backend is unicode:
            return n
        else:
            return n.decode(self._encoding, 'replace')

    @property
    def stem(self):
        return self._lib.splitext(self.name)[0]

    @property
    def ext(self):
        return self._lib.splitext(self.path)[1]

    def split_root(self):
        if not PY3 and hasattr(self._lib, 'splitunc'):
            root, rest = self._lib.splitunc(self.path)
            if root:
                if rest.startswith(self._sep):
                    root += self._sep
                    rest = rest[1:]
                return self.__class__(root), self.__class__(rest)
        root, rest = self._lib.splitdrive(self.path)
        if root:
            if rest.startswith(self._sep):
                root += self._sep
                rest = rest[1:]
            return self.__class__(root), self.__class__(rest)
        if self.path.startswith(self._sep):
            return self.__class__(self._sep), self.__class__(rest[1:])
        return self.__class__(''), self

    @property
    def root(self):
        return self.split_root()[0]

    @property
    def components(self):
        return [self.__class__(p) for p in self._components()]

    def _components(self):
        root, loc = self.split_root()
        if root.path != '.':
            components = [root.path]
        else:
            components = []
        if loc.path != self._to_backend('.'):
            components.extend(loc.path.split(self._sep))
        return components

    def ancestor(self, n):
        p = self
        for i in range(n):
            p = p.parent
        return p

    def norm_case(self):
        return self.__class__(self._lib.normcase(self.path))

    @property
    def is_absolute(self):
        return self.root.path != self._to_backend('.')

    def rel_path_to(self, dest):
        dest = self.__class__(dest)

        orig_list = self.norm_case()._components()
        dest_list = dest._components()

        for i, (orig_part, dest_part) in enumerate(zip(orig_list, dest_list)):
            if orig_part != self._lib.normcase(dest_part):
                up = ['..'] * (len(orig_list) - i)
                return self.__class__(*(up + dest_list[i:]))

        if len(orig_list) <= len(dest_list):
            if len(dest_list) > i + 1:
                return self.__class__(*dest_list[i + 1:])
            else:
                return self.__class__('')
        else:
            up = ['..'] * (len(orig_list) - i - 1)
            return self.__class__(*up)

    def relative(self):
        return self.cwd().rel_path_to(self)

class WindowsPath(AbstractPath):
    _lib = ntpath
    _encoding = 'windows-1252'
WindowsPath._cmp_base = WindowsPath

class PosixPath(AbstractPath):
    _lib = posixpath
    _encoding = 'utf-8'
PosixPath._cmp_base = PosixPath

DefaultAbstractPath = WindowsPath if os.name == 'nt' else PosixPath

class Path(DefaultAbstractPath):
    @property
    def _encoding(self):
        return sys.getfilesystemencoding()

    @classmethod
    def cwd(cls):
        return cls(os.getcwd())

    def chdir(self):
        os.chdir(self.path)

    @contextlib.contextmanager
    def in_dir(self):
        previous_dir = self.cwd()
        self.chdir()
        try:
            yield
        finally:
            previous_dir.chdir()

    @classmethod
    def tempfile(cls, suffix='', prefix=None, dir=None, text=False):
        if prefix is None:
            prefix = tempfile.template
        fd, filename = tempfile.mkstemp(suffix, prefix, dir, text)
        return fd, cls(filename).absolute()

    @classmethod
    def tempdir(cls, suffix='', prefix=None, dir=None):
        if prefix is None:
            prefix = tempfile.template
        dirname = tempfile.mkdtemp(suffix, prefix, dir)
        return cls(dirname).absolute()

    def absolute(self):
        return self.__class__(self._lib.abspath(self.path))

    def rel_path_to(self, dest):
        return self.absolute().rel_path_to(dest.absolute())

    def resolve(self):
        return self.__class__(self._lib.realpath(self.path))

    def listdir(self):
        return [self / self.__class__(p) for p in os.listdir(self.path)]

    def recursedir(self, top_down=True):
        return self._recursedir(top_down=top_down, seen=set())

    def _recursedir(self, top_down, seen):
        if not self.is_dir():
            raise ValueError("recursedir() called on non-directory %s" % self)
        real_dir = self.resolve()
        if real_dir in seen:
            return
        seen.add(real_dir)
        for child in self.listdir():
            is_dir = child.is_dir()
            if is_dir and not top_down:
                for grandkid in child._recursedir(top_down, seen):
                    yield grandkid
            yield child
            if is_dir and top_down:
                for grandkid in child._recursedir(top_down, seen):
                    yield grandkid

    def exists(self):
        return self._lib.exists(self.path)

    def lexists(self):
        return self._lib.lexists(self.path)

    def is_file(self):
        return self._lib.isfile(self.path)

    def is_dir(self):
        return self._lib.isdir(self.path)

    def is_link(self):
        return self._lib.islink(self.path)

    def is_mount(self):
        return self._lib.ismount(self.path)

    def atime(self):
        return self._lib.atime(self.path)

    def ctime(self):
        return self._lib.ctime(self.path)

    def mtime(self):
        return self._lib.mtime(self.path)

    def size(self):
        return self._lib.getsize(self.path)

    if hasattr(os.path, 'samefile'):
        def same_file(self, other):
            return self._lib.samefile(self.path, self._to_backend(other))

    def stat(self):
        return os.stat(self.path)

    def lstat(self):
        return os.lstat(self.path)

    if hasattr(os, 'statvfs'):
        def statvfs(self):
            return os.statvfs(self.path)

    if hasattr(os, 'chmod'):
        def chmod(self, mode):
            return os.chmod(self.path, mode)

    if hasattr(os, 'chown'):
        def chown(self, uid, gid):
            return os.chown(self.path, uid, gid)

    def mkdir(self, name=None, parents=False, mode=0o777):
        if name is not None:
            return (self / name).mkdir(parents=parents, mode=mode)
        if self.exists():
            return
        if parents:
            os.makedirs(self.path, mode)
        else:
            os.mkdir(self.path, mode)
        return self

    def rmdir(self, parents=False):
        if parents:
            os.removedirs(self.path)
        else:
            os.rmdir(self.path)

    def remove(self):
        os.remove(self.path)

    def rename(self, new, parents=False):
        if parents:
            os.renames(self.path, self._to_backend(new))
        else:
            os.rename(self.path, self._to_backend(new))

    if hasattr(os, 'link'):
        def hardlink(self, newpath):
            os.link(self.path, self._to_backend(newpath))

    if hasattr(os, 'symlink'):
        def symlink(self, target):
            os.symlink(self._to_backend(target), self.path)

    if hasattr(os, 'readlink'):
        def read_link(self, absolute=False):
            p = self.__class__(os.readlink(self))
            if absolute:
                return p.absolute()
            else:
                return p

    def copyfile(self, target):
        shutil.copyfile(self.path, self._to_backend(target))

    def copymode(self, target):
        shutil.copymode(self.path, self._to_backend(target))

    def copystat(self, target):
        shutil.copystat(self.path, self._to_backend(target))

    def copy(self, target):
        shutil.copy(self.path, self._to_backend(target))

    def copytree(self, target, symlinks=False):
        shutil.copytree(self.path, self._to_backend(target), symlinks)

    def rmtree(self, ignore_errors=False):
        shutil.rmtree(self.path, ignore_errors)

    def move(self, target):
        shutil.move(self.path, self._to_backend(target))

    def open(self, mode='r', name=None):
        if name is not None:
            return open((self / name).path, mode)
        else:
            return open(self.path, mode)
<commit_msg>Adds rpaths.__version__<commit_after>import contextlib
import ntpath
import os
import posixpath
import shutil
import sys
import tempfile

__version__ = '0.1'

PY3 = sys.version_info[0] == 3

if PY3:
    unicode = str
else:
    unicode = unicode
backend_types = (unicode, bytes)

def supports_unicode_filenames(lib):
    # Python is bugged; lib.supports_unicode_filenames is wrong
    return lib is ntpath

class AbstractPath(object):
    def _to_backend(self, p):
        """Converts something to the correct path representation.

        If given a Path, this will simply unpack it, if it's the correct type.
        If given the correct backend, it will return that.
        If given bytes for unicode of unicode for bytes, it will encode/decode
        with a reasonable encoding. Note that these operations can raise
        UnicodeError!
        """
        if isinstance(p, self._cmp_base):
            return p.path
        elif isinstance(p, self._backend):
            return p
        elif self._backend is unicode and isinstance(p, bytes):
            return p.decode(self._encoding)
        elif self._backend is bytes and isinstance(p, unicode):
            return p.encode(self._encoding,
                            'surrogateescape' if PY3 else 'strict')
        else:
            raise TypeError("Can't construct a %s from %r" % (
                            self.__class__.__name__, type(p)))

    def __init__(self, *parts):
        if self._lib is None:  # pragma: no cover
            raise RuntimeError("Can't create an AbstractPath directly!")
        self._backend = (unicode if supports_unicode_filenames(self._lib)
                         else bytes)
        self._sep = self._lib.sep
        if self._backend is unicode and isinstance(self._sep, bytes):
            self._sep = self._sep.decode('ascii')
        elif self._backend is bytes and isinstance(self._sep, unicode):
            self._sep = self._sep.encode('ascii')
        self.path = self._lib.normpath(
                self._lib.join(*[self._to_backend(p) for p in parts]))

    def __div__(self, other):
        return self.__class__(self, other)
    __truediv__ = __div__

    def __eq__(self, other):
        return (self._lib.normcase(self.path) ==
                self._lib.normcase(self._to_backend(other)))

    def __ne__(self, other):
        return not self.__eq__(other)

    def __hash__(self):
        return hash(self.path)

    def __repr__(self):
        if self._backend is unicode:
            s = repr(self.path)
            if PY3:
                s = s.encode('ascii', 'backslashreplace').decode('ascii')
            if s[0] != 'u':
                s = 'u' + s
        else:
            s = repr(self.path)
            if s[0] != 'b':
                s = 'b' + s
        # Returns WindowsPath(u'C:\\somedir') or PosixPath(b'/tmp')
        # It always puts the prefix (nobody uses Python 3.2 anyway)
        return '%s(%s)' % (self.__class__.__name__, s)

    def __bytes__(self):
        if self._backend is unicode:
            return self.path.encode(self._encoding, 'replace')
        else:
            return self.path

    def __unicode__(self):
        if self._backend is bytes:
            return self.path.decode(self._encoding, 'replace')
        else:
            return self.path

    if PY3:
        __str__ = __unicode__
    else:
        __str__ = __bytes__

    def expand_user(self):
        return self.__class__(self._lib.expanduser(self.path))

    def expand_vars(self):
        return self.__class__(self._lib.expandvars(self.path))

    @property
    def parent(self):
        p = self._lib.dirname(self.path)
        p = self.__class__(p)
        return p

    @property
    def name(self):
        return self._lib.basename(self.path)

    @property
    def unicodename(self):
        n = self._lib.basename(self.path)
        if self._backend is unicode:
            return n
        else:
            return n.decode(self._encoding, 'replace')

    @property
    def stem(self):
        return self._lib.splitext(self.name)[0]

    @property
    def ext(self):
        return self._lib.splitext(self.path)[1]

    def split_root(self):
        if not PY3 and hasattr(self._lib, 'splitunc'):
            root, rest = self._lib.splitunc(self.path)
            if root:
                if rest.startswith(self._sep):
                    root += self._sep
                    rest = rest[1:]
                return self.__class__(root), self.__class__(rest)
        root, rest = self._lib.splitdrive(self.path)
        if root:
            if rest.startswith(self._sep):
                root += self._sep
                rest = rest[1:]
            return self.__class__(root), self.__class__(rest)
        if self.path.startswith(self._sep):
            return self.__class__(self._sep), self.__class__(rest[1:])
        return self.__class__(''), self

    @property
    def root(self):
        return self.split_root()[0]

    @property
    def components(self):
        return [self.__class__(p) for p in self._components()]

    def _components(self):
        root, loc = self.split_root()
        if root.path != '.':
            components = [root.path]
        else:
            components = []
        if loc.path != self._to_backend('.'):
            components.extend(loc.path.split(self._sep))
        return components

    def ancestor(self, n):
        p = self
        for i in range(n):
            p = p.parent
        return p

    def norm_case(self):
        return self.__class__(self._lib.normcase(self.path))

    @property
    def is_absolute(self):
        return self.root.path != self._to_backend('.')

    def rel_path_to(self, dest):
        dest = self.__class__(dest)

        orig_list = self.norm_case()._components()
        dest_list = dest._components()

        for i, (orig_part, dest_part) in enumerate(zip(orig_list, dest_list)):
            if orig_part != self._lib.normcase(dest_part):
                up = ['..'] * (len(orig_list) - i)
                return self.__class__(*(up + dest_list[i:]))

        if len(orig_list) <= len(dest_list):
            if len(dest_list) > i + 1:
                return self.__class__(*dest_list[i + 1:])
            else:
                return self.__class__('')
        else:
            up = ['..'] * (len(orig_list) - i - 1)
            return self.__class__(*up)

    def relative(self):
        return self.cwd().rel_path_to(self)

class WindowsPath(AbstractPath):
    _lib = ntpath
    _encoding = 'windows-1252'
WindowsPath._cmp_base = WindowsPath

class PosixPath(AbstractPath):
    _lib = posixpath
    _encoding = 'utf-8'
PosixPath._cmp_base = PosixPath

DefaultAbstractPath = WindowsPath if os.name == 'nt' else PosixPath

class Path(DefaultAbstractPath):
    @property
    def _encoding(self):
        return sys.getfilesystemencoding()

    @classmethod
    def cwd(cls):
        return cls(os.getcwd())

    def chdir(self):
        os.chdir(self.path)

    @contextlib.contextmanager
    def in_dir(self):
        previous_dir = self.cwd()
        self.chdir()
        try:
            yield
        finally:
            previous_dir.chdir()

    @classmethod
    def tempfile(cls, suffix='', prefix=None, dir=None, text=False):
        if prefix is None:
            prefix = tempfile.template
        fd, filename = tempfile.mkstemp(suffix, prefix, dir, text)
        return fd, cls(filename).absolute()

    @classmethod
    def tempdir(cls, suffix='', prefix=None, dir=None):
        if prefix is None:
            prefix = tempfile.template
        dirname = tempfile.mkdtemp(suffix, prefix, dir)
        return cls(dirname).absolute()

    def absolute(self):
        return self.__class__(self._lib.abspath(self.path))

    def rel_path_to(self, dest):
        return self.absolute().rel_path_to(dest.absolute())

    def resolve(self):
        return self.__class__(self._lib.realpath(self.path))

    def listdir(self):
        return [self / self.__class__(p) for p in os.listdir(self.path)]

    def recursedir(self, top_down=True):
        return self._recursedir(top_down=top_down, seen=set())

    def _recursedir(self, top_down, seen):
        if not self.is_dir():
            raise ValueError("recursedir() called on non-directory %s" % self)
        real_dir = self.resolve()
        if real_dir in seen:
            return
        seen.add(real_dir)
        for child in self.listdir():
            is_dir = child.is_dir()
            if is_dir and not top_down:
                for grandkid in child._recursedir(top_down, seen):
                    yield grandkid
            yield child
            if is_dir and top_down:
                for grandkid in child._recursedir(top_down, seen):
                    yield grandkid

    def exists(self):
        return self._lib.exists(self.path)

    def lexists(self):
        return self._lib.lexists(self.path)

    def is_file(self):
        return self._lib.isfile(self.path)

    def is_dir(self):
        return self._lib.isdir(self.path)

    def is_link(self):
        return self._lib.islink(self.path)

    def is_mount(self):
        return self._lib.ismount(self.path)

    def atime(self):
        return self._lib.atime(self.path)

    def ctime(self):
        return self._lib.ctime(self.path)

    def mtime(self):
        return self._lib.mtime(self.path)

    def size(self):
        return self._lib.getsize(self.path)

    if hasattr(os.path, 'samefile'):
        def same_file(self, other):
            return self._lib.samefile(self.path, self._to_backend(other))

    def stat(self):
        return os.stat(self.path)

    def lstat(self):
        return os.lstat(self.path)

    if hasattr(os, 'statvfs'):
        def statvfs(self):
            return os.statvfs(self.path)

    if hasattr(os, 'chmod'):
        def chmod(self, mode):
            return os.chmod(self.path, mode)

    if hasattr(os, 'chown'):
        def chown(self, uid, gid):
            return os.chown(self.path, uid, gid)

    def mkdir(self, name=None, parents=False, mode=0o777):
        if name is not None:
            return (self / name).mkdir(parents=parents, mode=mode)
        if self.exists():
            return
        if parents:
            os.makedirs(self.path, mode)
        else:
            os.mkdir(self.path, mode)
        return self

    def rmdir(self, parents=False):
        if parents:
            os.removedirs(self.path)
        else:
            os.rmdir(self.path)

    def remove(self):
        os.remove(self.path)

    def rename(self, new, parents=False):
        if parents:
            os.renames(self.path, self._to_backend(new))
        else:
            os.rename(self.path, self._to_backend(new))

    if hasattr(os, 'link'):
        def hardlink(self, newpath):
            os.link(self.path, self._to_backend(newpath))

    if hasattr(os, 'symlink'):
        def symlink(self, target):
            os.symlink(self._to_backend(target), self.path)

    if hasattr(os, 'readlink'):
        def read_link(self, absolute=False):
            p = self.__class__(os.readlink(self))
            if absolute:
                return p.absolute()
            else:
                return p

    def copyfile(self, target):
        shutil.copyfile(self.path, self._to_backend(target))

    def copymode(self, target):
        shutil.copymode(self.path, self._to_backend(target))

    def copystat(self, target):
        shutil.copystat(self.path, self._to_backend(target))

    def copy(self, target):
        shutil.copy(self.path, self._to_backend(target))

    def copytree(self, target, symlinks=False):
        shutil.copytree(self.path, self._to_backend(target), symlinks)

    def rmtree(self, ignore_errors=False):
        shutil.rmtree(self.path, ignore_errors)

    def move(self, target):
        shutil.move(self.path, self._to_backend(target))

    def open(self, mode='r', name=None):
        if name is not None:
            return open((self / name).path, mode)
        else:
            return open(self.path, mode)
<|endoftext|>


<commit_before>"""Clickatell platform for notify component."""
import logging

import requests
import voluptuous as vol

from homeassistant.components.notify import PLATFORM_SCHEMA, BaseNotificationService
from homeassistant.const import CONF_API_KEY, CONF_RECIPIENT, HTTP_OK
import homeassistant.helpers.config_validation as cv

_LOGGER = logging.getLogger(__name__)

DEFAULT_NAME = "clickatell"

BASE_API_URL = "https://platform.clickatell.com/messages/http/send"

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
    {vol.Required(CONF_API_KEY): cv.string, vol.Required(CONF_RECIPIENT): cv.string}
)

def get_service(hass, config, discovery_info=None):
    """Get the Clickatell notification service."""
    return ClickatellNotificationService(config)

class ClickatellNotificationService(BaseNotificationService):
    """Implementation of a notification service for the Clickatell service."""

    def __init__(self, config):
        """Initialize the service."""
        self.api_key = config[CONF_API_KEY]
        self.recipient = config[CONF_RECIPIENT]

    def send_message(self, message="", **kwargs):
        """Send a message to a user."""
        data = {"apiKey": self.api_key, "to": self.recipient, "content": message}

        resp = requests.get(BASE_API_URL, params=data, timeout=5)
        if (resp.status_code != HTTP_OK) or (resp.status_code != 201):
            _LOGGER.error("Error %s : %s", resp.status_code, resp.text)
<commit_msg>Update notify.py (#38526)<commit_after>"""Clickatell platform for notify component."""
import logging

import requests
import voluptuous as vol

from homeassistant.components.notify import PLATFORM_SCHEMA, BaseNotificationService
from homeassistant.const import CONF_API_KEY, CONF_RECIPIENT, HTTP_OK
import homeassistant.helpers.config_validation as cv

_LOGGER = logging.getLogger(__name__)

DEFAULT_NAME = "clickatell"

BASE_API_URL = "https://platform.clickatell.com/messages/http/send"

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
    {vol.Required(CONF_API_KEY): cv.string, vol.Required(CONF_RECIPIENT): cv.string}
)

def get_service(hass, config, discovery_info=None):
    """Get the Clickatell notification service."""
    return ClickatellNotificationService(config)

class ClickatellNotificationService(BaseNotificationService):
    """Implementation of a notification service for the Clickatell service."""

    def __init__(self, config):
        """Initialize the service."""
        self.api_key = config[CONF_API_KEY]
        self.recipient = config[CONF_RECIPIENT]

    def send_message(self, message="", **kwargs):
        """Send a message to a user."""
        data = {"apiKey": self.api_key, "to": self.recipient, "content": message}

        resp = requests.get(BASE_API_URL, params=data, timeout=5)
        if (resp.status_code != HTTP_OK) or (resp.status_code != 202):
            _LOGGER.error("Error %s : %s", resp.status_code, resp.text)
<|endoftext|>