<commit_before>#!/usr/bin/python
###############################################################################
# Copyright (C) 2001-2015 Micronaet S.r.l. (<https://micronaet.com>)
# Developer: Nicola Riolini @thebrush
#            https://it.linkedin.com/in/thebrush
#            https://linktr.ee/nicolariolini
###############################################################################

import os
import sys
import hmac
import hashlib
import base64
import json
import uuid
import pytz
import pdb
from datetime import datetime
from zeep import Client
from flask import Flask, request
from flask import Response

try:
    import ConfigParser
except:
    try:
        import configparser as ConfigParser
    except:
        print('Errore importanto i parametri di avvio!')
        sys.exit()

token = False

# -----------------------------------------------------------------------------
#                                  Utility:
# -----------------------------------------------------------------------------
# LOG:
# -----------------------------------------------------------------------------
def write_log(log_f, message, mode='INFO', verbose=True):
    """ Write log file
    """
    complete_message = '%s [%s]: %s' % (
        str(datetime.now())[:19],
        mode,
        message,
    )
    if verbose:
        print(' * {}'.format(complete_message))
    log_f.write('{}\n'.format(complete_message))
    log_f.flush()

# -----------------------------------------------------------------------------
# SOAP:
# -----------------------------------------------------------------------------
message_mask = 'GET+/users/%s/account+%s+%s'
username = bytes('GENERALFOOD')
secret = bytes('5BC478479AB65798A4420F3FB19EF68E96ECFEA8')
namespace = bytes('{it.niuma.mscsoapws.ws}MscWsPortSoap11')
wsdl_root = bytes('https://layer7prod.msccruises.com/pep/wsdl')

# datetime_field = []
decimal_field = [
    # Header:
    'documentValue',

    # Line:
    'itemPrice',
    'quantityOrdered',
    'quantityConfirmed',
    'quantityLogistic',
    'nrPzConf',
    'flDogana',
]

def soap2dict(reply):
    """ Convert soap to dict
    """
    res = {}

    # -------------------------------------------------------------------------
    # Outcome part:
    # -------------------------------------------------------------------------
    res['operationOutcome'] = eval(str(reply['operationOutcome']))

    # -------------------------------------------------------------------------
    # Orders part:
    # -------------------------------------------------------------------------
    for order in reply['orders']:
        new_order = {}  # New structure:

        # ---------------------------------------------------------------------
        # All order fields
        # ---------------------------------------------------------------------
        for field in dir(order):
            # A. Order line updated after:
            if field == 'orderLines':
                new_order['orderLines'] = []
                continue  # after

            # B. Datetime field:
            if type(order[field]) == datetime:
                new_order[field] = str(order[field])

            # C. Decimal field:
            elif field in decimal_field:
                new_order[field] = float(order[field])

            # D. Normal fields (string, integer, boolean)
            else:
                new_order[field] = order[field]

        # ---------------------------------------------------------------------
        # Line part:
        # ---------------------------------------------------------------------
        for line in order['orderLines']:
            new_line = {}

            # Loop on every field:
            for line_field in dir(line):
                # a. Float
                if line_field in decimal_field:
                    new_line[line_field] = float(line[line_field])
                # b. Normal fields (string, integer, boolean)
                else:
                    new_line[line_field] = line[line_field]

            order['orderLines'].append(new_line)
    return res

def get_soap_service():
    """ Get WSDL Service link
        if passed namespace and wsdl root use that, instead of
        read from
        parameters
    """
    client = Client(wsdl_root)
    return client.create_service(namespace, wsdl_root)

def get_datetime_tz():
    """ Change datetime removing gap from now and GMT 0
    """
    return pytz.utc.localize(datetime.now()).astimezone(
        pytz.timezone('Europe/Rome'))

def get_token():
    """ Call server and get token
    """
    timestamp = get_datetime_tz().strftime('%d%m%Y%H%M%S')
    number = str(uuid.uuid4())[-6:]
    message = message_mask % (username, timestamp, number)

    signature = hmac.new(
        secret, msg=message, digestmod=hashlib.sha256).digest()
    hash_text = base64.b64encode(signature)

    # Call SOAP portal:
    service = get_soap_service()
    res = service.login(
        username=username, time=timestamp, number=number,
        hash=hash_text)
    res = eval(str(res))
    token = res['accessToken']
    return res

# -----------------------------------------------------------------------------
# Read configuration parameter from external file:
# -----------------------------------------------------------------------------
current_path = os.path.dirname(__file__)
log_file = os.path.join(current_path, 'flask.log')
log_f = open(log_file, 'a')
write_log(log_f, 'Start ODOO-MSC Flask agent')
write_log(log_f, 'Flask log file: {}'.format(log_file))

config_files = [
    os.path.join(current_path, 'flask.cfg'),
]
for config_file in config_files:
    if not os.path.isfile(config_file):
        continue
    cfg_file = os.path.expanduser(config_file)

    config = ConfigParser.ConfigParser()
    config.read([cfg_file])
    host = config.get('flask', 'host')
    port = config.get('flask', 'port')
    write_log(log_f, 'Read config file: {}'.format(config_file))
    break
else:
    write_log(log_f, 'Read default parameter [0.0.0.0:5000]')
    host = '0.0.0.0'
    port = '5000'

# -----------------------------------------------------------------------------
# End point definition:
# -----------------------------------------------------------------------------
app = Flask(__name__)

@app.route('/API/v1.0/micronaet/launcher', methods=['POST'])
def ODOOCall():
    """ Master function for Micronaet Call

    """
    # -------------------------------------------------------------------------
    # Get parameters from call:
    # -------------------------------------------------------------------------
    params = request.get_json()
    rpc_call = params['params']
    command = rpc_call['command']
    parameter = rpc_call['parameters']

    # -------------------------------------------------------------------------
    #                             Execute call:
    # -------------------------------------------------------------------------
    # Start reply payload:
    payload = {
        'success': False,
        'reply': {},
    }
    # -------------------------------------------------------------------------
    #                       Import invoice procedure:
    # -------------------------------------------------------------------------
    if command == 'token':
        account_command = parameter.get('command')  # account command
        #try:

        # ---------------------------------------------------------------------
        # Call for token
        # ---------------------------------------------------------------------
        try:
            # -----------------------------------------------------------------
            # Read parameters:
            # -----------------------------------------------------------------
            # wsdl_root = bytes(parameter.get('wsdl_root'))
            # namespace = bytes(parameter.get('namespace'))
            # username = bytes(parameter.get('username'))
            # timestamp = parameter.get('timestamp')
            # number = parameter.get('number')
            # hash_text = parameter.get('hash_text')

            res = get_token()
            payload['reply']['res'] = res
            payload['success'] = True
            return payload
        except:
            print('Errore: %s' % (sys.exc_info(), ))
            payload['reply'].update({
                'error': 'Errore nella chiamata ad MSC portale: '
                         '{}'.format(account_command),
            })
            return payload
        # finally:
        #    pass

    elif command == 'order':
        token = get_token()
        token = token['accessToken']  # Extract order from reply
        service = get_soap_service()
        reply = service.getOngoingPOrders(accessToken=token)
        pdb.set_trace()

        payload['reply']['res'] = soap2dict(reply)
        payload['success'] = True
        return payload

    elif command == 'invoice':
         pass
    else:
        # ---------------------------------------------------------------------
        # Bad call:
        # ---------------------------------------------------------------------
        message = '[ERROR] ODOO is calling wrong command {}\n'.format(
            command)
        payload['reply'].update({
            'error': message.strip(),
        })

    # -------------------------------------------------------------------------
    # Prepare response
    # -------------------------------------------------------------------------
    return payload

app.run(debug=True, host=host, port=port)
write_log(log_f, 'End ODOO-MSC Flask agent')
<commit_msg>generic bugfix (fast message)<commit_after>#!/usr/bin/python
###############################################################################
# Copyright (C) 2001-2015 Micronaet S.r.l. (<https://micronaet.com>)
# Developer: Nicola Riolini @thebrush
#            https://it.linkedin.com/in/thebrush
#            https://linktr.ee/nicolariolini
###############################################################################

import os
import sys
import hmac
import hashlib
import base64
import json
import uuid
import pytz
import pdb
from datetime import datetime
from zeep import Client
from flask import Flask, request
from flask import Response

try:
    import ConfigParser
except:
    try:
        import configparser as ConfigParser
    except:
        print('Errore importanto i parametri di avvio!')
        sys.exit()

token = False

# -----------------------------------------------------------------------------
#                                  Utility:
# -----------------------------------------------------------------------------
# LOG:
# -----------------------------------------------------------------------------
def write_log(log_f, message, mode='INFO', verbose=True):
    """ Write log file
    """
    complete_message = '%s [%s]: %s' % (
        str(datetime.now())[:19],
        mode,
        message,
    )
    if verbose:
        print(' * {}'.format(complete_message))
    log_f.write('{}\n'.format(complete_message))
    log_f.flush()

# -----------------------------------------------------------------------------
# SOAP:
# -----------------------------------------------------------------------------
message_mask = 'GET+/users/%s/account+%s+%s'
username = bytes('GENERALFOOD')
secret = bytes('5BC478479AB65798A4420F3FB19EF68E96ECFEA8')
namespace = bytes('{it.niuma.mscsoapws.ws}MscWsPortSoap11')
wsdl_root = bytes('https://layer7prod.msccruises.com/pep/wsdl')

