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

# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
"""
Tests For Compute
"""

import datetime

from nova import compute
from nova import context
from nova import db
from nova import exception
from nova import flags
from nova import log as logging
from nova import test
from nova import utils
from nova.auth import manager

LOG = logging.getLogger('nova.tests.compute')
FLAGS = flags.FLAGS
flags.DECLARE('stub_network', 'nova.compute.manager')

class ComputeTestCase(test.TestCase):
    """Test case for compute"""
    def setUp(self):
        super(ComputeTestCase, self).setUp()
        self.flags(connection_type='fake',
                   stub_network=True,
                   network_manager='nova.network.manager.FlatManager')
        self.compute = utils.import_object(FLAGS.compute_manager)
        self.compute_api = compute.API()
        self.manager = manager.AuthManager()
        self.user = self.manager.create_user('fake', 'fake', 'fake')
        self.project = self.manager.create_project('fake', 'fake', 'fake')
        self.context = context.RequestContext('fake', 'fake', False)

    def tearDown(self):
        self.manager.delete_user(self.user)
        self.manager.delete_project(self.project)
        super(ComputeTestCase, self).tearDown()

    def _create_instance(self):
        """Create a test instance"""
        inst = {}
        inst['image_id'] = 'ami-test'
        inst['reservation_id'] = 'r-fakeres'
        inst['launch_time'] = '10'
        inst['user_id'] = self.user.id
        inst['project_id'] = self.project.id
        inst['instance_type'] = 'm1.tiny'
        inst['mac_address'] = utils.generate_mac()
        inst['ami_launch_index'] = 0
        return db.instance_create(self.context, inst)['id']

    def _create_group(self):
        values = {'name': 'testgroup',
                  'description': 'testgroup',
                  'user_id': self.user.id,
                  'project_id': self.project.id}
        return db.security_group_create(self.context, values)

    def test_create_instance_defaults_display_name(self):
        """Verify that an instance cannot be created without a display_name."""
        cases = [dict(), dict(display_name=None)]
        for instance in cases:
            ref = self.compute_api.create(self.context,
                FLAGS.default_instance_type, None, **instance)
            try:
                self.assertNotEqual(ref[0]['display_name'], None)
            finally:
                db.instance_destroy(self.context, ref[0]['id'])

    def test_create_instance_associates_security_groups(self):
        """Make sure create associates security groups"""
        group = self._create_group()
        ref = self.compute_api.create(
                self.context,
                instance_type=FLAGS.default_instance_type,
                image_id=None,
                security_group=['testgroup'])
        try:
            self.assertEqual(len(db.security_group_get_by_instance(
                             self.context, ref[0]['id'])), 1)
            group = db.security_group_get(self.context, group['id'])
            self.assert_(len(group.instances) == 1)
        finally:
            db.security_group_destroy(self.context, group['id'])
            db.instance_destroy(self.context, ref[0]['id'])

    def test_destroy_instance_disassociates_security_groups(self):
        """Make sure destroying disassociates security groups"""
        group = self._create_group()

        ref = self.compute_api.create(
                self.context,
                instance_type=FLAGS.default_instance_type,
                image_id=None,
                security_group=['testgroup'])
        try:
            db.instance_destroy(self.context, ref[0]['id'])
            instance = db.instance_get(context.get_admin_context(
                                       read_deleted=True), ref[0]['id'])

            group = db.security_group_get(self.context, group['id'])
            self.assert_(len(group.instances) == 0)
        finally:
            db.security_group_destroy(self.context, group['id'])

    def test_destroy_security_group_disassociates_instances(self):
        """Make sure destroying security groups disassociates instances"""
        group = self._create_group()

        ref = self.compute_api.create(
                self.context,
                instance_type=FLAGS.default_instance_type,
                image_id=None,
                security_group=['testgroup'])

        try:
            db.security_group_destroy(self.context, group['id'])
            group = db.security_group_get(context.get_admin_context(
                                          read_deleted=True), group['id'])
            self.assert_(len(group.instances) == 0)
        finally:
            db.instance_destroy(self.context, ref[0]['id'])

    def test_run_terminate(self):
        """Make sure it is possible to  run and terminate instance"""
        instance_id = self._create_instance()

        self.compute.run_instance(self.context, instance_id)

        instances = db.instance_get_all(context.get_admin_context())
        LOG.info(_("Running instances: %s"), instances)
        self.assertEqual(len(instances), 1)

        self.compute.terminate_instance(self.context, instance_id)

        instances = db.instance_get_all(context.get_admin_context())
        LOG.info(_("After terminating instances: %s"), instances)
        self.assertEqual(len(instances), 0)

    def test_run_terminate_timestamps(self):
        """Make sure timestamps are set for launched and destroyed"""
        instance_id = self._create_instance()
        instance_ref = db.instance_get(self.context, instance_id)
        self.assertEqual(instance_ref['launched_at'], None)
        self.assertEqual(instance_ref['deleted_at'], None)
        launch = datetime.datetime.utcnow()
        self.compute.run_instance(self.context, instance_id)
        instance_ref = db.instance_get(self.context, instance_id)
        self.assert_(instance_ref['launched_at'] > launch)
        self.assertEqual(instance_ref['deleted_at'], None)
        terminate = datetime.datetime.utcnow()
        self.compute.terminate_instance(self.context, instance_id)
        self.context = self.context.elevated(True)
        instance_ref = db.instance_get(self.context, instance_id)
        self.assert_(instance_ref['launched_at'] < terminate)
        self.assert_(instance_ref['deleted_at'] > terminate)

    def test_pause(self):
        """Ensure instance can be paused"""
        instance_id = self._create_instance()
        self.compute.run_instance(self.context, instance_id)
        self.compute.pause_instance(self.context, instance_id)
        self.compute.unpause_instance(self.context, instance_id)
        self.compute.terminate_instance(self.context, instance_id)

    def test_suspend(self):
        """ensure instance can be suspended"""
        instance_id = self._create_instance()
        self.compute.run_instance(self.context, instance_id)
        self.compute.suspend_instance(self.context, instance_id)
        self.compute.resume_instance(self.context, instance_id)
        self.compute.terminate_instance(self.context, instance_id)

    def test_reboot(self):
        """Ensure instance can be rebooted"""
        instance_id = self._create_instance()
        self.compute.run_instance(self.context, instance_id)
        self.compute.reboot_instance(self.context, instance_id)
        self.compute.terminate_instance(self.context, instance_id)

    def test_set_admin_password(self):
        """Ensure instance can have its admin password set"""
        instance_id = self._create_instance()
        self.compute.run_instance(self.context, instance_id)
        self.compute.set_admin_password(self.context, instance_id)
        self.compute.terminate_instance(self.context, instance_id)

    def test_snapshot(self):
        """Ensure instance can be snapshotted"""
        instance_id = self._create_instance()
        name = "myfakesnapshot"
        self.compute.run_instance(self.context, instance_id)
        self.compute.snapshot_instance(self.context, instance_id, name)
        self.compute.terminate_instance(self.context, instance_id)

    def test_console_output(self):
        """Make sure we can get console output from instance"""
        instance_id = self._create_instance()
        self.compute.run_instance(self.context, instance_id)

        console = self.compute.get_console_output(self.context,
                                                        instance_id)
        self.assert_(console)
        self.compute.terminate_instance(self.context, instance_id)

    def test_ajax_console(self):
        """Make sure we can get console output from instance"""
        instance_id = self._create_instance()
        self.compute.run_instance(self.context, instance_id)

        console = self.compute.get_ajax_console(self.context,
                                                instance_id)
        self.assert_(console)
        self.compute.terminate_instance(self.context, instance_id)

    def test_run_instance_existing(self):
        """Ensure failure when running an instance that already exists"""
        instance_id = self._create_instance()
        self.compute.run_instance(self.context, instance_id)
        self.assertRaises(exception.Error,
                          self.compute.run_instance,
                          self.context,
                          instance_id)
        self.compute.terminate_instance(self.context, instance_id)

    def test_lock(self):
        """ensure locked instance cannot be changed"""
        instance_id = self._create_instance()
        self.compute.run_instance(self.context, instance_id)

        non_admin_context = context.RequestContext(None, None, False, False)

        # decorator should return False (fail) with locked nonadmin context
        self.compute.lock_instance(self.context, instance_id)
        ret_val = self.compute.reboot_instance(non_admin_context, instance_id)
        self.assertEqual(ret_val, False)

        # decorator should return None (success) with unlocked nonadmin context
        self.compute.unlock_instance(self.context, instance_id)
        ret_val = self.compute.reboot_instance(non_admin_context, instance_id)
        self.assertEqual(ret_val, None)

        self.compute.terminate_instance(self.context, instance_id)
<commit_msg>remove extraneous line<commit_after># vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
"""
Tests For Compute
"""

import datetime

from nova import compute
from nova import context
from nova import db
from nova import exception
from nova import flags
from nova import log as logging
from nova import test
from nova import utils
from nova.auth import manager

LOG = logging.getLogger('nova.tests.compute')
FLAGS = flags.FLAGS
flags.DECLARE('stub_network', 'nova.compute.manager')

class ComputeTestCase(test.TestCase):
    """Test case for compute"""
    def setUp(self):
        super(ComputeTestCase, self).setUp()
        self.flags(connection_type='fake',
                   stub_network=True,
                   network_manager='nova.network.manager.FlatManager')
        self.compute = utils.import_object(FLAGS.compute_manager)
        self.compute_api = compute.API()
        self.manager = manager.AuthManager()
        self.user = self.manager.create_user('fake', 'fake', 'fake')
        self.project = self.manager.create_project('fake', 'fake', 'fake')
        self.context = context.RequestContext('fake', 'fake', False)

    def tearDown(self):
        self.manager.delete_user(self.user)
        self.manager.delete_project(self.project)
        super(ComputeTestCase, self).tearDown()

    def _create_instance(self):
        """Create a test instance"""
        inst = {}
        inst['image_id'] = 'ami-test'
        inst['reservation_id'] = 'r-fakeres'
        inst['launch_time'] = '10'
        inst['user_id'] = self.user.id
        inst['project_id'] = self.project.id
        inst['instance_type'] = 'm1.tiny'
        inst['mac_address'] = utils.generate_mac()
        inst['ami_launch_index'] = 0
        return db.instance_create(self.context, inst)['id']

    def _create_group(self):
        values = {'name': 'testgroup',
                  'description': 'testgroup',
                  'user_id': self.user.id,
                  'project_id': self.project.id}
        return db.security_group_create(self.context, values)

    def test_create_instance_defaults_display_name(self):
        """Verify that an instance cannot be created without a display_name."""
        cases = [dict(), dict(display_name=None)]
        for instance in cases:
            ref = self.compute_api.create(self.context,
                FLAGS.default_instance_type, None, **instance)
            try:
                self.assertNotEqual(ref[0]['display_name'], None)
            finally:
                db.instance_destroy(self.context, ref[0]['id'])

    def test_create_instance_associates_security_groups(self):
        """Make sure create associates security groups"""
        group = self._create_group()
        ref = self.compute_api.create(
                self.context,
                instance_type=FLAGS.default_instance_type,
                image_id=None,
                security_group=['testgroup'])
        try:
            self.assertEqual(len(db.security_group_get_by_instance(
                             self.context, ref[0]['id'])), 1)
            group = db.security_group_get(self.context, group['id'])
            self.assert_(len(group.instances) == 1)
        finally:
            db.security_group_destroy(self.context, group['id'])
            db.instance_destroy(self.context, ref[0]['id'])

    def test_destroy_instance_disassociates_security_groups(self):
        """Make sure destroying disassociates security groups"""
        group = self._create_group()

        ref = self.compute_api.create(
                self.context,
                instance_type=FLAGS.default_instance_type,
                image_id=None,
                security_group=['testgroup'])
        try:
            db.instance_destroy(self.context, ref[0]['id'])
            group = db.security_group_get(self.context, group['id'])
            self.assert_(len(group.instances) == 0)
        finally:
            db.security_group_destroy(self.context, group['id'])

    def test_destroy_security_group_disassociates_instances(self):
        """Make sure destroying security groups disassociates instances"""
        group = self._create_group()

        ref = self.compute_api.create(
                self.context,
                instance_type=FLAGS.default_instance_type,
                image_id=None,
                security_group=['testgroup'])

        try:
            db.security_group_destroy(self.context, group['id'])
            group = db.security_group_get(context.get_admin_context(
                                          read_deleted=True), group['id'])
            self.assert_(len(group.instances) == 0)
        finally:
            db.instance_destroy(self.context, ref[0]['id'])

    def test_run_terminate(self):
        """Make sure it is possible to  run and terminate instance"""
        instance_id = self._create_instance()

        self.compute.run_instance(self.context, instance_id)

        instances = db.instance_get_all(context.get_admin_context())
        LOG.info(_("Running instances: %s"), instances)
        self.assertEqual(len(instances), 1)

        self.compute.terminate_instance(self.context, instance_id)

        instances = db.instance_get_all(context.get_admin_context())
        LOG.info(_("After terminating instances: %s"), instances)
        self.assertEqual(len(instances), 0)

    def test_run_terminate_timestamps(self):
        """Make sure timestamps are set for launched and destroyed"""
        instance_id = self._create_instance()
        instance_ref = db.instance_get(self.context, instance_id)
        self.assertEqual(instance_ref['launched_at'], None)
        self.assertEqual(instance_ref['deleted_at'], None)
        launch = datetime.datetime.utcnow()
        self.compute.run_instance(self.context, instance_id)
        instance_ref = db.instance_get(self.context, instance_id)
        self.assert_(instance_ref['launched_at'] > launch)
        self.assertEqual(instance_ref['deleted_at'], None)
        terminate = datetime.datetime.utcnow()
        self.compute.terminate_instance(self.context, instance_id)
        self.context = self.context.elevated(True)
        instance_ref = db.instance_get(self.context, instance_id)
        self.assert_(instance_ref['launched_at'] < terminate)
        self.assert_(instance_ref['deleted_at'] > terminate)

    def test_pause(self):
        """Ensure instance can be paused"""
        instance_id = self._create_instance()
        self.compute.run_instance(self.context, instance_id)
        self.compute.pause_instance(self.context, instance_id)
        self.compute.unpause_instance(self.context, instance_id)
        self.compute.terminate_instance(self.context, instance_id)

    def test_suspend(self):
        """ensure instance can be suspended"""
        instance_id = self._create_instance()
        self.compute.run_instance(self.context, instance_id)
        self.compute.suspend_instance(self.context, instance_id)
        self.compute.resume_instance(self.context, instance_id)
        self.compute.terminate_instance(self.context, instance_id)

    def test_reboot(self):
        """Ensure instance can be rebooted"""
        instance_id = self._create_instance()
        self.compute.run_instance(self.context, instance_id)
        self.compute.reboot_instance(self.context, instance_id)
        self.compute.terminate_instance(self.context, instance_id)

    def test_set_admin_password(self):
        """Ensure instance can have its admin password set"""
        instance_id = self._create_instance()
        self.compute.run_instance(self.context, instance_id)
        self.compute.set_admin_password(self.context, instance_id)
        self.compute.terminate_instance(self.context, instance_id)

    def test_snapshot(self):
        """Ensure instance can be snapshotted"""
        instance_id = self._create_instance()
        name = "myfakesnapshot"
        self.compute.run_instance(self.context, instance_id)
        self.compute.snapshot_instance(self.context, instance_id, name)
        self.compute.terminate_instance(self.context, instance_id)

    def test_console_output(self):
        """Make sure we can get console output from instance"""
        instance_id = self._create_instance()
        self.compute.run_instance(self.context, instance_id)

        console = self.compute.get_console_output(self.context,
                                                        instance_id)
        self.assert_(console)
        self.compute.terminate_instance(self.context, instance_id)

    def test_ajax_console(self):
        """Make sure we can get console output from instance"""
        instance_id = self._create_instance()
        self.compute.run_instance(self.context, instance_id)

        console = self.compute.get_ajax_console(self.context,
                                                instance_id)
        self.assert_(console)
        self.compute.terminate_instance(self.context, instance_id)

    def test_run_instance_existing(self):
        """Ensure failure when running an instance that already exists"""
        instance_id = self._create_instance()
        self.compute.run_instance(self.context, instance_id)
        self.assertRaises(exception.Error,
                          self.compute.run_instance,
                          self.context,
                          instance_id)
        self.compute.terminate_instance(self.context, instance_id)

    def test_lock(self):
        """ensure locked instance cannot be changed"""
        instance_id = self._create_instance()
        self.compute.run_instance(self.context, instance_id)

        non_admin_context = context.RequestContext(None, None, False, False)

        # decorator should return False (fail) with locked nonadmin context
        self.compute.lock_instance(self.context, instance_id)
        ret_val = self.compute.reboot_instance(non_admin_context, instance_id)
        self.assertEqual(ret_val, False)

        # decorator should return None (success) with unlocked nonadmin context
        self.compute.unlock_instance(self.context, instance_id)
        ret_val = self.compute.reboot_instance(non_admin_context, instance_id)
        self.assertEqual(ret_val, None)

        self.compute.terminate_instance(self.context, instance_id)
<|endoftext|>


<commit_before># See http://www.python.org/dev/peps/pep-0386/ for version numbering, especially NormalizedVersion
from distutils import version
version = version.LooseVersion('0.3.4-dev')<commit_msg>move the zookeeper contrib to 0.3.5-dev<commit_after># See http://www.python.org/dev/peps/pep-0386/ for version numbering, especially NormalizedVersion
from distutils import version
version = version.LooseVersion('0.3.5-dev')<|endoftext|>


<commit_before>__version__ = '0.27.3'
<commit_msg>Version -> 0.28<commit_after>__version__ = '0.28'
<|endoftext|>


<commit_before># --------------------------------------------------------------------------
# Copyright 2014 Digital Sapphire Development Team
#
# 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 __future__ import unicode_literals

import os

import pytest

from pyupdater.client import Client
from tconfig import TConfig

@pytest.mark.usefixtures("cleandir")
class TestClient(object):

    @pytest.fixture
    def client(self):
        t_config = TConfig()
        t_config.DATA_DIR = os.getcwd()
        client = Client(t_config, refresh=True, test=True)
        client.FROZEN = True
        return client

    def test_data_dir(self, client):
        assert os.path.exists(client.data_dir)

    def test_new_init(self, client):
        assert client.app_name == 'jms'
        assert client.update_urls[0] == ('https://s3-us-west-1.amazon'
                                         'aws.com/pyupdater-test/')

    def test_no_cert(self, client):
        client.verify = False
        assert client.app_name == 'jms'
        assert client.update_urls[0] == ('https://s3-us-west-1.amazon'
                                         'aws.com/pyupdater-test/')

    def test_bad_pub_key(self, client):
        t_config = TConfig()
        t_config.PUBLIC_KEYS = ['bad key']
        t_config.DATA_DIR = os.getcwd()
        client = Client(t_config, refresh=True, test=True)
        assert client.update_check('jms', '0.0.0') is None

    def test_check_version(self, client):
        assert client.update_check(client.app_name, '0.0.2') is not None
        assert client.update_check(client.app_name, '6.0.0') is None

    def test_failed_refresh_download(self, client):
        client = Client(None, refresh=True, test=True)
        client.data_dir = os.getcwd()
        assert client.ready is False

    def test_download_https(self, client):
        update = client.update_check(client.app_name, '0.0.1')
        assert update is not None
        assert update.app_name == 'jms'
        temp_name = update.name
        update.name = None
        assert update.is_downloaded() is False
        update.name = temp_name
        assert update.is_downloaded() is False
        assert update.download() is True
        assert update.is_downloaded() is True
        assert update.extract() is True

    def test_download_http(client):
        t_config = TConfig()
        t_config.DATA_DIR = os.getcwd()
        t_config.VERIFY_SERVER_CERT = False
        client = Client(t_config, refresh=True, test=True)
        update = client.update_check(client.app_name, '0.0.1')
        assert update is not None
        assert update.app_name == 'jms'
        assert update.download() is True
        assert update.is_downloaded() is True

    def test_extract(self, client):
        update = client.update_check('jms', '0.0.1')
        assert update is not None
        assert update.download() is True
        assert update.extract() is True
<commit_msg>Don't test methods no supported on windows<commit_after># --------------------------------------------------------------------------
# Copyright 2014 Digital Sapphire Development Team
#
# 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 __future__ import unicode_literals

import os

from jms_utils.system import get_system
import pytest

from pyupdater.client import Client
from tconfig import TConfig