# datetime_field = []
decimal_field = [
    # Header:
    'documentValue',

    # Line:
    'itemPrice',
    'quantityOrdered',
    'quantityConfirmed',
    'quantityLogistic',
    'nrPzConf',
    'flDogana',
]

def soap2dict(reply):
    """ Convert soap to dict
    """
    res = {}

    # -------------------------------------------------------------------------
    # Outcome part:
    # -------------------------------------------------------------------------
    res['operationOutcome'] = eval(str(reply['operationOutcome']))

    # -------------------------------------------------------------------------
    # Orders part:
    # -------------------------------------------------------------------------
    for order in reply['orders']:
        new_order = {}  # New structure:

        # ---------------------------------------------------------------------
        # All order fields
        # ---------------------------------------------------------------------
        for field in dir(order):
            # A. Order line updated after:
            if field == 'orderLines':
                new_order['orderLines'] = []
                continue  # after

            # B. Datetime field:
            if type(order[field]) == datetime:
                new_order[field] = str(order[field])

            # C. Decimal field:
            elif field in decimal_field:
                try:
                    new_order[field] = float(order[field])
                except:
                    pdb.set_trace()
                    new_order[field] = 0.0

            # D. Normal fields (string, integer, boolean)
            else:
                new_order[field] = order[field]

        # ---------------------------------------------------------------------
        # Line part:
        # ---------------------------------------------------------------------
        for line in order['orderLines']:
            new_line = {}

            # Loop on every field:
            for line_field in dir(line):
                # a. Float
                if line_field in decimal_field:
                    try:
                        new_line[line_field] = float(line[line_field])
                    except:
                        pdb.set_trace()
                        new_line[line_field] = 0.0
                # b. Normal fields (string, integer, boolean)
                else:
                    new_line[line_field] = line[line_field]

            order['orderLines'].append(new_line)
    return res

def get_soap_service():
    """ Get WSDL Service link
        if passed namespace and wsdl root use that, instead of
        read from
        parameters
    """
    client = Client(wsdl_root)
    return client.create_service(namespace, wsdl_root)

def get_datetime_tz():
    """ Change datetime removing gap from now and GMT 0
    """
    return pytz.utc.localize(datetime.now()).astimezone(
        pytz.timezone('Europe/Rome'))

def get_token():
    """ Call server and get token
    """
    timestamp = get_datetime_tz().strftime('%d%m%Y%H%M%S')
    number = str(uuid.uuid4())[-6:]
    message = message_mask % (username, timestamp, number)

    signature = hmac.new(
        secret, msg=message, digestmod=hashlib.sha256).digest()
    hash_text = base64.b64encode(signature)

    # Call SOAP portal:
    service = get_soap_service()
    res = service.login(
        username=username, time=timestamp, number=number,
        hash=hash_text)
    res = eval(str(res))
    token = res['accessToken']
    return res

# -----------------------------------------------------------------------------
# Read configuration parameter from external file:
# -----------------------------------------------------------------------------
current_path = os.path.dirname(__file__)
log_file = os.path.join(current_path, 'flask.log')
log_f = open(log_file, 'a')
write_log(log_f, 'Start ODOO-MSC Flask agent')
write_log(log_f, 'Flask log file: {}'.format(log_file))

config_files = [
    os.path.join(current_path, 'flask.cfg'),
]
for config_file in config_files:
    if not os.path.isfile(config_file):
        continue
    cfg_file = os.path.expanduser(config_file)

    config = ConfigParser.ConfigParser()
    config.read([cfg_file])
    host = config.get('flask', 'host')
    port = config.get('flask', 'port')
    write_log(log_f, 'Read config file: {}'.format(config_file))
    break
else:
    write_log(log_f, 'Read default parameter [0.0.0.0:5000]')
    host = '0.0.0.0'
    port = '5000'

# -----------------------------------------------------------------------------
# End point definition:
# -----------------------------------------------------------------------------
app = Flask(__name__)

@app.route('/API/v1.0/micronaet/launcher', methods=['POST'])
def ODOOCall():
    """ Master function for Micronaet Call

    """
    # -------------------------------------------------------------------------
    # Get parameters from call:
    # -------------------------------------------------------------------------
    params = request.get_json()
    rpc_call = params['params']
    command = rpc_call['command']
    parameter = rpc_call['parameters']

    # -------------------------------------------------------------------------
    #                             Execute call:
    # -------------------------------------------------------------------------
    # Start reply payload:
    payload = {
        'success': False,
        'reply': {},
    }
    # -------------------------------------------------------------------------
    #                       Import invoice procedure:
    # -------------------------------------------------------------------------
    if command == 'token':
        account_command = parameter.get('command')  # account command
        #try:

        # ---------------------------------------------------------------------
        # Call for token
        # ---------------------------------------------------------------------
        try:
            # -----------------------------------------------------------------
            # Read parameters:
            # -----------------------------------------------------------------
            # wsdl_root = bytes(parameter.get('wsdl_root'))
            # namespace = bytes(parameter.get('namespace'))
            # username = bytes(parameter.get('username'))
            # timestamp = parameter.get('timestamp')
            # number = parameter.get('number')
            # hash_text = parameter.get('hash_text')

            res = get_token()
            payload['reply']['res'] = res
            payload['success'] = True
            return payload
        except:
            print('Errore: %s' % (sys.exc_info(), ))
            payload['reply'].update({
                'error': 'Errore nella chiamata ad MSC portale: '
                         '{}'.format(account_command),
            })
            return payload
        # finally:
        #    pass

    elif command == 'order':
        token = get_token()
        token = token['accessToken']  # Extract order from reply
        service = get_soap_service()
        reply = service.getOngoingPOrders(accessToken=token)
        pdb.set_trace()

        payload['reply']['res'] = soap2dict(reply)
        payload['success'] = True
        return payload

    elif command == 'invoice':
         pass
    else:
        # ---------------------------------------------------------------------
        # Bad call:
        # ---------------------------------------------------------------------
        message = '[ERROR] ODOO is calling wrong command {}\n'.format(
            command)
        payload['reply'].update({
            'error': message.strip(),
        })

    # -------------------------------------------------------------------------
    # Prepare response
    # -------------------------------------------------------------------------
    return payload

app.run(debug=True, host=host, port=port)
write_log(log_f, 'End ODOO-MSC Flask agent')
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
import django.utils.timezone
from django.conf import settings
import core.mixins

class Migration(migrations.Migration):

    dependencies = [
        ('accounts', '0001_initial'),
    ]

    operations = [
        migrations.RunSQL(
            "ALTER TABLE id_profile RENAME TO accounts_profile"
        ),

        migrations.RunSQL(
            "ALTER TABLE id_profile_groups RENAME TO accounts_profile_groups"
        ),

        migrations.RunSQL(
            "ALTER TABLE id_profile_user_permissions RENAME TO accounts_profile_user_permissions"
        ),
    ]
<commit_msg>Only attempt to apply this migration if old tables are in place.<commit_after># -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations, connection
from django.db.utils import OperationalError
import django.utils.timezone
from django.conf import settings
import core.mixins

def got_old_migrations():
    """
    Check if we got old migrations - i.e.,
    we are running on a system that has
    migrations applied before they were purged
    (which happened in May/June 2016).
    """

    cursor = connection.cursor()

    try:
        cursor.execute('SELECT id FROM django_migrations WHERE app="accounts" AND name="0003_network"')

        if (len(cursor.fetchall()) > 0):
            return True

        return False

    # No such table, we can return False
    except OperationalError:
        return False

class Migration(migrations.Migration):
    def __init__(self, name, app_label):
        """
        Detect if we got old migrations - see got_old_migrations().
        If so, put in place operations that will rename tables.
        """

        super(Migration, self).__init__(name, app_label)

        if (got_old_migrations() == True):
            self.operations = self.perhaps_run_operations

    dependencies = [
        ('accounts', '0001_initial'),
    ]

    perhaps_run_operations = [
        migrations.RunSQL(
            "ALTER TABLE id_profile RENAME TO accounts_profile"
        ),

        migrations.RunSQL(
            "ALTER TABLE id_profile_groups RENAME TO accounts_profile_groups"
        ),

        migrations.RunSQL(
            "ALTER TABLE id_profile_user_permissions RENAME TO accounts_profile_user_permissions"
        ),
    ]

    # By default, we don't do anything,
    # but, see __init__() for situations
    # were we do something
    operations = []
<|endoftext|>


<commit_before>from pyjamas.ui.Composite import Composite
from pyjamas.ui.VerticalPanel import VerticalPanel
from pyjamas.ui.Hyperlink import Hyperlink

class SinkList(Composite):
    def __init__(self):
        Composite.__init__(self)
        self.vp_list=VerticalPanel()
        self.sinks=[]
        self.selectedSink=-1

        self.initWidget(self.vp_list)
        self.setStyleName("ks-List")

    def addSink(self, info):
        name = info.getName()
        link = Hyperlink(name, False, name)
        link.setStyleName("ks-SinkItem")
        self.vp_list.add(link)
        self.sinks.append(info)

    def find(self, sinkName):
        for info in self.sinks:
            if info.getName()==sinkName:
                return info
        return None

    def setSinkSelection(self, name):
        if self.selectedSink <> -1:
            self.vp_list.getWidget(self.selectedSink).removeStyleName("ks-SinkItem-selected")

        for i in range(len(self.sinks)):
            info = self.sinks[i]
            if (info.getName()==name):
                self.selectedSink = i
                widget=self.vp_list.getWidget(self.selectedSink)
                widget.addStyleName("ks-SinkItem-selected")
                return