@pytest.mark.usefixtures("cleandir")
class TestClient(object):

    @pytest.fixture
    def client(self):
        t_config = TConfig()
        t_config.DATA_DIR = os.getcwd()
        client = Client(t_config, refresh=True, test=True)
        client.FROZEN = True
        return client

    def test_data_dir(self, client):
        assert os.path.exists(client.data_dir)

    def test_new_init(self, client):
        assert client.app_name == 'jms'
        assert client.update_urls[0] == ('https://s3-us-west-1.amazon'
                                         'aws.com/pyupdater-test/')

    def test_no_cert(self, client):
        client.verify = False
        assert client.app_name == 'jms'
        assert client.update_urls[0] == ('https://s3-us-west-1.amazon'
                                         'aws.com/pyupdater-test/')

    def test_bad_pub_key(self, client):
        t_config = TConfig()
        t_config.PUBLIC_KEYS = ['bad key']
        t_config.DATA_DIR = os.getcwd()
        client = Client(t_config, refresh=True, test=True)
        assert client.update_check('jms', '0.0.0') is None

    def test_check_version(self, client):
        assert client.update_check(client.app_name, '0.0.2') is not None
        assert client.update_check(client.app_name, '6.0.0') is None

    def test_failed_refresh_download(self, client):
        client = Client(None, refresh=True, test=True)
        client.data_dir = os.getcwd()
        assert client.ready is False

    def test_download_https(self, client):
        update = client.update_check(client.app_name, '0.0.1')
        assert update is not None
        assert update.app_name == 'jms'
        temp_name = update.name
        update.name = None
        assert update.is_downloaded() is False
        update.name = temp_name
        assert update.is_downloaded() is False
        assert update.download() is True
        assert update.is_downloaded() is True
        if not get_system == 'win32':
            assert update.extract() is True

    def test_download_http(client):
        t_config = TConfig()
        t_config.DATA_DIR = os.getcwd()
        t_config.VERIFY_SERVER_CERT = False
        client = Client(t_config, refresh=True, test=True)
        update = client.update_check(client.app_name, '0.0.1')
        assert update is not None
        assert update.app_name == 'jms'
        assert update.download() is True
        assert update.is_downloaded() is True

    def test_extract(self, client):
        update = client.update_check('jms', '0.0.1')
        assert update is not None
        assert update.download() is True
        if not get_system == 'win32':
            assert update.extract() is True
<|endoftext|>


<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-
#-------------------------------------------------------------------------
#- PYOOML.  Python Object Oriented Mechanics Library
#-------------------------------------------------------------------------
#  (C)  Juan Gonzalez-Gomez (Obijuan)  March-2015
#  (C)  Alberto Valero
#--------------------------------------------------------------------------
#-  Released under de GPL v2 License
#---------------------------------------------------------------------------

import FreeCAD
import Part
import copy
import Draft

class part(object):
	"""Generic objects"""

	version = '0.1'

	def __init__(self):
		pass

	# overload +
	def __add__(self, other):
		"""Union operator"""

		#-- Return the union of the two objects
		return union([self, other])

	 #-- Overload - operator
	def __sub__(self, other):
		"""Difference operator"""
		return difference(self, other)

	def translate(self, x, y, z):
		"""Translate the object"""

		#-- Get the translation vector
		v = FreeCAD.Vector(x, y, z)

		#-- Apply the translation (relative to the current position)
		self.obj.Placement.Base += v

		return self

	#-- All subclases should implement the copy() method
	def copy(self):
		"""Return a copy of the object"""

		assert False, '[PYOOML] The object do NOT have a copy() method'
		return

	def clone(self):
		"""Returns a clone of the object"""
		duplicate = copy.copy(self)
		duplicate.obj = Draft.clone(self.obj)
		return duplicate

	def _vector_from_args(self, x, y, z):
		"""Utility function. It returns a vector with the x,y,z components"""

		#-- Function overloading. x is mandatory
		if y == None and z == None:
			#-- the first argument is an App.Vector
			v = x
		else:
			#-- The three components are given
			v = FreeCAD.Vector(x, y, z)

		#-- Return the vector
		return v

class union(part):
	"""Union of objects"""

	def __init__(self, items):
		"""items = list of parts to perform union"""

		#-- Call the parent class constructor first
		super(union, self).__init__()

		#-- Create the Freecad Object
		doc = FreeCAD.activeDocument()
		self.obj = doc.addObject("Part::MultiFuse","Union")

		#-- Save the list of parts
		self.childs = items

		#-- Do the union!
		l = [item.obj for item in self.childs]
		self.obj.Shapes = l

		doc.recompute()

	def __str__(self):
		str_id = "[{}] Union:\n".format(self.obj.Label)
		for child in self.childs:
			str_id += "{}".format(child)
		return str_id + '\n'

	def copy(self):
		"""Return a copy of the object"""

		#-- Copy the childs
		lc = [child.copy() for child in self.childs]

		#-- Create a new union
		u = union(lc)

		#-- Copy the placement
		u.obj.Placement = self.obj.Placement

		return u

class difference(part):
	"""Difference of two parts: base - tool"""

	def __init__(self, base, tool):
		"""Perform the difference of base - tool"""

		#-- Call the parent class constructor first
		super(difference, self).__init__()

		#-- Create the Freecad Object
		doc = FreeCAD.activeDocument()
		self.obj = doc.addObject("Part::Cut","Difference")

		#-- Store the childs
		self.op1 = base
		self.op2 = tool

		#-- Do the difference!
		self.obj.Base = self.op1.obj
		self.obj.Tool = self.op2.obj

		doc.recompute()

	def __str__(self):
		str_id = "[{}] Difference:\n".format(self.obj.Label)
		str_id += "{}".format(self.op1)
		str_id += "{}".format(self.op2)
		return str_id + '\n'

		doc.recompute()

	def copy(self):
		"""Return a copy of the object"""

		#-- Create the new difference
		d = difference(self.op1.copy(), self.op2.copy())

		#-- Copy the placement
		d.obj.Placement = self.obj.Placement

		return d

class cube(part):
	"""Primitive Object: a cube"""

	def __init__(self, lx, ly = None, lz = None, center = False):
		"""Create a primitive cube:
			lx: length in x axis
			ly: length in y axis
			lz: length in z axis"""

		#-- Call the parent class constructor first
		super(cube, self).__init__()

		v = self._vector_from_args(lx, ly, lz)

		#-- Create the Freecad Object
		self.obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Cube")

		#--Add property
		self.obj.addProperty("App::PropertyLength","lx","Cube","Length in x axis").lx = v.x
		self.obj.addProperty("App::PropertyLength","ly","Cube","Length in y axis").ly = v.y
		self.obj.addProperty("App::PropertyLength","lz","Cube","Length in z axis").lz = v.z

		#-- Set the pos
		if center == True:
			self.obj.Placement.Base = FreeCAD.Vector(-v.x / 2., -v.y / 2., -v.z / 2.)

		#-- Configure the object for working ok in the Freecad environment
		self.obj.Proxy = self
		self.obj.ViewObject.Proxy = self

		#-- Show the object!
		FreeCAD.ActiveDocument.recompute()

	def __str__(self):
		str_id = "[{}] cube({}, {}, {})\n".format(self.obj.Label, self.obj.lx,
											 	    self.obj.ly, self.obj.lz)
		return str_id

	def copy(self):
		"""Return a copy of the object"""

		#-- Create a new cube
		c = cube(self.lx, self.ly, self.lz)

		#-- Set the same placement
		c.obj.Placement = self.obj.Placement
		return c

	@property
	def lx(self):
		"""Object length in x axis"""
		return self.obj.lx

	@lx.setter
	def lx(self, value):
		"""Attribute: Set the length in x axis"""
		self.obj.lx = value
		FreeCAD.ActiveDocument.recompute()

	@property
	def ly(self):
		"""Object length in y axis"""
		return self.obj.ly

	@ly.setter
	def ly(self, value):
		"""Attribute: Set the length in y axis"""
		self.obj.ly = value
		FreeCAD.ActiveDocument.recompute()

	@property
	def lz(self):
		"""Object length in z axis"""
		return self.obj.lz

	@lz.setter
	def lz(self, value):
		"""Attribute: Set the length in z axis"""
		self.obj.lz = value
		FreeCAD.ActiveDocument.recompute()

	def execute(self, obj):
		"""Build the object"""

		obj.Shape = Part.makeBox(obj.lx, obj.ly, obj.lz)

	def getDefaultDisplayMode(self):
		"""VIEWPROVIDER..."""
		#print("getDefaultDisplayMode")
		return "Flat Lines"

def test_cube1():
	#-- Place a single cube
	cube()

	#-- Place a translated cube
	cube().translate(10, 10, 10)

def test_L():
	c1 = cube(40, 10, 10)
	c2 = cube(10, 40, 10)
	l = c1 + c2

def test_cross():
	c1 = cube(40, 10, 10, center = True)
	c2 = cube(10, 40, 10, center = True)
	cross = c1 + c2

def test_cross2():
	s1 = FreeCAD.Vector(40, 10, 10)
	s2 = FreeCAD.Vector(10, 40, 10)
	cross = cube(s1, center = True) + cube(s2, center = True)

	#-- Base
	b = s1 + s2
	base = cube(b, center = True).translate(0, 0, -b.z/2)

	final_part = base + cross

def test_multiple_unions_1():
	v = FreeCAD.Vector(10, 10, 10)
	c1 = cube(v)
	c2 = cube(v).translate(v.x, 0, 0)
	c3 = cube(v).translate(2 * v.x, 0, 0)
	c4 = cube(v).translate(3 * v.x, 0, 0)
	part = c1 + c2 + c3 + c4

def test_multiple_unions_2():
	v = FreeCAD.Vector(10, 10, 10)
	l = [cube(v).translate(i * v.x, i, 0) for i in range(10) ]
	part = union(l)

def test_stairs():
	v = FreeCAD.Vector(10, 40, 4)
	l = [cube(v.x, v.y, v.z * i).translate(i * v.x, 0, 0) for i in range(1,10)]
	union(l)

def test_stairs_2D():
	v = FreeCAD.Vector(100, 100, 4)
	l = [cube(v.x - 10*i, v.y - 10*i, v.z).translate(0, 0, v.z * i) for i in range(10)]
	union(l)

import math

def cube_sine_1():
	v = FreeCAD.Vector(10, 80, 10)
	A = 20
	N = 20
	k = 2
	z0 = 10
	phi_ini = math.pi / 2
	l = [cube(v.x, v.y, A * math.sin(2 * math.pi * i / N - phi_ini) + A + z0).translate(v.x * i, 0, 0) for i in range(k * N)]
	union(l)

def cube_sine_2():
	v = FreeCAD.Vector(5, 5, 5)
	A = 10
	N = 10
	k = 1
	z0 = 5
	phi_ini = math.pi / 2
	z = [A * math.sin(2 * math.pi * i / N - phi_ini) + A + z0 for i in range(k * N)]
	l = [cube(v.x, v.y, zx + zy).translate(v.x * i, v.y * j, 0)
          for i, zx in enumerate(z) for j, zy in enumerate(z)]
	part = union(l)
	return part

def cube_sine_3():
	p1 = cube_sine_2()
	c =cube(50, 50, 50)
	c.translate(0,0,10)
	p2 = c - p1

def test_difference_1():
	c1 = cube(30, 30, 2, center = True)
	c2 = cube(5,5,20, center = True)
	d = c1 - c2

def test_difference_2():
	w = 10
	h = 3
	d1 = 10
	d2 = 3
	N = 2
	length = d1 * N
	base = cube(length, w, h, center = True)
	hole1 = cube(d2, d2, 3*h, center = True).translate(-length/2 + d1/2, 0, 0)
	hole2 = cube(d2, d2, 3*h, center = True).translate(-length/2 + d1/2 + d1, 0, 0)
	part = base - hole1 - hole2

def test_cube_copy():
	#-- The two cubes are equal
	c1 = cube(10, 20, 30)
	c2 = c1.copy()

	#-- Translate the copy. It should not affect cube 1
	c2.translate(20, 0, 0)

	#-- Change cube 1. It should NOT affect cube 2
	c1.lx = 5

	#-- Change cube 2. It should NOT affect cube 1
	c2.lx = 20

def test_difference_copy():
	#-- Create an object using differences
	c1 = cube(30, 30, 2, center = True)
	c2 = cube(5,5,20, center = True)
	d1 = c1 - c2

	#-- Copy the object
	d2 = d1.copy()

	#-- Translate the copy
	d2.translate(50, 0, 0)

	#-- Change the inner part of the first object
	c2.lx = 10

def test_difference_3():
	"""Test the difference  a - (b + c +d)"""
	base = cube(40,40,3, center = True)
	drill1 = cube(3,3,10, center = True)
	drill2 = drill1.copy().translate(-10,0,0)
	drill3 = drill1.copy().translate(10,0,0)
	drills = drill1 + drill2 + drill3

	mypart = base - drills

if __name__ == "__main__":
	#test_cube1()
	#test_L()
	#test_cross()
	#test_cross2()
	#test_multiple_unions_1()
	#test_multiple_unions_2()
	#test_stairs()
	#test_stairs_2D()
	#cube_sine_1()
	#cube_sine_2()
	#cube_sine_3()
	#test_difference_1()
	#test_difference_2()
	#test_cube_copy()
	test_difference_3()

<commit_msg>New copy method<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-
#-------------------------------------------------------------------------
#- PYOOML.  Python Object Oriented Mechanics Library
#-------------------------------------------------------------------------
#  (C)  Juan Gonzalez-Gomez (Obijuan)  March-2015
#  (C)  Alberto Valero
#--------------------------------------------------------------------------
#-  Released under de GPL v2 License
#---------------------------------------------------------------------------

import FreeCAD
import Part
import copy
import Draft

class part(object):
	"""Generic objects"""

	version = '0.1'

	def __init__(self):
		pass

	# overload +
	def __add__(self, other):
		"""Union operator"""

		#-- Return the union of the two objects
		return union([self, other])

	 #-- Overload - operator
	def __sub__(self, other):
		"""Difference operator"""
		return difference(self, other)

	def translate(self, x, y, z):
		"""Translate the object"""

		#-- Get the translation vector
		v = FreeCAD.Vector(x, y, z)

		#-- Apply the translation (relative to the current position)
		self.obj.Placement.Base += v

		return self

	def copy(self):
		"""Return a copy of the object"""

		c = copy.copy(self)
		c.obj = FreeCAD.ActiveDocument.copyObject(self.obj)
		return c

	def clone(self):
		"""Returns a clone of the object"""
		duplicate = copy.copy(self)
		duplicate.obj = Draft.clone(self.obj)
		return duplicate

	def _vector_from_args(self, x, y, z):
		"""Utility function. It returns a vector with the x,y,z components"""

		#-- Function overloading. x is mandatory
		if y == None and z == None:
			#-- the first argument is an App.Vector
			v = x
		else:
			#-- The three components are given
			v = FreeCAD.Vector(x, y, z)

		#-- Return the vector
		return v

class union(part):
	"""Union of objects"""

	def __init__(self, items):
		"""items = list of parts to perform union"""

		#-- Call the parent class constructor first
		super(union, self).__init__()

		#-- Create the Freecad Object
		doc = FreeCAD.activeDocument()
		self.obj = doc.addObject("Part::MultiFuse","Union")

		#-- Save the list of parts
		self.childs = items

		#-- Do the union!
		l = [item.obj for item in self.childs]
		self.obj.Shapes = l

		doc.recompute()

	def __str__(self):
		str_id = "[{}] Union:\n".format(self.obj.Label)
		for child in self.childs:
			str_id += "{}".format(child)
		return str_id + '\n'

	def copy(self):
		"""Return a copy of the object"""

		#-- Create a new union
		lc = [child.copy() for child in self.childs]
		u = union(lc)

		#-- Copy the placement
		u.obj.Placement = self.obj.Placement

		FreeCAD.activeDocument().recompute()

		return u

class difference(part):
	"""Difference of two parts: base - tool"""

	def __init__(self, base, tool):
		"""Perform the difference of base - tool"""

		#-- Call the parent class constructor first
		super(difference, self).__init__()

		#-- Create the Freecad Object
		doc = FreeCAD.activeDocument()
		self.obj = doc.addObject("Part::Cut","Difference")

		#-- Store the childs
		self.op1 = base
		self.op2 = tool

		#-- Do the difference!
		self.obj.Base = self.op1.obj
		self.obj.Tool = self.op2.obj

		doc.recompute()

	def __str__(self):
		str_id = "[{}] Difference:\n".format(self.obj.Label)
		str_id += "{}".format(self.op1)
		str_id += "{}".format(self.op2)
		return str_id + '\n'

		doc.recompute()

	def copy(self):
		"""Return a copy of the object"""

		#-- Create the new difference
		d = difference(self.op1.copy(), self.op2.copy())

		#-- Copy the placement
		d.obj.Placement = self.obj.Placement

		return d

class cube(part):
	"""Primitive Object: a cube"""

	def __init__(self, lx, ly = None, lz = None, center = False):
		"""Create a primitive cube:
			lx: length in x axis
			ly: length in y axis
			lz: length in z axis"""

		#-- Call the parent class constructor first
		super(cube, self).__init__()

		v = self._vector_from_args(lx, ly, lz)

		#-- Create the Freecad Object
		self.obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Cube")

		#--Add property
		self.obj.addProperty("App::PropertyLength","lx","Cube","Length in x axis").lx = v.x
		self.obj.addProperty("App::PropertyLength","ly","Cube","Length in y axis").ly = v.y
		self.obj.addProperty("App::PropertyLength","lz","Cube","Length in z axis").lz = v.z

		#-- Set the pos
		if center == True:
			self.obj.Placement.Base = FreeCAD.Vector(-v.x / 2., -v.y / 2., -v.z / 2.)

		#-- Configure the object for working ok in the Freecad environment
		self.obj.Proxy = self
		self.obj.ViewObject.Proxy = self

		#-- Show the object!
		FreeCAD.ActiveDocument.recompute()

	def __str__(self):
		str_id = "[{}] cube({}, {}, {})\n".format(self.obj.Label, self.obj.lx,
											 	    self.obj.ly, self.obj.lz)
		return str_id

	@property
	def lx(self):
		"""Object length in x axis"""
		return self.obj.lx

	@lx.setter
	def lx(self, value):
		"""Attribute: Set the length in x axis"""
		self.obj.lx = value
		FreeCAD.ActiveDocument.recompute()

	@property
	def ly(self):
		"""Object length in y axis"""
		return self.obj.ly

	@ly.setter
	def ly(self, value):
		"""Attribute: Set the length in y axis"""
		self.obj.ly = value
		FreeCAD.ActiveDocument.recompute()

	@property
	def lz(self):
		"""Object length in z axis"""
		return self.obj.lz

	@lz.setter
	def lz(self, value):
		"""Attribute: Set the length in z axis"""
		self.obj.lz = value
		FreeCAD.ActiveDocument.recompute()

	def execute(self, obj):
		"""Build the object"""

		obj.Shape = Part.makeBox(obj.lx, obj.ly, obj.lz)

	def getDefaultDisplayMode(self):
		"""VIEWPROVIDER..."""
		#print("getDefaultDisplayMode")
		return "Flat Lines"

def test_cube1():
	#-- Place a single cube
	cube()

	#-- Place a translated cube
	cube().translate(10, 10, 10)

def test_L():
	c1 = cube(40, 10, 10)
	c2 = cube(10, 40, 10)
	l = c1 + c2

def test_cross():
	c1 = cube(40, 10, 10, center = True)
	c2 = cube(10, 40, 10, center = True)
	cross = c1 + c2

def test_cross2():
	s1 = FreeCAD.Vector(40, 10, 10)
	s2 = FreeCAD.Vector(10, 40, 10)
	cross = cube(s1, center = True) + cube(s2, center = True)

	#-- Base
	b = s1 + s2
	base = cube(b, center = True).translate(0, 0, -b.z/2)

	final_part = base + cross

def test_multiple_unions_1():
	v = FreeCAD.Vector(10, 10, 10)
	c1 = cube(v)
	c2 = cube(v).translate(v.x, 0, 0)
	c3 = cube(v).translate(2 * v.x, 0, 0)
	c4 = cube(v).translate(3 * v.x, 0, 0)
	part = c1 + c2 + c3 + c4

def test_multiple_unions_2():
	v = FreeCAD.Vector(10, 10, 10)
	l = [cube(v).translate(i * v.x, i, 0) for i in range(10) ]
	part = union(l)

def test_stairs():
	v = FreeCAD.Vector(10, 40, 4)
	l = [cube(v.x, v.y, v.z * i).translate(i * v.x, 0, 0) for i in range(1,10)]
	union(l)