<commit_msg>Fix hyperlink bug in addonns galery introduced in 21788e5fca3ada168cdf8150bc7ba1e3fdf7e039<commit_after>from pyjamas.ui.Composite import Composite
from pyjamas.ui.VerticalPanel import VerticalPanel
from pyjamas.ui.Hyperlink import Hyperlink

class SinkList(Composite):
    def __init__(self):
        Composite.__init__(self)
        self.vp_list=VerticalPanel()
        self.sinks=[]
        self.selectedSink=-1

        self.initWidget(self.vp_list)
        self.setStyleName("ks-List")

    def addSink(self, info):
        name = info.getName()
        link = Hyperlink(name, False, TargetHistoryToken=name)
        link.setStyleName("ks-SinkItem")
        self.vp_list.add(link)
        self.sinks.append(info)

    def find(self, sinkName):
        for info in self.sinks:
            if info.getName()==sinkName:
                return info
        return None

    def setSinkSelection(self, name):
        if self.selectedSink <> -1:
            self.vp_list.getWidget(self.selectedSink).removeStyleName("ks-SinkItem-selected")

        for i in range(len(self.sinks)):
            info = self.sinks[i]
            if (info.getName()==name):
                self.selectedSink = i
                widget=self.vp_list.getWidget(self.selectedSink)
                widget.addStyleName("ks-SinkItem-selected")
                return

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
#    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 wizard
import pooler
import time
import tools
import os

view_form_company = '''<?xml version="1.0"?>
<form string="Setup">
    <notebook colspan="4">
    <page string="General Information">
    <image name="gtk-dialog-info" colspan="2"/>
    <group>
        <separator string="Define Main Company" colspan="4"/>
        <newline/>
        <field name="name" align="0.0" colspan="4" required="True"/>
        <newline/>
        <field name="street" align="0.0"/>
        <field name="street2" align="0.0"/>
        <field name="zip" align="0.0"/>
        <field name="city" align="0.0"/>
        <field name="country_id" align="0.0"/>
        <field name="state_id" align="0.0"/>
        <field name="email" align="0.0"/>
        <field name="phone" align="0.0"/>
        <field name="currency" align="0.0"/>
    </group>
    </page>
    <page string="Report Information">
        <separator string="Report header" colspan="4"/>
        <newline/>
        <field name="rml_header1" align="0.0" colspan="4"/>
        <field name="rml_footer1" align="0.0" colspan="4"/>
        <field name="rml_footer2" align="0.0" colspan="4"/>
        <separator colspan="4" string="Your Logo - Use a size of about 450x150 pixels."/>
        <field colspan="4" name="logo" widget="image"/>
    </page>
    </notebook>
</form>'''

view_form_finish = '''<?xml version="1.0"?>
<form string="Setup">
    <image name="gtk-dialog-info" colspan="2"/>
    <group colspan="2" col="4">
        <separator colspan="4" string="Installation Done"/>
        <label align="0.0" colspan="4" string="Your new database is now fully installed."/>
        <label align="0.0" colspan="4" string="You can start configuring the system or connect directly to the database using the default setup."/>
    </group>
</form>
'''

class wizard_base_setup(wizard.interface):

    def _get_company(self, cr, uid, data, context):
        pool = pooler.get_pool(cr.dbname)
        company_obj = pool.get('res.company')
        ids=company_obj.search(cr, uid, [])
        if not ids:
            return {}
        company = company_obj.browse(cr, uid, ids)[0]

        res = {'currency': company.currency_id.id}

        for field in 'name logo rml_header1 rml_footer1 rml_footer2'.split():
            res[field] = company[field]

        if company.partner_id.address:
            address = company.partner_id.address[0]
            for field in 'street street2 zip city email phone'.split():
                res[field] = address[field]

            for field in 'country_id state_id'.split():
                if address[field]:
                    res[field] = address[field].id

        serv_pro_id = pool.get('ir.module.module').search(cr, uid, [('name','=','profile_service')])
        if serv_pro_id:
            res['profile'] = serv_pro_id[0]

        return res

    def _get_all(self, cr, uid, context, model):
        pool = pooler.get_pool(cr.dbname)
        obj = pool.get(model)
        ids = obj.search(cr, uid, [])
        res = [(o.id, o.name) for o in obj.browse(cr, uid, ids, context=context)]
        res.append((-1, ''))
        res.sort(key=lambda x: x[1])
        return res

    def _get_states(self, cr, uid, context):
        return self._get_all(cr, uid, context, 'res.country.state')

    def _get_countries(self, cr, uid, context):
        return self._get_all(cr, uid, context, 'res.country')

    def _get_currency(self, cr, uid, context):
        return self._get_all(cr, uid, context, 'res.currency')

    def _update(self, cr, uid, data, context):
        pool=pooler.get_pool(cr.dbname)
        form=data['form']

        company_obj=pool.get('res.company')
        partner_obj=pool.get('res.partner')
        address_obj=pool.get('res.partner.address')
        ids=company_obj.search(cr, uid, [])
        company=company_obj.browse(cr, uid, ids)[0]
        company_obj.write(cr, uid, [company.id], {
                'name': form['name'],
                'rml_header1': form['rml_header1'],
                'rml_footer1': form['rml_footer1'],
                'rml_footer2': form['rml_footer2'],
                'currency_id': form['currency'],
                'logo': form['logo'],
            })
        partner_obj.write(cr, uid, [company.partner_id.id], {
                'name': form['name'],
            })
        values={
                    'name': form['name'],
                    'street': form['street'],
                    'street2': form['street2'],
                    'zip': form['zip'],
                    'city': form['city'],
                    'email': form['email'],
                    'phone': form['phone'],
                }
        # we can do this, or set res.append((False, '')) in _get_all()
        if form['country_id'] > 0:
            values['country_id'] = form['country_id']
        if form['state_id'] > 0:
            values['state_id'] = form['state_id']
        if company.partner_id.address:
            address=company.partner_id.address[0]
            address_obj.write(cr, uid, [address.id], values)
        else:
            values['partner_id']=company.partner_id.id
            add_id=address_obj.create(cr, uid, values)

        cr.commit()
        (db, pool)=pooler.restart_pool(cr.dbname, update_module=True)

        return {}

    def _menu(self, cr, uid, data, context):
        users_obj=pooler.get_pool(cr.dbname).get('res.users')
        action_obj=pooler.get_pool(cr.dbname).get('ir.actions.act_window')

        ids=action_obj.search(cr, uid, [('name', '=', 'Menu')])
        menu=action_obj.browse(cr, uid, ids)[0]

        ids=users_obj.search(cr, uid, [('action_id', '=', 'Setup')])
        users_obj.write(cr, uid, ids, {'action_id': menu.id})
        ids=users_obj.search(cr, uid, [('menu_id', '=', 'Setup')])
        users_obj.write(cr, uid, ids, {'menu_id': menu.id})

        return {
            'name': menu.name,
            'type': menu.type,
            'view_id': (menu.view_id and\
                    (menu.view_id.id, menu.view_id.name)) or False,
            'domain': menu.domain,
            'res_model': menu.res_model,
            'src_model': menu.src_model,
            'view_type': menu.view_type,
            'view_mode': menu.view_mode,
            'views': menu.views,
        }

    def _config(self, cr, uid, data, context=None):
        pool = pooler.get_pool(cr.dbname)
        users_obj=pool.get('res.users')
        action_obj=pool.get('ir.actions.act_window')

        ids=action_obj.search(cr, uid, [('name', '=', 'Menu')])
        menu=action_obj.browse(cr, uid, ids)[0]

        ids=users_obj.search(cr, uid, [('action_id', '=', 'Setup')])
        users_obj.write(cr, uid, ids, {'action_id': menu.id})
        ids=users_obj.search(cr, uid, [('menu_id', '=', 'Setup')])
        users_obj.write(cr, uid, ids, {'menu_id': menu.id})

        return pool.get('res.config').next(cr, uid, [], context=context)

    fields={
        'name':{
            'string': 'Company Name',
            'type': 'char',
            'size': 64,
        },
        'street':{
            'string': 'Street',
            'type': 'char',
            'size': 128,
        },
        'street2':{
            'string': 'Street2',
            'type': 'char',
            'size': 128,
        },
        'zip':{
            'string': 'Zip code',
            'type': 'char',
            'size': 24,
        },
        'city':{
            'string': 'City',
            'type': 'char',
            'size': 128,
        },
        'state_id':{
            'string': 'State',
            'type': 'selection',
            'selection':_get_states,
        },
        'country_id':{
            'string': 'Country',
            'type': 'selection',
            'selection':_get_countries,
        },
        'email':{
            'string': 'E-mail',
            'type': 'char',
            'size': 64,
        },
        'phone':{
            'string': 'Phone',
            'type': 'char',
            'size': 64,
        },
        'currency': {
            'string': 'Currency',
            'type': 'selection',
            'selection':_get_currency,
            'required': True,
        },
        'rml_header1':{
            'string': 'Report Header',
            'type': 'char',
            'help': """This sentence will appear at the top right corner of your reports.
We suggest you to put a slogan here:
"Open Source Business Solutions".""",
            'size': 200,
        },
        'rml_footer1':{
            'string': 'Report Footer 1',
            'type': 'char',
            'help': """This sentence will appear at the bottom of your reports.
We suggest you to write legal sentences here:
Web: http://openerp.com - Fax: +32.81.73.35.01 - Fortis Bank: 126-2013269-07""",
            'size': 200,
        },
        'rml_footer2':{
            'string': 'Report Footer 2',
            'help': """This sentence will appear at the bottom of your reports.
We suggest you to put bank information here:
IBAN: BE74 1262 0121 6907 - SWIFT: CPDF BE71 - VAT: BE0477.472.701""",
            'type': 'char',
            'size': 200,
        },
        'logo':{
            'string': 'Logo',
            'type': 'binary',
        },
    }
    states={
        'init':{
            'actions': [_get_company],
            'result': {'type': 'form', 'arch': view_form_company, 'fields': fields,
                'state': [
                    ('menu', 'Cancel', 'gtk-cancel'),
                    ('finish', 'Next', 'gtk-go-forward', True)
                ]
            }
        },
        'finish':{
            'actions': [_update],
            'result': {'type': 'form', 'arch': view_form_finish, 'fields': {},
                'state': [
                    ('menu', 'Use Directly', 'gtk-ok'),
                    ('config', 'Start Configuration', 'gtk-go-forward', True)
                ]
            }
        },
        'config': {
            'result': {
                'type': 'action',
                'action': _config,
                'state': 'end',
            },
        },
        'menu': {
            'actions': [],
            'result': {'type': 'action', 'action': _menu, 'state': 'end'}
        },
    }