def test_stairs_2D():
	v = FreeCAD.Vector(100, 100, 4)
	l = [cube(v.x - 10*i, v.y - 10*i, v.z).translate(0, 0, v.z * i) for i in range(10)]
	union(l)

import math

def cube_sine_1():
	v = FreeCAD.Vector(10, 80, 10)
	A = 20
	N = 20
	k = 2
	z0 = 10
	phi_ini = math.pi / 2
	l = [cube(v.x, v.y, A * math.sin(2 * math.pi * i / N - phi_ini) + A + z0).translate(v.x * i, 0, 0) for i in range(k * N)]
	union(l)

def cube_sine_2():
	v = FreeCAD.Vector(5, 5, 5)
	A = 10
	N = 10
	k = 1
	z0 = 5
	phi_ini = math.pi / 2
	z = [A * math.sin(2 * math.pi * i / N - phi_ini) + A + z0 for i in range(k * N)]
	l = [cube(v.x, v.y, zx + zy).translate(v.x * i, v.y * j, 0)
          for i, zx in enumerate(z) for j, zy in enumerate(z)]
	part = union(l)
	return part

def cube_sine_3():
	p1 = cube_sine_2()
	c =cube(50, 50, 50)
	c.translate(0,0,10)
	p2 = c - p1

def test_difference_1():
	c1 = cube(30, 30, 2, center = True)
	c2 = cube(5,5,20, center = True)
	d = c1 - c2

def test_difference_2():
	w = 10
	h = 3
	d1 = 10
	d2 = 3
	N = 2
	length = d1 * N
	base = cube(length, w, h, center = True)
	hole1 = cube(d2, d2, 3*h, center = True).translate(-length/2 + d1/2, 0, 0)
	hole2 = cube(d2, d2, 3*h, center = True).translate(-length/2 + d1/2 + d1, 0, 0)
	part = base - hole1 - hole2

def test_cube_copy():
	#-- The two cubes are equal
	c1 = cube(10, 20, 30)
	c2 = c1.copy()

	#-- Translate the copy. It should not affect cube 1
	c2.translate(20, 0, 0)

	#-- Change cube 1. It should NOT affect cube 2
	c1.lx = 5

	#-- Change cube 2. It should NOT affect cube 1
	c2.lx = 20

def test_difference_copy():
	#-- Create an object using differences
	c1 = cube(30, 30, 2, center = True)
	c2 = cube(5,5,20, center = True)
	d1 = c1 - c2

	#-- Copy the object
	d2 = d1.copy()

	#-- Translate the copy
	d2.translate(50, 0, 0)

	#-- Change the inner part of the first object
	c2.lx = 10

def test_difference_3():
	"""Test the difference  a - (b + c +d)"""
	base = cube(40,40,3, center = True)
	drill1 = cube(3,3,10, center = True)
	drill2 = drill1.copy().translate(-10,0,0)
	drill3 = drill1.copy().translate(10,0,0)
	drills = drill1 + drill2 + drill3

	mypart = base - drills

def test_union_copy():
	c1 = cube(10,10,10)
	c2 = cube(10,10,10).translate(10,0,0)
	u1 = (c1 + c2).translate(30,0,0)

	u2 = u1.copy()
	u2.translate(30, 0, 0)
	c1.ly = 20

if __name__ == "__main__":
	#test_cube1()
	#test_L()
	#test_cross()
	#test_cross2()
	#test_multiple_unions_1()
	#test_multiple_unions_2()
	#test_stairs()
	#test_stairs_2D()
	#cube_sine_1()
	#cube_sine_2()
	#cube_sine_3()
	#test_difference_1()
	#test_difference_2()
	#test_cube_copy()
	test_difference_3()
	#test_union_copy()

<|endoftext|>


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

{
    "name": "operation_time_control",
    "version": "1.0",
    "depends": ["base", "mrp"],
    "author": "OdooMRP team",
    "contributors": ["Mikel Arregi <mikelarregi@avanzosc.es>"],
    "category": "mrp",
    "description": """
    Manufacturing operations time control
    """,
    'data': ["views/operation_time_view.xml"],
    "installable": True,
    "auto_install": False,
}
<commit_msg>[MOD] module name changed<commit_after>
# -*- encoding: utf-8 -*-
##############################################################################
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see http://www.gnu.org/licenses/.
#
##############################################################################

{
    "name": "mrp_operations_time_control",
    "version": "1.0",
    "depends": ["base", "mrp"],
    "author": "OdooMRP team",
    "contributors": ["Mikel Arregi <mikelarregi@avanzosc.es>"],
    "category": "mrp",
    "description": """
    Manufacturing operations time control
    """,
    'data': ["views/operation_time_view.xml"],
    "installable": True,
    "auto_install": False,
}
<|endoftext|>


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

import os
import re
import urllib
from datetime import datetime
from django.core.files import File

from basecollector import BaseCollector
from montanha.models import *

def parse_money(string):
    string = string.replace('.', '')
    string = string.replace(',', '.')
    return float(string)

def parse_date(string):
    return datetime.strptime(string, '%d/%m/%Y').date()

def parse_cmsp_date(month, year):
    day = '01'
    return parse_date(day + '/' + month + '/' + year)

class CMSP(BaseCollector):
    def __init__(self, collection_runs, debug_enabled=False):
        super(CMSP, self).__init__(collection_runs, debug_enabled)

        institution, institution_created = Institution.objects.get_or_create(
            siglum='CMSP',
            name=u'Câmara Municipal de São Paulo')

        self.institution = institution

    def _normalize_party_siglum(self, siglum):
        names_map = {
            'DEMOCRATAS': 'DEM',
        }
        return names_map.get(siglum, siglum)

    def retrieve_expenses(self, month, year):
        uri = 'http://www.camara.sp.gov.br/wp-content/uploads/transparencia/saeg/%s%s.XML' % (year, month)
        return BaseCollector.retrieve_uri(self, uri, force_encoding='utf-8')

    def retrieve_legislators(self):
        uri = 'http://www1.camara.sp.gov.br/vereadores_joomla.asp'
        return BaseCollector.retrieve_uri(self, uri)

    def retrieve_legislator(self, link):
        uri = 'http://www1.camara.sp.gov.br/%s' % link
        return BaseCollector.retrieve_uri(self, uri)

    def add_legislator(self, name):
        legislator, created = Legislator.objects.get_or_create(name=name)

        if created:
            self.debug(u'New legislator found: %s' % legislator)
        else:
            self.debug(u'Found existing legislator: %s' % legislator)

        return legislator

    def process_legislators(self, legislature):
        legislators = self.retrieve_legislators()
        if not legislators:
            return

        links = legislators.findAll(
            'a',
            href=re.compile('^vereador_joomla2.asp\?vereador='))

        for link in links:
            href = link.get('href')
            html_legislator = self.retrieve_legislator(href)
            if not html_legislator:
                continue

            url, code = href.split('=', 1)
            name = html_legislator.find(id='nome_vereador').getText()

            legislator = self.add_legislator(name)

            legislator_img = html_legislator.find(
                'img',
                src=re.compile('imgs/fotos/'))

            if legislator_img:
                legislator_img_src = legislator_img.get('src')

                legislator_img_url = 'http://www1.camara.sp.gov.br/%s' % (
                    legislator_img_src)

                result = urllib.urlretrieve(legislator_img_url)

                legislator.picture.save(
                    os.path.basename(legislator_img_url), File(open(result[0])))

                legislator.save()

                self.debug('Updating legislator picture.')

            try:
                mandate = Mandate.objects.get(
                    legislator=legislator,
                    date_start=legislature.date_start,
                    legislature=legislature)
                self.debug(u'Found existing Mandate: %s' % mandate)
            except Mandate.DoesNotExist:
                mandate = Mandate(
                    legislator=legislator,
                    date_start=legislature.date_start,
                    legislature=legislature)
                mandate.save()
                self.debug(u'New Mandate found: %s' % mandate)

            party_name = html_legislator.find(
                'img',
                src=re.compile('imgs/Partidos'))

            party_name = party_name.parent.parent.find('font', size='2')
            party_name = party_name.getText()
            party_siglum = party_name[party_name.find('(')+1:party_name.find(')')]

            if 'Vereadores Licenciados' not in party_siglum:
                party_siglum = self._normalize_party_siglum(party_siglum)
                party, party_created = PoliticalParty.objects.get_or_create(
                    siglum=party_siglum)

                mandate.party = party
                mandate.save()
                self.debug('Updating legislator party: %s' % party_siglum)

    def process_expenses(self, month, year, legislature, collection_run):
        data = self.retrieve_expenses(month, year)
        if not data:
            return

        for x in data.findAll('g_deputado'):
            name = x.find('nm_deputado').getText().capitalize()
            legislator = self.add_legislator(name)

            try:
                mandate = Mandate.objects.get(
                    legislator=legislator,
                    date_start=legislature.date_start,
                    legislature=legislature)
                self.debug(u'Found existing Mandate: %s' % mandate)
            except Mandate.DoesNotExist:
                mandate = Mandate(
                    legislator=legislator,
                    date_start=legislature.date_start,
                    legislature=legislature)
                mandate.save()
                self.debug(u'New Mandate found: %s' % mandate)

            expense_type = x.find('list_g_tipo_despesa')

            for i in expense_type.findAll('g_tipo_despesa'):
                nature_text = i.find('nm_tipo_despesa').getText()
                try:
                    nature_text = nature_text.split('-', 1)[1].strip()
                except IndexError:
                    pass

                nature_text = nature_text.capitalize()

                ignore_list = [u'total', u'TOTAL', u'utilizado até 30/11/07']
                ignore_matches = [s for s in ignore_list if s in nature_text]
                if ignore_matches:
                    continue

                nature, nature_created = ExpenseNature.objects.get_or_create(
                    name=nature_text)

                if nature_created:
                    self.debug(u'New ExpenseNature found: %s' % nature)
                else:
                    self.debug(u'Found existing ExpenseNature: %s' % nature)

                m_month = i.find('nr_mes_ref').getText()
                m_year = i.find('nr_ano_ref').getText()
                date = parse_cmsp_date(m_month, m_year)

                for j in i.findAll('g_beneficiario'):
                    supplier_name = j.find('nm_beneficiario').getText()
                    supplier_name = supplier_name.capitalize()
                    cnpj = self.normalize_cnpj_or_cpf(j.find('nr_cnpj').getText())

                    if not cnpj and not supplier_name:
                        continue

                    try:
                        supplier = Supplier.objects.get(identifier=cnpj)
                        supplier_created = False
                    except Supplier.DoesNotExist:
                        supplier = Supplier(identifier=cnpj, name=supplier_name)
                        supplier.save()
                        supplier_created = True

                    if supplier_created:
                        self.debug(u'New Supplier found: %s' % supplier)
                    else:
                        self.debug(u'Found existing supplier: %s' % supplier)

                    expensed = parse_money(j.find('vl_desp').getText())

                    expense = ArchivedExpense(number='None',
                                              nature=nature,
                                              date=date,
                                              expensed=expensed,
                                              mandate=mandate,
                                              supplier=supplier,
                                              collection_run=collection_run)
                    expense.save()

                    self.debug(u'New expense found: %s' % expense)

    def get_legislature(self, year):
        start_year = end_year = year

        if year >= 2013 and year <= 2016:
            start_year = 2013
            end_year = 2016

        if year >= 2009 and year <= 2012:
            start_year = 2009
            end_year = 2012

        if year >= 2005 and year <= 2008:
            start_year = 2005
            end_year = 2008

        legislature, created = Legislature.objects.get_or_create(
            institution=self.institution,
            date_start=datetime(start_year, 1, 1),
            date_end=datetime(end_year, 12, 31))

        if created:
            self.debug(u'New Legislature found: %s' % legislature)
        else:
            self.debug(u'Found existing legislature: %s' % legislature)

        return legislature

    def process_all_expenses(self):
        for year in xrange(2013, 2017):
            legislature = self.get_legislature(year)
            collection_run = self.create_collection_run(legislature)
            for m in xrange(1, 13):
                month = '%02d' % m
                self.debug('Adding expenses from %s/%s' % (month, year))
                self.process_expenses(month, year, legislature, collection_run)

    def process_current_legislators(self):
        current_legislature = self.get_legislature(2013)
        self.process_legislators(current_legislature)

    def process_all_legislators(self):
        import urllib2
        uri = 'http://www2.camara.sp.gov.br/Dados_abertos/vereador/vereador.txt'

        contents = urllib2.urlopen(uri)

        for line in contents:

            try:
                line = line.decode('utf-8')
            except UnicodeDecodeError:
                try:
                    line = line.decode('iso-8859-1')
                except Exception:
                    pass

            row = line.split('#')
            if len(row) > 2:
                name = row[1]
                nickname = row[2]

                if nickname:
                    legislator = self.add_legislator(nickname)
                else:
                    legislator = self.add_legislator(name)

                aa = re.search('\^\p([^\^|%]*)(\^|%)', row[7])
                if aa:
                    party_siglum = aa.group(1)
                else:
                    pass

                try:
                    date_start_re = re.search('\^\i([^\^|%]*)(\^|%)', row[7])
                    start_year = int(date_start_re.group(1).split('/')[2])
                    date_start = datetime(start_year, 1, 1)
                except IndexError:
                    continue

                legislature = self.get_legislature(start_year)

                mandate, mandate_created = Mandate.objects.get_or_create(
                    legislator=legislator,
                    date_start=legislature.date_start,
                    legislature=legislature)

                if mandate_created:
                    self.debug(u'New Mandate found: %s' % mandate)
                else:
                    self.debug(u'Found existing Mandate: %s' % mandate)

                if party_siglum and 'Sem' or 'Vereaores' not in party_siglum:
                    party, party_created = PoliticalParty.objects.get_or_create(
                        siglum=party_siglum)

                    mandate.party = party
                    mandate.save()
                    self.debug('Updating legislator party: %s' % party)

    def update_data(self):
        self.process_all_legislators()
        self.process_current_legislators()
        self.process_all_expenses()