wizard_base_setup('base_setup.base_setup')

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

<commit_msg>[rem] selection of default profile, as profile selection is not part of the base_setup wizard anymore<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
#    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 wizard
import pooler
import time
import tools
import os

view_form_company = '''<?xml version="1.0"?>
<form string="Setup">
    <notebook colspan="4">
    <page string="General Information">
    <image name="gtk-dialog-info" colspan="2"/>
    <group>
        <separator string="Define Main Company" colspan="4"/>
        <newline/>
        <field name="name" align="0.0" colspan="4" required="True"/>
        <newline/>
        <field name="street" align="0.0"/>
        <field name="street2" align="0.0"/>
        <field name="zip" align="0.0"/>
        <field name="city" align="0.0"/>
        <field name="country_id" align="0.0"/>
        <field name="state_id" align="0.0"/>
        <field name="email" align="0.0"/>
        <field name="phone" align="0.0"/>
        <field name="currency" align="0.0"/>
    </group>
    </page>
    <page string="Report Information">
        <separator string="Report header" colspan="4"/>
        <newline/>
        <field name="rml_header1" align="0.0" colspan="4"/>
        <field name="rml_footer1" align="0.0" colspan="4"/>
        <field name="rml_footer2" align="0.0" colspan="4"/>
        <separator colspan="4" string="Your Logo - Use a size of about 450x150 pixels."/>
        <field colspan="4" name="logo" widget="image"/>
    </page>
    </notebook>
</form>'''

view_form_finish = '''<?xml version="1.0"?>
<form string="Setup">
    <image name="gtk-dialog-info" colspan="2"/>
    <group colspan="2" col="4">
        <separator colspan="4" string="Installation Done"/>
        <label align="0.0" colspan="4" string="Your new database is now fully installed."/>
        <label align="0.0" colspan="4" string="You can start configuring the system or connect directly to the database using the default setup."/>
    </group>
</form>
'''

class wizard_base_setup(wizard.interface):

    def _get_company(self, cr, uid, data, context):
        pool = pooler.get_pool(cr.dbname)
        company_obj = pool.get('res.company')
        ids=company_obj.search(cr, uid, [])
        if not ids:
            return {}
        company = company_obj.browse(cr, uid, ids)[0]

        res = {'currency': company.currency_id.id}

        for field in 'name logo rml_header1 rml_footer1 rml_footer2'.split():
            res[field] = company[field]

        if company.partner_id.address:
            address = company.partner_id.address[0]
            for field in 'street street2 zip city email phone'.split():
                res[field] = address[field]

            for field in 'country_id state_id'.split():
                if address[field]:
                    res[field] = address[field].id

        return res

    def _get_all(self, cr, uid, context, model):
        pool = pooler.get_pool(cr.dbname)
        obj = pool.get(model)
        ids = obj.search(cr, uid, [])
        res = [(o.id, o.name) for o in obj.browse(cr, uid, ids, context=context)]
        res.append((-1, ''))
        res.sort(key=lambda x: x[1])
        return res

    def _get_states(self, cr, uid, context):
        return self._get_all(cr, uid, context, 'res.country.state')

    def _get_countries(self, cr, uid, context):
        return self._get_all(cr, uid, context, 'res.country')

    def _get_currency(self, cr, uid, context):
        return self._get_all(cr, uid, context, 'res.currency')

    def _update(self, cr, uid, data, context):
        pool=pooler.get_pool(cr.dbname)
        form=data['form']

        company_obj=pool.get('res.company')
        partner_obj=pool.get('res.partner')
        address_obj=pool.get('res.partner.address')
        ids=company_obj.search(cr, uid, [])
        company=company_obj.browse(cr, uid, ids)[0]
        company_obj.write(cr, uid, [company.id], {
                'name': form['name'],
                'rml_header1': form['rml_header1'],
                'rml_footer1': form['rml_footer1'],
                'rml_footer2': form['rml_footer2'],
                'currency_id': form['currency'],
                'logo': form['logo'],
            })
        partner_obj.write(cr, uid, [company.partner_id.id], {
                'name': form['name'],
            })
        values={
                    'name': form['name'],
                    'street': form['street'],
                    'street2': form['street2'],
                    'zip': form['zip'],
                    'city': form['city'],
                    'email': form['email'],
                    'phone': form['phone'],
                }
        # we can do this, or set res.append((False, '')) in _get_all()
        if form['country_id'] > 0:
            values['country_id'] = form['country_id']
        if form['state_id'] > 0:
            values['state_id'] = form['state_id']
        if company.partner_id.address:
            address=company.partner_id.address[0]
            address_obj.write(cr, uid, [address.id], values)
        else:
            values['partner_id']=company.partner_id.id
            add_id=address_obj.create(cr, uid, values)

        cr.commit()
        (db, pool)=pooler.restart_pool(cr.dbname, update_module=True)

        return {}

    def _menu(self, cr, uid, data, context):
        users_obj=pooler.get_pool(cr.dbname).get('res.users')
        action_obj=pooler.get_pool(cr.dbname).get('ir.actions.act_window')

        ids=action_obj.search(cr, uid, [('name', '=', 'Menu')])
        menu=action_obj.browse(cr, uid, ids)[0]

        ids=users_obj.search(cr, uid, [('action_id', '=', 'Setup')])
        users_obj.write(cr, uid, ids, {'action_id': menu.id})
        ids=users_obj.search(cr, uid, [('menu_id', '=', 'Setup')])
        users_obj.write(cr, uid, ids, {'menu_id': menu.id})

        return {
            'name': menu.name,
            'type': menu.type,
            'view_id': (menu.view_id and\
                    (menu.view_id.id, menu.view_id.name)) or False,
            'domain': menu.domain,
            'res_model': menu.res_model,
            'src_model': menu.src_model,
            'view_type': menu.view_type,
            'view_mode': menu.view_mode,
            'views': menu.views,
        }

    def _config(self, cr, uid, data, context=None):
        pool = pooler.get_pool(cr.dbname)
        users_obj=pool.get('res.users')
        action_obj=pool.get('ir.actions.act_window')

        ids=action_obj.search(cr, uid, [('name', '=', 'Menu')])
        menu=action_obj.browse(cr, uid, ids)[0]

        ids=users_obj.search(cr, uid, [('action_id', '=', 'Setup')])
        users_obj.write(cr, uid, ids, {'action_id': menu.id})
        ids=users_obj.search(cr, uid, [('menu_id', '=', 'Setup')])
        users_obj.write(cr, uid, ids, {'menu_id': menu.id})

        return pool.get('res.config').next(cr, uid, [], context=context)

    fields={
        'name':{
            'string': 'Company Name',
            'type': 'char',
            'size': 64,
        },
        'street':{
            'string': 'Street',
            'type': 'char',
            'size': 128,
        },
        'street2':{
            'string': 'Street2',
            'type': 'char',
            'size': 128,
        },
        'zip':{
            'string': 'Zip code',
            'type': 'char',
            'size': 24,
        },
        'city':{
            'string': 'City',
            'type': 'char',
            'size': 128,
        },
        'state_id':{
            'string': 'State',
            'type': 'selection',
            'selection':_get_states,
        },
        'country_id':{
            'string': 'Country',
            'type': 'selection',
            'selection':_get_countries,
        },
        'email':{
            'string': 'E-mail',
            'type': 'char',
            'size': 64,
        },
        'phone':{
            'string': 'Phone',
            'type': 'char',
            'size': 64,
        },
        'currency': {
            'string': 'Currency',
            'type': 'selection',
            'selection':_get_currency,
            'required': True,
        },
        'rml_header1':{
            'string': 'Report Header',
            'type': 'char',
            'help': """This sentence will appear at the top right corner of your reports.
We suggest you to put a slogan here:
"Open Source Business Solutions".""",
            'size': 200,
        },
        'rml_footer1':{
            'string': 'Report Footer 1',
            'type': 'char',
            'help': """This sentence will appear at the bottom of your reports.
We suggest you to write legal sentences here:
Web: http://openerp.com - Fax: +32.81.73.35.01 - Fortis Bank: 126-2013269-07""",
            'size': 200,
        },
        'rml_footer2':{
            'string': 'Report Footer 2',
            'help': """This sentence will appear at the bottom of your reports.
We suggest you to put bank information here:
IBAN: BE74 1262 0121 6907 - SWIFT: CPDF BE71 - VAT: BE0477.472.701""",
            'type': 'char',
            'size': 200,
        },
        'logo':{
            'string': 'Logo',
            'type': 'binary',
        },
    }
    states={
        'init':{
            'actions': [_get_company],
            'result': {'type': 'form', 'arch': view_form_company, 'fields': fields,
                'state': [
                    ('menu', 'Cancel', 'gtk-cancel'),
                    ('finish', 'Next', 'gtk-go-forward', True)
                ]
            }
        },
        'finish':{
            'actions': [_update],
            'result': {'type': 'form', 'arch': view_form_finish, 'fields': {},
                'state': [
                    ('menu', 'Use Directly', 'gtk-ok'),
                    ('config', 'Start Configuration', 'gtk-go-forward', True)
                ]
            }
        },
        'config': {
            'result': {
                'type': 'action',
                'action': _config,
                'state': 'end',
            },
        },
        'menu': {
            'actions': [],
            'result': {'type': 'action', 'action': _menu, 'state': 'end'}
        },
    }