<commit_msg>cmsp: correctly create collection run for the legislature<commit_after># -*- coding: utf-8 -*-
#
# Copyright (©) 2013 Marcelo Jorge Vieira <metal@alucinados.com>
#
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU Affero General Public License as
#  published by the Free Software Foundation, either version 3 of the
#  License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU Affero General Public License for more details.
#
#  You should have received a copy of the GNU Affero General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.

import os
import re
import urllib
from datetime import datetime
from django.core.files import File

from basecollector import BaseCollector
from montanha.models import *

def parse_money(string):
    string = string.replace('.', '')
    string = string.replace(',', '.')
    return float(string)

def parse_date(string):
    return datetime.strptime(string, '%d/%m/%Y').date()

def parse_cmsp_date(month, year):
    day = '01'
    return parse_date(day + '/' + month + '/' + year)

class CMSP(BaseCollector):
    def __init__(self, collection_runs, debug_enabled=False):
        super(CMSP, self).__init__(collection_runs, debug_enabled)

        institution, institution_created = Institution.objects.get_or_create(
            siglum='CMSP',
            name=u'Câmara Municipal de São Paulo')

        self.institution = institution

    def _normalize_party_siglum(self, siglum):
        names_map = {
            'DEMOCRATAS': 'DEM',
        }
        return names_map.get(siglum, siglum)

    def retrieve_expenses(self, month, year):
        uri = 'http://www.camara.sp.gov.br/wp-content/uploads/transparencia/saeg/%s%s.XML' % (year, month)
        return BaseCollector.retrieve_uri(self, uri, force_encoding='utf-8')

    def retrieve_legislators(self):
        uri = 'http://www1.camara.sp.gov.br/vereadores_joomla.asp'
        return BaseCollector.retrieve_uri(self, uri)

    def retrieve_legislator(self, link):
        uri = 'http://www1.camara.sp.gov.br/%s' % link
        return BaseCollector.retrieve_uri(self, uri)

    def add_legislator(self, name):
        legislator, created = Legislator.objects.get_or_create(name=name)

        if created:
            self.debug(u'New legislator found: %s' % legislator)
        else:
            self.debug(u'Found existing legislator: %s' % legislator)

        return legislator

    def process_legislators(self, legislature):
        legislators = self.retrieve_legislators()
        if not legislators:
            return

        links = legislators.findAll(
            'a',
            href=re.compile('^vereador_joomla2.asp\?vereador='))

        for link in links:
            href = link.get('href')
            html_legislator = self.retrieve_legislator(href)
            if not html_legislator:
                continue

            url, code = href.split('=', 1)
            name = html_legislator.find(id='nome_vereador').getText()

            legislator = self.add_legislator(name)

            legislator_img = html_legislator.find(
                'img',
                src=re.compile('imgs/fotos/'))

            if legislator_img:
                legislator_img_src = legislator_img.get('src')

                legislator_img_url = 'http://www1.camara.sp.gov.br/%s' % (
                    legislator_img_src)

                result = urllib.urlretrieve(legislator_img_url)

                legislator.picture.save(
                    os.path.basename(legislator_img_url), File(open(result[0])))

                legislator.save()

                self.debug('Updating legislator picture.')

            try:
                mandate = Mandate.objects.get(
                    legislator=legislator,
                    date_start=legislature.date_start,
                    legislature=legislature)
                self.debug(u'Found existing Mandate: %s' % mandate)
            except Mandate.DoesNotExist:
                mandate = Mandate(
                    legislator=legislator,
                    date_start=legislature.date_start,
                    legislature=legislature)
                mandate.save()
                self.debug(u'New Mandate found: %s' % mandate)

            party_name = html_legislator.find(
                'img',
                src=re.compile('imgs/Partidos'))

            party_name = party_name.parent.parent.find('font', size='2')
            party_name = party_name.getText()
            party_siglum = party_name[party_name.find('(')+1:party_name.find(')')]

            if 'Vereadores Licenciados' not in party_siglum:
                party_siglum = self._normalize_party_siglum(party_siglum)
                party, party_created = PoliticalParty.objects.get_or_create(
                    siglum=party_siglum)

                mandate.party = party
                mandate.save()
                self.debug('Updating legislator party: %s' % party_siglum)

    def process_expenses(self, month, year, legislature, collection_run):
        data = self.retrieve_expenses(month, year)
        if not data:
            return

        for x in data.findAll('g_deputado'):
            name = x.find('nm_deputado').getText().capitalize()
            legislator = self.add_legislator(name)

            try:
                mandate = Mandate.objects.get(
                    legislator=legislator,
                    date_start=legislature.date_start,
                    legislature=legislature)
                self.debug(u'Found existing Mandate: %s' % mandate)
            except Mandate.DoesNotExist:
                mandate = Mandate(
                    legislator=legislator,
                    date_start=legislature.date_start,
                    legislature=legislature)
                mandate.save()
                self.debug(u'New Mandate found: %s' % mandate)

            expense_type = x.find('list_g_tipo_despesa')

            for i in expense_type.findAll('g_tipo_despesa'):
                nature_text = i.find('nm_tipo_despesa').getText()
                try:
                    nature_text = nature_text.split('-', 1)[1].strip()
                except IndexError:
                    pass

                nature_text = nature_text.capitalize()

                ignore_list = [u'total', u'TOTAL', u'utilizado até 30/11/07']
                ignore_matches = [s for s in ignore_list if s in nature_text]
                if ignore_matches:
                    continue

                nature, nature_created = ExpenseNature.objects.get_or_create(
                    name=nature_text)

                if nature_created:
                    self.debug(u'New ExpenseNature found: %s' % nature)
                else:
                    self.debug(u'Found existing ExpenseNature: %s' % nature)

                m_month = i.find('nr_mes_ref').getText()
                m_year = i.find('nr_ano_ref').getText()
                date = parse_cmsp_date(m_month, m_year)

                for j in i.findAll('g_beneficiario'):
                    supplier_name = j.find('nm_beneficiario').getText()
                    supplier_name = supplier_name.capitalize()
                    cnpj = self.normalize_cnpj_or_cpf(j.find('nr_cnpj').getText())

                    if not cnpj and not supplier_name:
                        continue

                    try:
                        supplier = Supplier.objects.get(identifier=cnpj)
                        supplier_created = False
                    except Supplier.DoesNotExist:
                        supplier = Supplier(identifier=cnpj, name=supplier_name)
                        supplier.save()
                        supplier_created = True

                    if supplier_created:
                        self.debug(u'New Supplier found: %s' % supplier)
                    else:
                        self.debug(u'Found existing supplier: %s' % supplier)

                    expensed = parse_money(j.find('vl_desp').getText())

                    expense = ArchivedExpense(number='None',
                                              nature=nature,
                                              date=date,
                                              expensed=expensed,
                                              mandate=mandate,
                                              supplier=supplier,
                                              collection_run=collection_run)
                    expense.save()

                    self.debug(u'New expense found: %s' % expense)

    def get_legislature(self, year):
        start_year = end_year = year

        if year >= 2013 and year <= 2016:
            start_year = 2013
            end_year = 2016

        if year >= 2009 and year <= 2012:
            start_year = 2009
            end_year = 2012

        if year >= 2005 and year <= 2008:
            start_year = 2005
            end_year = 2008

        legislature, created = Legislature.objects.get_or_create(
            institution=self.institution,
            date_start=datetime(start_year, 1, 1),
            date_end=datetime(end_year, 12, 31))

        if created:
            self.debug(u'New Legislature found: %s' % legislature)
        else:
            self.debug(u'Found existing legislature: %s' % legislature)

        return legislature

    def process_all_expenses(self):
        legislature = self.get_legislature(2013)
        collection_run = self.create_collection_run(legislature)
        for year in xrange(legislature.date_start.year, legislature.date_end.year + 1):
            for m in xrange(1, 13):
                month = '%02d' % m
                self.debug('Adding expenses from %s/%s' % (month, year))
                self.process_expenses(month, year, legislature, collection_run)

    def process_current_legislators(self):
        current_legislature = self.get_legislature(2013)
        self.process_legislators(current_legislature)

    def process_all_legislators(self):
        import urllib2
        uri = 'http://www2.camara.sp.gov.br/Dados_abertos/vereador/vereador.txt'

        contents = urllib2.urlopen(uri)

        for line in contents:

            try:
                line = line.decode('utf-8')
            except UnicodeDecodeError:
                try:
                    line = line.decode('iso-8859-1')
                except Exception:
                    pass

            row = line.split('#')
            if len(row) > 2:
                name = row[1]
                nickname = row[2]

                if nickname:
                    legislator = self.add_legislator(nickname)
                else:
                    legislator = self.add_legislator(name)

                aa = re.search('\^\p([^\^|%]*)(\^|%)', row[7])
                if aa:
                    party_siglum = aa.group(1)
                else:
                    pass

                try:
                    date_start_re = re.search('\^\i([^\^|%]*)(\^|%)', row[7])
                    start_year = int(date_start_re.group(1).split('/')[2])
                    date_start = datetime(start_year, 1, 1)
                except IndexError:
                    continue

                legislature = self.get_legislature(start_year)

                mandate, mandate_created = Mandate.objects.get_or_create(
                    legislator=legislator,
                    date_start=legislature.date_start,
                    legislature=legislature)

                if mandate_created:
                    self.debug(u'New Mandate found: %s' % mandate)
                else:
                    self.debug(u'Found existing Mandate: %s' % mandate)

                if party_siglum and 'Sem' or 'Vereaores' not in party_siglum:
                    party, party_created = PoliticalParty.objects.get_or_create(
                        siglum=party_siglum)

                    mandate.party = party
                    mandate.save()
                    self.debug('Updating legislator party: %s' % party)

    def update_data(self):
        self.process_all_legislators()
        self.process_current_legislators()
        self.process_all_expenses()
<|endoftext|>


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

import os.path
import platform
import re
import subprocess
import sys

from distutils.version import LooseVersion

from setuptools import Extension
from setuptools.command.build_ext import build_ext

import cbuild_config
from gen_config import win_cmake_path
from cbuild_config import couchbase_core, build_type
import logging
import traceback

PYCBC_SSL_FETCH = os.getenv('PYCBC_SSL_FETCH', '')

class CMakeExtension(Extension):
    def __init__(self, name, sourcedir='', **kw):
        Extension.__init__(self, name, **kw)
        self.sourcedir = os.path.abspath(sourcedir)

class CMakeBuild(cbuild_config.CBuildCommon):
    hasrun = False
    hasbuilt = False
    hybrid = False
    info = None  # type: cbuild_config.CBuildInfo

    def run(self):
        if not CMakeBuild.hasrun:
            out = self.check_for_cmake()
            if not out:
                raise RuntimeError(
                    "CMake must be installed to build the following extensions: " +
                    ", ".join(e.name for e in self.extensions))

            if platform.system() == "Windows":
                cmake_version = LooseVersion(re.search(r'version\s*([\d.]+)',
                                                       out.decode()).group(1))
                if cmake_version < '3.5.1':
                    raise RuntimeError("CMake >= 3.5.1 is required on Windows")
            CMakeBuild.hasrun = True
            if CMakeBuild.hybrid:
                build_ext.run(self)

            for ext in self.extensions:
                self.build_extension(ext)

    @staticmethod
    def check_for_cmake():
        try:
            return subprocess.check_output(['cmake', '--version'])
        except BaseException:
            return None

    @staticmethod
    def requires():
        base_req = []
        if re.match(r'.*(CONAN|ALL).*', PYCBC_SSL_FETCH):
            base_req.append('conan')
        if re.match(r'.*(GITHUB_API|ALL).*', PYCBC_SSL_FETCH):
            base_req.append('PyGithub')
        return base_req + ([] if CMakeBuild.check_for_cmake() else ["cmake"])

    def prep_build(self, ext):
        if not CMakeBuild.hasbuilt:
            from distutils.sysconfig import get_python_inc
            import distutils.sysconfig as sysconfig
            cfg = self.cfg_type()
            extdir = os.path.abspath(
                os.path.dirname(self.get_ext_fullpath(ext.name)))

            lcb_api_flags = self.get_lcb_api_flags()
            cmake_args = lcb_api_flags + ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir,
                                          '-DPYTHON_EXECUTABLE=' + sys.executable]
            cmake_args += ['-DPYTHON_INCLUDE_DIR={}'.format(get_python_inc())]
            self.info.setbase(self.build_temp)
            self.info.cfg = cfg
            from distutils import sysconfig
            import os.path as op
            v = sysconfig.get_config_vars()
            print("LIBDIR {}, LIBPL {}".format(
                v.get("LIBDIR"), v.get("LIBPL")))
            fpaths = [op.join(v.get(pv, ''), v.get('LDLIBRARY', '')) for pv in ('LIBDIR', 'LIBPL')] + [os.path.normpath(
                os.path.join(get_python_inc(), "..", "..", "lib",
                             "libpython{}.dylib".format('.'.join(map(str, sys.version_info[0:2]))))),
                os.path.join(get_python_inc(), "..", "..", "lib")]
            python_lib = None
            python_libdir = None
            for entry in fpaths:
                if not op.exists(entry):
                    print("fpath {} does not exist".format(entry))
                    continue
                try:
                    print("got fpath {}:".format(entry))
                    if op.isfile(entry):
                        print("fpath {} is file, selecting".format(entry))
                        python_lib = python_lib or entry
                        continue
                    else:
                        entries = os.listdir(entry)
                        print("fpath {} is directory, contents {}".format(
                            entry, entries))
                        for subentry in entries:
                            fullname = op.normpath(op.join(entry, subentry))
                            try:
                                fullname = op.readlink(fullname)
                            except BaseException:
                                pass
                            print("trying subentry:{}".format(fullname))

                            if op.exists(fullname):
                                python_lib = python_lib or fullname
                                python_libdir = op.normpath(entry)
                                print(
                                    "got match {}, breaking out".format(fullname))
                                continue

                except BaseException:
                    pass
            cmake_args += ['-DHYBRID_BUILD=TRUE'] if CMakeBuild.hybrid else []
            cmake_args += ['-DPYTHON_LIBFILE={}'.format(
                python_lib)] if python_lib else []
            cmake_args += ['-DPYTHON_LIBDIR={}'.format(
                python_libdir)] if python_libdir else []
            cmake_args += [
                '-DPYTHON_VERSION_EXACT={}'.format('.'.join(map(str, sys.version_info[0:2])))] if python_libdir else []
            build_args = ['--config', cfg]
            if platform.system() == "Windows":
                cmake_args += ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(
                    cfg.upper(),
                    extdir), '-DLCB_NO_MOCK=1',
                    '-DCMAKE_BUILD_PARALLEL_LEVEL=1']
                if sys.maxsize > 2 ** 32:
                    cmake_args += ['-A', 'x64']
                build_args += ['--', '/m']
            else:
                cmake_args += ['-DCMAKE_BUILD_TYPE=' + cfg.upper()]
                build_args += ['--', '-j2']
            env = os.environ.copy()
            python_executable = win_cmake_path(sys.executable)
            pass_path = False
            if re.match(r'.*(CONAN|ALL).*', PYCBC_SSL_FETCH):
                try:
                    import conans.conan
                    env['PATH'] = env['PATH'] + \
                        ";{}".format(os.path.dirname(conans.conan.__file__))
                    pass_path = True
                except BaseException:
                    logging.warning("Cannot find conan : {}".format(
                        traceback.format_exc()))
            if re.match(r'.*(GITHUB|ALL).*', PYCBC_SSL_FETCH):
                pass_path = True
            if pass_path:
                pathsep = ';' if platform.system().lower().startswith('win') else ':'
                env['PYTHONPATH'] = pathsep.join(sys.path)
            cmake_args += [
                '-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON',
                '-DPYTHON_EXECUTABLE={}'.format(python_executable)]
            if PYCBC_SSL_FETCH:
                cmake_args += ['-DPYCBC_SSL_FETCH={}'.format(PYCBC_SSL_FETCH)]
            PYCBC_CMAKE_DEBUG = env.get('PYCBC_CMAKE_DEBUG')
            if PYCBC_CMAKE_DEBUG:
                cmake_args += [
                    '--trace-source=CMakeLists.txt',
                    '--trace-expand']
            cxx_compile_args = filter(re.compile(
                r'^(?!-std\s*=\s*c(11|99)).*').match, ext.extra_compile_args)
            env['CXXFLAGS'] = '{} {} -DVERSION_INFO=\\"{}\\"'.format(
                env.get('CXXFLAGS', ''), ' '.join(cxx_compile_args),
                self.distribution.get_version())

            env['CFLAGS'] = '{} {}'.format(
                env.get('CFLAGS', ''), ' '.join(ext.extra_compile_args),
                self.distribution.get_version())
            print("Launching build with env: {}, build_args: {}, cmake_args: {}".format(
                env, build_args, cmake_args))
            if not os.path.exists(self.build_temp):
                os.makedirs(self.build_temp)
            subprocess.check_call(['cmake', ext.sourcedir] + cmake_args, stdout=sys.stdout, stderr=sys.stdout,
                                  cwd=self.build_temp, env=env)
            subprocess.check_call(['cmake', '--build', '.'] + build_args,
                                  cwd=self.build_temp)
            CMakeBuild.hasbuilt = True
            build_dir = os.path.realpath(self.build_lib)

            if CMakeBuild.hybrid:
                if not self.compiler:
                    self.run()

            for name in self.info.entries():
                try:
                    pkg_build_dir = os.path.join(
                        build_dir, cbuild_config.couchbase_core)
                    self.copy_binary_to(cfg, pkg_build_dir,
                                        self.info.lcb_pkgs_srcs(), name)
                    self.copy_binary_to(
                        cfg, self.info.pkg_data_dir, self.info.lcb_pkgs_srcs(), name)
                except BaseException:
                    print("failure")
                    raise