wizard_base_setup('base_setup.base_setup')

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
Created on 2017-7-20

@author: cheng.li
"""

import unittest
import numpy as np
import pandas as pd
from alphamind.portfolio.constraints import Constraints
from alphamind.portfolio.constraints import BoxBoundary
from alphamind.portfolio.constraints import BoundaryImpl
from alphamind.portfolio.constraints import BoundaryDirection
from alphamind.portfolio.constraints import BoundaryType
from alphamind.portfolio.constraints import create_box_bounds
from alphamind.portfolio.constraints import LinearConstraints

class TestConstraints(unittest.TestCase):

    @staticmethod
    def test_constraints():
        cons = Constraints()

        test_exp = np.array([[1., 2.],
                             [3., 4.]])
        test_names = np.array(['a', 'b'])
        cons.add_exposure(test_names, test_exp)

        test_exp = np.array([[5.],
                             [6.]])
        test_names = ['c']
        cons.add_exposure(test_names, test_exp)

        np.testing.assert_array_almost_equal(np.array([[1., 2., 5.], [3., 4., 6.]]),
                                             cons.risk_exp)

        risk_targets = cons.risk_targets()
        np.testing.assert_array_almost_equal(risk_targets[0], np.array([-np.inf, -np.inf, -np.inf]))
        np.testing.assert_array_almost_equal(risk_targets[1], np.array([np.inf, np.inf, np.inf]))

        cons.set_constraints('a', -0.1, 0.1)
        risk_targets = cons.risk_targets()
        np.testing.assert_array_almost_equal(risk_targets[0], np.array([-0.1, -np.inf, -np.inf]))
        np.testing.assert_array_almost_equal(risk_targets[1], np.array([0.1, np.inf, np.inf]))

        cons.set_constraints('c', -0.1, 0.1)
        risk_targets = cons.risk_targets()
        np.testing.assert_array_almost_equal(risk_targets[0], np.array([-0.1, -np.inf, -0.1]))
        np.testing.assert_array_almost_equal(risk_targets[1], np.array([0.1, np.inf, 0.1]))

    def test_absolute_box_boundary(self):
        lower = BoundaryImpl(BoundaryDirection.LOWER,
                             BoundaryType.ABSOLUTE,
                             -0.8)
        upper = BoundaryImpl(BoundaryDirection.UPPER,
                             BoundaryType.ABSOLUTE,
                             1.1)
        bound = BoxBoundary(lower, upper)

        center = 2.2
        l, u = bound.bounds(center)
        self.assertAlmostEqual(l, 1.4)
        self.assertAlmostEqual(u, 3.3)

    def test_relative_box_boundary(self):
        lower = BoundaryImpl(BoundaryDirection.LOWER,
                             BoundaryType.RELATIVE,
                             0.8)
        upper = BoundaryImpl(BoundaryDirection.UPPER,
                             BoundaryType.RELATIVE,
                             1.1)
        bound = BoxBoundary(lower, upper)

        center = 2.2
        l, u = bound.bounds(center)
        self.assertAlmostEqual(l, 1.76)
        self.assertAlmostEqual(u, 2.42)

    def test_create_box_bounds_single_value(self):
        names = ['a', 'b', 'c']
        b_type = BoundaryType.RELATIVE
        l_val = 0.8
        u_val = 1.1

        bounds = create_box_bounds(names,
                                   b_type,
                                   l_val,
                                   u_val)

        for key, bound in bounds.items():
            l_bound = bound.lower
            u_bound = bound.upper
            self.assertEqual(l_bound.b_type, b_type)
            self.assertEqual(u_bound.b_type, b_type)
            self.assertAlmostEqual(l_bound.val, l_val)
            self.assertAlmostEqual(u_bound.val, u_val)

    def test_create_box_bounds_multiple_values(self):
        names = ['a', 'b', 'c']
        b_type = BoundaryType.RELATIVE
        l_val = [0.9, 0.8, 1.1]
        u_val = [1.1, 1.2, 1.3]

        bounds = create_box_bounds(names,
                                   b_type,
                                   l_val,
                                   u_val)

        for i, name in enumerate(names):
            bound = bounds[name]
            l_bound = bound.lower
            u_bound = bound.upper
            self.assertEqual(l_bound.b_type, b_type)
            self.assertEqual(u_bound.b_type, b_type)
            self.assertAlmostEqual(l_bound.val, l_val[i])
            self.assertAlmostEqual(u_bound.val, u_val[i])

    def test_linear_constraints(self):
        cons_mat = np.random.randn(100, 3)
        backbone = np.random.randn(100)
        names = ['a', 'b', 'c']
        cons_mat = pd.DataFrame(cons_mat, columns=names)

        b_type = BoundaryType.ABSOLUTE
        l_val = -0.8
        u_val = 1.1

        bounds = create_box_bounds(names,
                                   b_type,
                                   l_val,
                                   u_val)

        constraints = LinearConstraints(bounds=bounds,
                                        cons_mat=cons_mat,
                                        backbone=backbone)

        l_bounds, u_bounds = constraints.risk_targets()
        risk_exp = constraints.risk_exp()

        for i, name in enumerate(names):
            center = risk_exp[:, i] @ backbone
            self.assertAlmostEqual(center + l_val, l_bounds[i])
            self.assertAlmostEqual(center + u_val, u_bounds[i])

if __name__ == '__main__':
    unittest.main()
<commit_msg>fixed test<commit_after># -*- coding: utf-8 -*-
"""
Created on 2017-7-20

@author: cheng.li
"""

import unittest
import numpy as np
import pandas as pd
from alphamind.portfolio.constraints import Constraints
from alphamind.portfolio.constraints import BoxBoundary
from alphamind.portfolio.constraints import BoundaryImpl
from alphamind.portfolio.constraints import BoundaryDirection
from alphamind.portfolio.constraints import BoundaryType
from alphamind.portfolio.constraints import create_box_bounds
from alphamind.portfolio.constraints import LinearConstraints

class TestConstraints(unittest.TestCase):

    @staticmethod
    def test_constraints():
        cons = Constraints()

        test_exp = np.array([[1., 2.],
                             [3., 4.]])
        test_names = np.array(['a', 'b'])
        cons.add_exposure(test_names, test_exp)

        test_exp = np.array([[5.],
                             [6.]])
        test_names = ['c']
        cons.add_exposure(test_names, test_exp)

        np.testing.assert_array_almost_equal(np.array([[1., 2., 5.], [3., 4., 6.]]),
                                             cons.risk_exp)

        risk_targets = cons.risk_targets()
        np.testing.assert_array_almost_equal(risk_targets[0], np.array([-np.inf, -np.inf, -np.inf]))
        np.testing.assert_array_almost_equal(risk_targets[1], np.array([np.inf, np.inf, np.inf]))

        cons.set_constraints('a', -0.1, 0.1)
        risk_targets = cons.risk_targets()
        np.testing.assert_array_almost_equal(risk_targets[0], np.array([-0.1, -np.inf, -np.inf]))
        np.testing.assert_array_almost_equal(risk_targets[1], np.array([0.1, np.inf, np.inf]))

        cons.set_constraints('c', -0.1, 0.1)
        risk_targets = cons.risk_targets()
        np.testing.assert_array_almost_equal(risk_targets[0], np.array([-0.1, -np.inf, -0.1]))
        np.testing.assert_array_almost_equal(risk_targets[1], np.array([0.1, np.inf, 0.1]))

    def test_absolute_box_boundary(self):
        lower = BoundaryImpl(BoundaryDirection.LOWER,
                             BoundaryType.ABSOLUTE,
                             -0.8)
        upper = BoundaryImpl(BoundaryDirection.UPPER,
                             BoundaryType.ABSOLUTE,
                             1.1)
        bound = BoxBoundary(lower, upper)

        center = 2.2
        l, u = bound.bounds(center)
        self.assertAlmostEqual(l, 1.4)
        self.assertAlmostEqual(u, 3.3)

    def test_relative_box_boundary(self):
        lower = BoundaryImpl(BoundaryDirection.LOWER,
                             BoundaryType.RELATIVE,
                             0.8)
        upper = BoundaryImpl(BoundaryDirection.UPPER,
                             BoundaryType.RELATIVE,
                             1.1)
        bound = BoxBoundary(lower, upper)

        center = 2.2
        l, u = bound.bounds(center)
        self.assertAlmostEqual(l, 1.76)
        self.assertAlmostEqual(u, 2.42)

    def test_create_box_bounds_single_value(self):
        names = ['a', 'b', 'c']
        b_type = BoundaryType.RELATIVE
        l_val = 0.8
        u_val = 1.1

        bounds = create_box_bounds(names,
                                   b_type,
                                   l_val,
                                   u_val)

        for key, bound in bounds.items():
            l_bound = bound.lower
            u_bound = bound.upper
            self.assertEqual(l_bound.b_type, b_type)
            self.assertEqual(u_bound.b_type, b_type)
            self.assertAlmostEqual(l_bound.val, l_val)
            self.assertAlmostEqual(u_bound.val, u_val)

    def test_create_box_bounds_multiple_values(self):
        names = ['a', 'b', 'c']
        b_type = BoundaryType.RELATIVE
        l_val = [0.9, 0.8, 1.1]
        u_val = [1.1, 1.2, 1.3]

        bounds = create_box_bounds(names,
                                   b_type,
                                   l_val,
                                   u_val)

        for i, name in enumerate(names):
            bound = bounds[name]
            l_bound = bound.lower
            u_bound = bound.upper
            self.assertEqual(l_bound.b_type, b_type)
            self.assertEqual(u_bound.b_type, b_type)
            self.assertAlmostEqual(l_bound.val, l_val[i])
            self.assertAlmostEqual(u_bound.val, u_val[i])

    def test_linear_constraints(self):
        cons_mat = np.random.randn(100, 3)
        backbone = np.random.randn(100)
        names = ['a', 'b', 'c']
        cons_mat = pd.DataFrame(cons_mat, columns=names)

        b_type = BoundaryType.ABSOLUTE
        l_val = -0.8
        u_val = 1.1

        bounds = create_box_bounds(names,
                                   b_type,
                                   l_val,
                                   u_val)

        constraints = LinearConstraints(bounds=bounds,
                                        cons_mat=cons_mat,
                                        backbone=backbone)

        l_bounds, u_bounds = constraints.risk_targets()
        risk_exp = constraints.risk_exp

        for i, name in enumerate(names):
            center = risk_exp[:, i] @ backbone
            self.assertAlmostEqual(center + l_val, l_bounds[i])
            self.assertAlmostEqual(center + u_val, u_bounds[i])

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


<commit_before>#!/usr/bin/env python3

# Copyright 2014-2016 Open Source Robotics Foundation, Inc.
#
# 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 argparse
import os
import subprocess
import sys
import time
from xml.etree import ElementTree
from xml.sax.saxutils import escape
from xml.sax.saxutils import quoteattr

import yaml

def main(argv=sys.argv[1:]):
    config_file = os.path.join(
        os.path.dirname(__file__), 'configuration', '.clang-format')
    extensions = ['c', 'cc', 'cpp', 'cxx', 'h', 'hh', 'hpp', 'hxx']

    parser = argparse.ArgumentParser(
        description='Check code style using clang_format.',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument(
        '--config',
        metavar='path',
        default=config_file,
        dest='config_file',
        help='The config file')
    parser.add_argument(
        'paths',
        nargs='*',
        default=[os.curdir],
        help='The files or directories to check. For directories files ending '
             'in %s will be considered.' %
             ', '.join(["'.%s'" % e for e in extensions]))
    parser.add_argument(
        '--reformat',
        action='store_true',
        help='Reformat the files in place')
    # not using a file handle directly
    # in order to prevent leaving an empty file when something fails early
    parser.add_argument(
        '--xunit-file',
        help='Generate a xunit compliant XML file')
    args = parser.parse_args(argv)

    if not os.path.exists(args.config_file):
        print("Could not find config file '%s'" % args.config_file,
              file=sys.stderr)
        return 1

    if args.xunit_file:
        start_time = time.time()

    files = get_files(args.paths, extensions)
    if not files:
        print('No files found', file=sys.stderr)
        return 1

    bin_names = [
        'clang-format',
        'clang-format-3.8',
        'clang-format-3.7',
        'clang-format-3.6',
        'clang-format-3.5',
        'clang-format-3.4',
        'clang-format-3.3',
    ]
    clang_format_bin = find_executable(bin_names)
    if not clang_format_bin:
        print('Could not find %s executable' %
              ' / '.join(["'%s'" % n for n in bin_names]), file=sys.stderr)
        return 1

    report = []

    # invoke clang_format
    with open(args.config_file, 'r') as h:
        content = h.read()
    data = yaml.load(content)
    style = yaml.dump(data, default_flow_style=True, width=float('inf'))
    cmd = [clang_format_bin,
           '-output-replacements-xml',
           '-style=%s' % style]
    cmd.extend(files)
    try:
        output = subprocess.check_output(cmd)
    except subprocess.CalledProcessError as e:
        print("The invocation of '%s' failed with error code %d: %s" %
              (os.path.basename(clang_format_bin), e.returncode, e),
              file=sys.stderr)
        return 1

    # output errors
    report = {}
    for filename in files:
        report[filename] = []

    xmls = output.split(b"<?xml version='1.0'?>")[1:]
    changed_files = []
    for filename, xml in zip(files, xmls):
        try:
            root = ElementTree.fromstring(xml)
        except ElementTree.ParseError as e:
            print('Invalid XML in clang format output: %s' % str(e),
                  file=sys.stderr)
            return 1

        replacements = root.findall('replacement')
        if replacements:
            changed_files.append(filename)
            if not args.reformat:
                print("Code style divergence in file '%s':" % filename,
                      file=sys.stderr)
                print('', file=sys.stderr)
            else:
                print("%d code style divergences in file '%s': reformatted "
                      'file' % (len(replacements), filename))
            with open(filename, 'r') as h:
                content = h.read()
            for replacement in replacements:
                data = {
                    'offset': int(replacement.get('offset')),
                    'length': int(replacement.get('length')),
                    'replacement': replacement.text or '',
                }
                # to-be-replaced snippet
                data['original'] = content[
                    data['offset']:data['offset'] + data['length']]
                # map global offset to line number and offset in line
                index_of_line_start = find_index_of_line_start(
                    content, data['offset'])
                index_of_line_end = find_index_of_line_end(
                    content, data['offset'] + data['length'])
                data['line_no'] = get_line_number(content, index_of_line_start)
                data['offset_in_line'] = data['offset'] - index_of_line_start

                # generate diff like changes
                subcontent = content[
                    index_of_line_start:index_of_line_end]
                data['deletion'] = subcontent
                data['addition'] = subcontent[0:data['offset_in_line']] + \
                    data['replacement'] + \
                    subcontent[data['offset_in_line'] + data['length']:]

                # make common control characters visible
                mapping = {'\n': '\\n', '\r': '\\r', '\t': '\\t'}
                for old, new in mapping.items():
                    data['replacement'] = data['replacement'].replace(old, new)
                    data['original'] = data['original'].replace(old, new)

                mapping = {'\r': '\n'}
                for old, new in mapping.items():
                    data['deletion'] = data['deletion'].replace(old, new)
                    data['addition'] = data['addition'].replace(old, new)

                # format deletion / addition as unified diff
                data['deletion'] = '\n'.join(
                    ['- ' + l for l in data['deletion'].split('\n')])
                data['addition'] = '\n'.join(
                    ['+ ' + l for l in data['addition'].split('\n')])

                report[filename].append(data)

                if not args.reformat:
                    data = dict(data)
                    data['filename'] = filename
                    print('[%(filename)s:%(line_no)d:%(offset_in_line)d]: '
                          'Replace [%(original)s] with [%(replacement)s]' %
                          data, file=sys.stderr)
                    print(data['deletion'], file=sys.stderr)
                    print(data['addition'], file=sys.stderr)
            if not args.reformat:
                print('', file=sys.stderr)
        else:
            print("No code style divergence in file '%s'" % filename)
            if not args.reformat:
                print('')

    # overwrite original with reformatted files
    if args.reformat and changed_files:
        cmd = [clang_format_bin,
               '-i',
               '-style=%s' % style]
        cmd.extend(files)
        try:
            subprocess.check_call(cmd)
        except subprocess.CalledProcessError as e:
            print("The invocation of '%s' failed with error code %d: %s" %
                  (os.path.basename(clang_format_bin), e.returncode, e),
                  file=sys.stderr)
            return 1

    # output summary
    file_count = sum(1 if report[k] else 0 for k in report.keys())
    replacement_count = sum(len(r) for r in report.values())
    if not file_count:
        print('No errors')
        rc = 0
    else:
        print('%d files with %d code style divergences' %
              (file_count, replacement_count), file=sys.stderr)
        rc = 1

    # generate xunit file
    if args.xunit_file:
        folder_name = os.path.basename(os.path.dirname(args.xunit_file))
        file_name = os.path.basename(args.xunit_file)
        suffix = '.xml'
        if file_name.endswith(suffix):
            file_name = file_name[0:-len(suffix)]
            suffix = '.xunit'
            if file_name.endswith(suffix):
                file_name = file_name[0:-len(suffix)]
        testname = '%s.%s' % (folder_name, file_name)

        xml = get_xunit_content(report, testname, time.time() - start_time)
        path = os.path.dirname(os.path.abspath(args.xunit_file))
        if not os.path.exists(path):
            os.makedirs(path)
        with open(args.xunit_file, 'w') as f:
            f.write(xml)

    return rc

def find_executable(file_names):
    paths = os.getenv('PATH').split(os.path.pathsep)
    for file_name in file_names:
        for path in paths:
            file_path = os.path.join(path, file_name)
            if os.path.isfile(file_path) and os.access(file_path, os.X_OK):
                return file_path
    return None

def get_files(paths, extensions):
    files = []
    for path in paths:
        if os.path.isdir(path):
            for dirpath, dirnames, filenames in os.walk(path):
                if 'AMENT_IGNORE' in filenames:
                    dirnames[:] = []
                    continue
                # ignore folder starting with . or _
                dirnames[:] = [d for d in dirnames if d[0] not in ['.', '_']]
                dirnames.sort()

                # select files by extension
                for filename in sorted(filenames):
                    _, ext = os.path.splitext(filename)
                    if ext in ['.%s' % e for e in extensions]:
                        files.append(os.path.join(dirpath, filename))
        if os.path.isfile(path):
            files.append(path)
    return [os.path.normpath(f) for f in files]

def find_index_of_line_start(data, offset):
    index_1 = data.rfind('\n', 0, offset) + 1
    index_2 = data.rfind('\r', 0, offset) + 1
    return max(index_1, index_2)

def find_index_of_line_end(data, offset):
    index_1 = data.find('\n', offset)
    if index_1 == -1:
        index_1 = len(data)
    index_2 = data.find('\r', offset)
    if index_2 == -1:
        index_2 = len(data)
    return min(index_1, index_2)

def get_line_number(data, offset):
    return data[0:offset].count('\n') + data[0:offset].count('\r') + 1

def get_xunit_content(report, testname, elapsed):
    test_count = sum(max(len(r), 1) for r in report.values())
    error_count = sum(len(r) for r in report.values())
    data = {
        'testname': testname,
        'test_count': test_count,
        'error_count': error_count,
        'time': '%.3f' % round(elapsed, 3),
    }
    xml = """<?xml version="1.0" encoding="UTF-8"?>