def gen_cmake_build(extoptions, pkgdata):
    CMakeBuild.hybrid = build_type in ['CMAKE_HYBRID']
    CMakeBuild.setup_build_info(extoptions, pkgdata)
    e_mods = [CMakeExtension(
        str(couchbase_core + '._libcouchbase'), '', **extoptions)]
    return e_mods, CMakeBuild.requires(), cbuild_config.LazyCommandClass(CMakeBuild)
<commit_msg>PYCBC-1223: Provide build hook to allow env config to set OpenSSL path<commit_after>#
# Copyright 2019, Couchbase, Inc.
# All Rights Reserved
#
# Licensed under the Apache License, Version 2.0 (the "License")
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import os.path
import platform
import re
import subprocess
import sys

from distutils.version import LooseVersion

from setuptools import Extension
from setuptools.command.build_ext import build_ext

import cbuild_config
from gen_config import win_cmake_path
from cbuild_config import couchbase_core, build_type
import logging
import traceback

PYCBC_SSL_FETCH = os.getenv('PYCBC_SSL_FETCH', '')
PYCBC_OPENSSL_DIR = os.getenv("PYCBC_OPENSSL_DIR", None)

class CMakeExtension(Extension):
    def __init__(self, name, sourcedir='', **kw):
        Extension.__init__(self, name, **kw)
        self.sourcedir = os.path.abspath(sourcedir)

class CMakeBuild(cbuild_config.CBuildCommon):
    hasrun = False
    hasbuilt = False
    hybrid = False
    info = None  # type: cbuild_config.CBuildInfo

    def run(self):
        if not CMakeBuild.hasrun:
            out = self.check_for_cmake()
            if not out:
                raise RuntimeError(
                    "CMake must be installed to build the following extensions: " +
                    ", ".join(e.name for e in self.extensions))

            if platform.system() == "Windows":
                cmake_version = LooseVersion(re.search(r'version\s*([\d.]+)',
                                                       out.decode()).group(1))
                if cmake_version < '3.5.1':
                    raise RuntimeError("CMake >= 3.5.1 is required on Windows")
            CMakeBuild.hasrun = True
            if CMakeBuild.hybrid:
                build_ext.run(self)

            for ext in self.extensions:
                self.build_extension(ext)

    @staticmethod
    def check_for_cmake():
        try:
            return subprocess.check_output(['cmake', '--version'])
        except BaseException:
            return None

    @staticmethod
    def requires():
        base_req = []
        if re.match(r'.*(CONAN|ALL).*', PYCBC_SSL_FETCH):
            base_req.append('conan')
        if re.match(r'.*(GITHUB_API|ALL).*', PYCBC_SSL_FETCH):
            base_req.append('PyGithub')
        return base_req + ([] if CMakeBuild.check_for_cmake() else ["cmake"])

    def prep_build(self, ext):
        if not CMakeBuild.hasbuilt:
            from distutils.sysconfig import get_python_inc
            import distutils.sysconfig as sysconfig
            cfg = self.cfg_type()
            extdir = os.path.abspath(
                os.path.dirname(self.get_ext_fullpath(ext.name)))

            lcb_api_flags = self.get_lcb_api_flags()
            cmake_args = lcb_api_flags + ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir,
                                          '-DPYTHON_EXECUTABLE=' + sys.executable]
            cmake_args += ['-DPYTHON_INCLUDE_DIR={}'.format(get_python_inc())]
            self.info.setbase(self.build_temp)
            self.info.cfg = cfg
            from distutils import sysconfig
            import os.path as op
            v = sysconfig.get_config_vars()
            print("LIBDIR {}, LIBPL {}".format(
                v.get("LIBDIR"), v.get("LIBPL")))
            fpaths = [op.join(v.get(pv, ''), v.get('LDLIBRARY', '')) for pv in ('LIBDIR', 'LIBPL')] + [os.path.normpath(
                os.path.join(get_python_inc(), "..", "..", "lib",
                             "libpython{}.dylib".format('.'.join(map(str, sys.version_info[0:2]))))),
                os.path.join(get_python_inc(), "..", "..", "lib")]
            python_lib = None
            python_libdir = None
            for entry in fpaths:
                if not op.exists(entry):
                    print("fpath {} does not exist".format(entry))
                    continue
                try:
                    print("got fpath {}:".format(entry))
                    if op.isfile(entry):
                        print("fpath {} is file, selecting".format(entry))
                        python_lib = python_lib or entry
                        continue
                    else:
                        entries = os.listdir(entry)
                        print("fpath {} is directory, contents {}".format(
                            entry, entries))
                        for subentry in entries:
                            fullname = op.normpath(op.join(entry, subentry))
                            try:
                                fullname = op.readlink(fullname)
                            except BaseException:
                                pass
                            print("trying subentry:{}".format(fullname))

                            if op.exists(fullname):
                                python_lib = python_lib or fullname
                                python_libdir = op.normpath(entry)
                                print(
                                    "got match {}, breaking out".format(fullname))
                                continue

                except BaseException:
                    pass
            cmake_args += ['-DHYBRID_BUILD=TRUE'] if CMakeBuild.hybrid else []
            cmake_args += ['-DPYTHON_LIBFILE={}'.format(
                python_lib)] if python_lib else []
            cmake_args += ['-DPYTHON_LIBDIR={}'.format(
                python_libdir)] if python_libdir else []
            cmake_args += [
                '-DPYTHON_VERSION_EXACT={}'.format('.'.join(map(str, sys.version_info[0:2])))] if python_libdir else []
            build_args = ['--config', cfg]
            if platform.system() == "Windows":
                cmake_args += ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(
                    cfg.upper(),
                    extdir), '-DLCB_NO_MOCK=1',
                    '-DCMAKE_BUILD_PARALLEL_LEVEL=1']
                if sys.maxsize > 2 ** 32:
                    cmake_args += ['-A', 'x64']
                build_args += ['--', '/m']
            else:
                cmake_args += ['-DCMAKE_BUILD_TYPE=' + cfg.upper()]
                build_args += ['--', '-j2']
            env = os.environ.copy()
            python_executable = win_cmake_path(sys.executable)
            pass_path = False
            if re.match(r'.*(CONAN|ALL).*', PYCBC_SSL_FETCH):
                try:
                    import conans.conan
                    env['PATH'] = env['PATH'] + \
                        ";{}".format(os.path.dirname(conans.conan.__file__))
                    pass_path = True
                except BaseException:
                    logging.warning("Cannot find conan : {}".format(
                        traceback.format_exc()))
            if re.match(r'.*(GITHUB|ALL).*', PYCBC_SSL_FETCH):
                pass_path = True
            if pass_path:
                pathsep = ';' if platform.system().lower().startswith('win') else ':'
                env['PYTHONPATH'] = pathsep.join(sys.path)
            cmake_args += [
                '-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON',
                '-DPYTHON_EXECUTABLE={}'.format(python_executable)]
            if PYCBC_SSL_FETCH:
                cmake_args += ['-DPYCBC_SSL_FETCH={}'.format(PYCBC_SSL_FETCH)]
            if PYCBC_OPENSSL_DIR:
                cmake_args += ['-DOPENSSL_ROOT_DIR={}'.format(PYCBC_OPENSSL_DIR)]
            PYCBC_CMAKE_DEBUG = env.get('PYCBC_CMAKE_DEBUG')
            if PYCBC_CMAKE_DEBUG:
                cmake_args += [
                    '--trace-source=CMakeLists.txt',
                    '--trace-expand']
            cxx_compile_args = filter(re.compile(
                r'^(?!-std\s*=\s*c(11|99)).*').match, ext.extra_compile_args)
            env['CXXFLAGS'] = '{} {} -DVERSION_INFO=\\"{}\\"'.format(
                env.get('CXXFLAGS', ''), ' '.join(cxx_compile_args),
                self.distribution.get_version())

            env['CFLAGS'] = '{} {}'.format(
                env.get('CFLAGS', ''), ' '.join(ext.extra_compile_args),
                self.distribution.get_version())
            print("Launching build with env: {}, build_args: {}, cmake_args: {}".format(
                env, build_args, cmake_args))
            if not os.path.exists(self.build_temp):
                os.makedirs(self.build_temp)
            subprocess.check_call(['cmake', ext.sourcedir] + cmake_args, stdout=sys.stdout, stderr=sys.stdout,
                                  cwd=self.build_temp, env=env)
            subprocess.check_call(['cmake', '--build', '.'] + build_args,
                                  cwd=self.build_temp)
            CMakeBuild.hasbuilt = True
            build_dir = os.path.realpath(self.build_lib)

            if CMakeBuild.hybrid:
                if not self.compiler:
                    self.run()

            for name in self.info.entries():
                try:
                    pkg_build_dir = os.path.join(
                        build_dir, cbuild_config.couchbase_core)
                    self.copy_binary_to(cfg, pkg_build_dir,
                                        self.info.lcb_pkgs_srcs(), name)
                    self.copy_binary_to(
                        cfg, self.info.pkg_data_dir, self.info.lcb_pkgs_srcs(), name)
                except BaseException:
                    print("failure")
                    raise

def gen_cmake_build(extoptions, pkgdata):
    CMakeBuild.hybrid = build_type in ['CMAKE_HYBRID']
    CMakeBuild.setup_build_info(extoptions, pkgdata)
    e_mods = [CMakeExtension(
        str(couchbase_core + '._libcouchbase'), '', **extoptions)]
    return e_mods, CMakeBuild.requires(), cbuild_config.LazyCommandClass(CMakeBuild)
<|endoftext|>