<testsuite
  name="%(testname)s"
  tests="%(test_count)d"
  failures="%(error_count)d"
  time="%(time)s"
>
""" % data

    for filename in sorted(report.keys()):
        replacements = report[filename]

        if replacements:
            # report each replacement as a failing testcase
            for replacement in replacements:
                data = {
                    'quoted_location': quoteattr(
                        '%s:%d:%d' % (
                            filename, replacement['line_no'],
                            replacement['offset_in_line'])),
                    'testname': testname,
                    'quoted_message': quoteattr(
                        'Replace [%s] with [%s]' %
                        (replacement['original'], replacement['replacement'])),
                    'cdata': '\n'.join([
                        '%s:%d:%d' % (
                            filename, replacement['line_no'],
                            replacement['offset_in_line']),
                        replacement['deletion'],
                        replacement['addition'],
                    ]),
                }
                xml += """  <testcase
    name=%(quoted_location)s
    classname="%(testname)s"
  >
      <failure message=%(quoted_message)s><![CDATA[%(cdata)s]]></failure>
  </testcase>
""" % data

        else:
            # if there are no replacements report a single successful test
            data = {
                'quoted_location': quoteattr(filename),
                'testname': testname,
            }
            xml += """  <testcase
    name=%(quoted_location)s
    classname="%(testname)s"
    status="No errors"/>
""" % data

    # output list of checked files
    data = {
        'escaped_files': escape(''.join(['\n* %s' % r
                                         for r in sorted(report.keys())])),
    }
    xml += """  <system-out>Checked files:%(escaped_files)s</system-out>
""" % data

    xml += '</testsuite>\n'
    return xml

if __name__ == '__main__':
    sys.exit(main())
<commit_msg>use safe_load instead of deprecated load (#135)<commit_after>#!/usr/bin/env python3

# Copyright 2014-2016 Open Source Robotics Foundation, Inc.
#
# 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 argparse
import os
import subprocess
import sys
import time
from xml.etree import ElementTree
from xml.sax.saxutils import escape
from xml.sax.saxutils import quoteattr

import yaml

def main(argv=sys.argv[1:]):
    config_file = os.path.join(
        os.path.dirname(__file__), 'configuration', '.clang-format')
    extensions = ['c', 'cc', 'cpp', 'cxx', 'h', 'hh', 'hpp', 'hxx']

    parser = argparse.ArgumentParser(
        description='Check code style using clang_format.',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument(
        '--config',
        metavar='path',
        default=config_file,
        dest='config_file',
        help='The config file')
    parser.add_argument(
        'paths',
        nargs='*',
        default=[os.curdir],
        help='The files or directories to check. For directories files ending '
             'in %s will be considered.' %
             ', '.join(["'.%s'" % e for e in extensions]))
    parser.add_argument(
        '--reformat',
        action='store_true',
        help='Reformat the files in place')
    # not using a file handle directly
    # in order to prevent leaving an empty file when something fails early
    parser.add_argument(
        '--xunit-file',
        help='Generate a xunit compliant XML file')
    args = parser.parse_args(argv)

    if not os.path.exists(args.config_file):
        print("Could not find config file '%s'" % args.config_file,
              file=sys.stderr)
        return 1

    if args.xunit_file:
        start_time = time.time()

    files = get_files(args.paths, extensions)
    if not files:
        print('No files found', file=sys.stderr)
        return 1

    bin_names = [
        'clang-format',
        'clang-format-3.8',
        'clang-format-3.7',
        'clang-format-3.6',
        'clang-format-3.5',
        'clang-format-3.4',
        'clang-format-3.3',
    ]
    clang_format_bin = find_executable(bin_names)
    if not clang_format_bin:
        print('Could not find %s executable' %
              ' / '.join(["'%s'" % n for n in bin_names]), file=sys.stderr)
        return 1

    report = []

    # invoke clang_format
    with open(args.config_file, 'r') as h:
        content = h.read()
    data = yaml.safe_load(content)
    style = yaml.dump(data, default_flow_style=True, width=float('inf'))
    cmd = [clang_format_bin,
           '-output-replacements-xml',
           '-style=%s' % style]
    cmd.extend(files)
    try:
        output = subprocess.check_output(cmd)
    except subprocess.CalledProcessError as e:
        print("The invocation of '%s' failed with error code %d: %s" %
              (os.path.basename(clang_format_bin), e.returncode, e),
              file=sys.stderr)
        return 1

    # output errors
    report = {}
    for filename in files:
        report[filename] = []

    xmls = output.split(b"<?xml version='1.0'?>")[1:]
    changed_files = []
    for filename, xml in zip(files, xmls):
        try:
            root = ElementTree.fromstring(xml)
        except ElementTree.ParseError as e:
            print('Invalid XML in clang format output: %s' % str(e),
                  file=sys.stderr)
            return 1

        replacements = root.findall('replacement')
        if replacements:
            changed_files.append(filename)
            if not args.reformat:
                print("Code style divergence in file '%s':" % filename,
                      file=sys.stderr)
                print('', file=sys.stderr)
            else:
                print("%d code style divergences in file '%s': reformatted "
                      'file' % (len(replacements), filename))
            with open(filename, 'r') as h:
                content = h.read()
            for replacement in replacements:
                data = {
                    'offset': int(replacement.get('offset')),
                    'length': int(replacement.get('length')),
                    'replacement': replacement.text or '',
                }
                # to-be-replaced snippet
                data['original'] = content[
                    data['offset']:data['offset'] + data['length']]
                # map global offset to line number and offset in line
                index_of_line_start = find_index_of_line_start(
                    content, data['offset'])
                index_of_line_end = find_index_of_line_end(
                    content, data['offset'] + data['length'])
                data['line_no'] = get_line_number(content, index_of_line_start)
                data['offset_in_line'] = data['offset'] - index_of_line_start

                # generate diff like changes
                subcontent = content[
                    index_of_line_start:index_of_line_end]
                data['deletion'] = subcontent
                data['addition'] = subcontent[0:data['offset_in_line']] + \
                    data['replacement'] + \
                    subcontent[data['offset_in_line'] + data['length']:]

                # make common control characters visible
                mapping = {'\n': '\\n', '\r': '\\r', '\t': '\\t'}
                for old, new in mapping.items():
                    data['replacement'] = data['replacement'].replace(old, new)
                    data['original'] = data['original'].replace(old, new)

                mapping = {'\r': '\n'}
                for old, new in mapping.items():
                    data['deletion'] = data['deletion'].replace(old, new)
                    data['addition'] = data['addition'].replace(old, new)

                # format deletion / addition as unified diff
                data['deletion'] = '\n'.join(
                    ['- ' + l for l in data['deletion'].split('\n')])
                data['addition'] = '\n'.join(
                    ['+ ' + l for l in data['addition'].split('\n')])

                report[filename].append(data)

                if not args.reformat:
                    data = dict(data)
                    data['filename'] = filename
                    print('[%(filename)s:%(line_no)d:%(offset_in_line)d]: '
                          'Replace [%(original)s] with [%(replacement)s]' %
                          data, file=sys.stderr)
                    print(data['deletion'], file=sys.stderr)
                    print(data['addition'], file=sys.stderr)
            if not args.reformat:
                print('', file=sys.stderr)
        else:
            print("No code style divergence in file '%s'" % filename)
            if not args.reformat:
                print('')

    # overwrite original with reformatted files
    if args.reformat and changed_files:
        cmd = [clang_format_bin,
               '-i',
               '-style=%s' % style]
        cmd.extend(files)
        try:
            subprocess.check_call(cmd)
        except subprocess.CalledProcessError as e:
            print("The invocation of '%s' failed with error code %d: %s" %
                  (os.path.basename(clang_format_bin), e.returncode, e),
                  file=sys.stderr)
            return 1

    # output summary
    file_count = sum(1 if report[k] else 0 for k in report.keys())
    replacement_count = sum(len(r) for r in report.values())
    if not file_count:
        print('No errors')
        rc = 0
    else:
        print('%d files with %d code style divergences' %
              (file_count, replacement_count), file=sys.stderr)
        rc = 1

    # generate xunit file
    if args.xunit_file:
        folder_name = os.path.basename(os.path.dirname(args.xunit_file))
        file_name = os.path.basename(args.xunit_file)
        suffix = '.xml'
        if file_name.endswith(suffix):
            file_name = file_name[0:-len(suffix)]
            suffix = '.xunit'
            if file_name.endswith(suffix):
                file_name = file_name[0:-len(suffix)]
        testname = '%s.%s' % (folder_name, file_name)

        xml = get_xunit_content(report, testname, time.time() - start_time)
        path = os.path.dirname(os.path.abspath(args.xunit_file))
        if not os.path.exists(path):
            os.makedirs(path)
        with open(args.xunit_file, 'w') as f:
            f.write(xml)

    return rc

def find_executable(file_names):
    paths = os.getenv('PATH').split(os.path.pathsep)
    for file_name in file_names:
        for path in paths:
            file_path = os.path.join(path, file_name)
            if os.path.isfile(file_path) and os.access(file_path, os.X_OK):
                return file_path
    return None

def get_files(paths, extensions):
    files = []
    for path in paths:
        if os.path.isdir(path):
            for dirpath, dirnames, filenames in os.walk(path):
                if 'AMENT_IGNORE' in filenames:
                    dirnames[:] = []
                    continue
                # ignore folder starting with . or _
                dirnames[:] = [d for d in dirnames if d[0] not in ['.', '_']]
                dirnames.sort()

                # select files by extension
                for filename in sorted(filenames):
                    _, ext = os.path.splitext(filename)
                    if ext in ['.%s' % e for e in extensions]:
                        files.append(os.path.join(dirpath, filename))
        if os.path.isfile(path):
            files.append(path)
    return [os.path.normpath(f) for f in files]

def find_index_of_line_start(data, offset):
    index_1 = data.rfind('\n', 0, offset) + 1
    index_2 = data.rfind('\r', 0, offset) + 1
    return max(index_1, index_2)

def find_index_of_line_end(data, offset):
    index_1 = data.find('\n', offset)
    if index_1 == -1:
        index_1 = len(data)
    index_2 = data.find('\r', offset)
    if index_2 == -1:
        index_2 = len(data)
    return min(index_1, index_2)

def get_line_number(data, offset):
    return data[0:offset].count('\n') + data[0:offset].count('\r') + 1

def get_xunit_content(report, testname, elapsed):
    test_count = sum(max(len(r), 1) for r in report.values())
    error_count = sum(len(r) for r in report.values())
    data = {
        'testname': testname,
        'test_count': test_count,
        'error_count': error_count,
        'time': '%.3f' % round(elapsed, 3),
    }
    xml = """<?xml version="1.0" encoding="UTF-8"?>
<testsuite
  name="%(testname)s"
  tests="%(test_count)d"
  failures="%(error_count)d"
  time="%(time)s"
>
""" % data

    for filename in sorted(report.keys()):
        replacements = report[filename]

        if replacements:
            # report each replacement as a failing testcase
            for replacement in replacements:
                data = {
                    'quoted_location': quoteattr(
                        '%s:%d:%d' % (
                            filename, replacement['line_no'],
                            replacement['offset_in_line'])),
                    'testname': testname,
                    'quoted_message': quoteattr(
                        'Replace [%s] with [%s]' %
                        (replacement['original'], replacement['replacement'])),
                    'cdata': '\n'.join([
                        '%s:%d:%d' % (
                            filename, replacement['line_no'],
                            replacement['offset_in_line']),
                        replacement['deletion'],
                        replacement['addition'],
                    ]),
                }
                xml += """  <testcase
    name=%(quoted_location)s
    classname="%(testname)s"
  >
      <failure message=%(quoted_message)s><![CDATA[%(cdata)s]]></failure>
  </testcase>
""" % data

        else:
            # if there are no replacements report a single successful test
            data = {
                'quoted_location': quoteattr(filename),
                'testname': testname,
            }
            xml += """  <testcase
    name=%(quoted_location)s
    classname="%(testname)s"
    status="No errors"/>
""" % data

    # output list of checked files
    data = {
        'escaped_files': escape(''.join(['\n* %s' % r
                                         for r in sorted(report.keys())])),
    }
    xml += """  <system-out>Checked files:%(escaped_files)s</system-out>
""" % data

    xml += '</testsuite>\n'
    return xml

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


<commit_before># Copyright 2014-2015 Open Source Robotics Foundation, Inc.
#
# 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 xml.sax.saxutils import escape
from xml.sax.saxutils import quoteattr

def get_xunit_content(report, testname, elapsed):
    test_count = len(report)
    error_count = sum([1 if r[1] else 0 for r in report])
    data = {
        'testname': testname,
        'test_count': test_count,
        'error_count': error_count,
        'time': '%.3f' % round(elapsed, 3),
    }
    xml = '''<?xml version="1.0" encoding="UTF-8"?>
<testsuite
  name="%(testname)s"
  tests="%(test_count)d"
  failures="%(error_count)d"
  time="%(time)s"
>
''' % data

    for (filename, diff_lines) in report:

        if diff_lines:
            # report any diff as a failing testcase
            data = {
                'quoted_location': quoteattr(filename),
                'testname': testname,
                'quoted_diff': escape(''.join(diff_lines)),
            }
            xml += '''  <testcase
    name=%(quoted_location)s
    classname="%(testname)s"
  >
      <system-err>%(quoted_diff)s</system-err>
  </testcase>
''' % data

        else:
            # if there is no diff report a single successful test
            data = {
                'quoted_location': quoteattr(filename),
                'testname': testname,
            }
            xml += '''  <testcase
    name=%(quoted_location)s
    classname="%(testname)s"
    status="No errors"/>
''' % data

    # output list of checked files
    data = {
        'escaped_files': escape(''.join(['\n* %s' % r[0] for r in report])),
    }
    xml += '''  <system-out>Checked files:%(escaped_files)s</system-out>
''' % data

    xml += '</testsuite>\n'
    return xml
<commit_msg>fix uncrustify unit test results<commit_after># Copyright 2014-2015 Open Source Robotics Foundation, Inc.
#
# 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 xml.sax.saxutils import escape
from xml.sax.saxutils import quoteattr

def get_xunit_content(report, testname, elapsed):
    test_count = len(report)
    error_count = sum([1 if r[1] else 0 for r in report])
    data = {
        'testname': testname,
        'test_count': test_count,
        'error_count': error_count,
        'time': '%.3f' % round(elapsed, 3),
    }
    xml = '''<?xml version="1.0" encoding="UTF-8"?>
<testsuite
  name="%(testname)s"
  tests="%(test_count)d"
  failures="%(error_count)d"
  time="%(time)s"
>
''' % data

    for (filename, diff_lines) in report:

        if diff_lines:
            # report any diff as a failing testcase
            data = {
                'quoted_location': quoteattr(filename),
                'testname': testname,
                'quoted_message': quoteattr(
                    'Diff with %d lines' % len(diff_lines)
                ),
                'cdata': ''.join(diff_lines),
            }
            xml += '''  <testcase
    name=%(quoted_location)s
    classname="%(testname)s"
  >
      <failure message=%(quoted_message)s><![CDATA[%(cdata)s]]></failure>
  </testcase>
''' % data

        else:
            # if there is no diff report a single successful test
            data = {
                'quoted_location': quoteattr(filename),
                'testname': testname,
            }
            xml += '''  <testcase
    name=%(quoted_location)s
    classname="%(testname)s"
    status="No errors"/>
''' % data

    # output list of checked files
    data = {
        'escaped_files': escape(''.join(['\n* %s' % r[0] for r in report])),
    }
    xml += '''  <system-out>Checked files:%(escaped_files)s</system-out>
''' % data

    xml += '</testsuite>\n'
    return xml
<|endoftext|>