<commit_before>"""Utility function to perform global search and replace in a source tree.

`perlpie` will perform a global search and replace on all files in a
directory recursively.  It's a small python wrapper around the `perl
-p -i -e` functionality, but with easier syntax.  I **strongly
recommend** running `perlpie` on files under source control.  In this
way it's easy to track your changes and if (more likely when) you
discover your regular expression was wrong you can easily revert.  I
also recommend using `grin` to test your regular expressions before
running `perlpie`.

Parameters
----------
oldstring : regular expression
    Regular expression matching the string you want to replace
newstring : string
    The string you would like to replace the oldstring with.  Note
    this is not a regular expression but the exact string. One
    exception to this rule is the at symbol `@`.  This has special
    meaning in perl, so you need an escape character for this.  See
    Examples below.

Requires
--------
perl : The underlying language we're using to perform the search and replace.

`grin <http://pypi.python.org/pypi/grin/>`_ : Grin is a tool written
by Robert Kern to wrap `grep` and `find` with python and easier
command line options.

Example
-------

Replace all occurences of foo with bar::

    perlpie foo bar

Replace numpy.testing with nipy's testing framework::

    perlpie 'from\s+numpy\.testing.*' 'from nipy.testing import *'

Replace all @slow decorators in my code with @dec.super_slow.  Here we
have to escape the @ symbol which has special meaning in perl::

    perlpie '\@slow' '\@dec.super_slow'

Remove all occurences of importing make_doctest_suite::

    perlpie 'from\snipy\.utils\.testutils.*make_doctest_suite'

"""

# notes on perl-dash-pie
# perl -p -i -e 's/oldstring/newstring/g' *
# find . -name '*.html' -print0 | xargs -0 perl -pi -e 's/oldstring/newstring/g'

from optparse import OptionParser
import subprocess

def check_deps():
    try:
        import grin
    except ImportError:
        print 'perlpie requires grin to operate.'
        print 'You can find grin in the python package index:'
        print '  http://pypi.python.org/pypi/grin/'
        return False
    # assume they have perl for now
    return True

def perl_dash_pie(oldstr, newstr):
    """Use perl to replace the oldstr with the newstr.

    Examples
    --------

    # To replace all occurences of 'import numpy as N' with 'import numpy as np'
    from nipy.utils import perlpie
    perlpie.perl_dash_pie('import\s+numpy\s+as\s+N', 'import numpy as np')
    grind | xargs perl -pi -e 's/import\s+numpy\s+as\s+N/import numpy as np/g'

    """

    cmd = "grind | xargs perl -pi -e 's/%s/%s/g'" % (oldstr, newstr)
    print cmd
    try:
        subprocess.check_call(cmd, shell=True)
    except subprocess.CalledProcessError, err:
        msg = """
        Error while executing perl_dash_pie command:
        %s
        Error:
        %s
        """ % (cmd, str(err))
        raise Exception(msg)

def main():
    param_index = __doc__.index('Parameters')
    description = __doc__[:param_index]
    usage = "usage: %prog [options] oldstring newstring"
    parser = OptionParser(usage=usage, description=description)
    (options, args) = parser.parse_args()

    if not args:
        parser.print_help()
        return

    if check_deps():
        oldstr = args[0]
        newstr = args[1]
        perl_dash_pie(oldstr, newstr)
<commit_msg>Cleanup documentation for perlpie script<commit_after>"""Perform a global search and replace on the current directory *recursively*.

This a small python wrapper around the `perl -p -i -e` functionality.
I **strongly recommend** running `perlpie` on files under source
control.  In this way it's easy to track your changes and if you
discover your regular expression was wrong you can easily revert.  I
also recommend using `grin` to test your regular expressions before
running `perlpie`.

Parameters
----------
regex : regular expression
    Regular expression matching the string you want to replace
newstring : string
    The string you would like to replace the oldstring with.  Note
    this is not a regular expression but the exact string. One
    exception to this rule is the at symbol `@`.  This has special
    meaning in perl, so you need an escape character for this.  See
    Examples below.

Requires
--------
perl : The underlying language we're using to perform the search and replace.

`grin <http://pypi.python.org/pypi/grin/>`_ : Grin is a tool written
by Robert Kern to wrap `grep` and `find` with python and easier
command line options.

Examples
--------
Replace all occurences of foo with bar::

    perlpie foo bar

Replace numpy.testing with nipy's testing framework::

    perlpie 'from\s+numpy\.testing.*' 'from nipy.testing import *'

Replace all @slow decorators in my code with @dec.super_slow.  Here we
have to escape the @ symbol which has special meaning in perl::

    perlpie '\@slow' '\@dec.super_slow'

Remove all occurences of importing make_doctest_suite::

    perlpie 'from\snipy\.utils\.testutils.*make_doctest_suite'

"""

# notes on perl-dash-pie
# perl -p -i -e 's/oldstring/newstring/g' *
# find . -name '*.html' -print0 | xargs -0 perl -pi -e 's/oldstring/newstring/g'

from optparse import OptionParser
import subprocess

usage_doc = "usage: %prog [options] regex newstring"

def check_deps():
    try:
        import grin
    except ImportError:
        print 'perlpie requires grin to operate.'
        print 'You can find grin in the python package index:'
        print '  http://pypi.python.org/pypi/grin/'
        return False
    # assume they have perl for now
    return True

def perl_dash_pie(oldstr, newstr):
    """Use perl to replace the oldstr with the newstr.

    Examples
    --------

    # To replace all occurences of 'import numpy as N' with 'import numpy as np'
    from nipy.utils import perlpie
    perlpie.perl_dash_pie('import\s+numpy\s+as\s+N', 'import numpy as np')
    grind | xargs perl -pi -e 's/import\s+numpy\s+as\s+N/import numpy as np/g'

    """

    cmd = "grind | xargs perl -pi -e 's/%s/%s/g'" % (oldstr, newstr)
    print cmd
    try:
        subprocess.check_call(cmd, shell=True)
    except subprocess.CalledProcessError, err:
        msg = """
        Error while executing perl_dash_pie command:
        %s
        Error:
        %s
        """ % (cmd, str(err))
        raise Exception(msg)

def print_extended_help(option, opt_str, value, parser, *args, **kwargs):
    print __doc__

def main():
    description = __doc__.splitlines()[0]
    usage = usage_doc
    parser = OptionParser(usage=usage, description=description)
    parser.add_option('-e', '--extended-help', action='callback',
                      callback=print_extended_help,
                      help='print extended help including examples')
    (options, args) = parser.parse_args()

    if not args:
        parser.print_help()
        return

    if check_deps():
        oldstr = args[0]
        newstr = args[1]
        perl_dash_pie(oldstr, newstr)
<|endoftext|>


<commit_before># Copyright (C) 2014  Renato Lima - Akretion
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

from odoo import models, fields, api

from ...l10n_br_fiscal.constants.fiscal import (
    TAX_FRAMEWORK,
)

class StockPicking(models.Model):
    _name = "stock.picking"
    _inherit = [
        _name,
        "l10n_br_fiscal.document.mixin",
    ]

class StockMove(models.Model):
    _name = "stock.move"
    _inherit = [
        _name,
        "l10n_br_fiscal.document.line.mixin",
    ]

    fiscal_tax_ids = fields.Many2many(
        comodel_name='l10n_br_fiscal.tax',
        relation='fiscal_move_line_tax_rel',
        column1='document_id',
        column2='fiscal_tax_id',
        string="Fiscal Taxes")

    tax_framework = fields.Selection(
        selection=TAX_FRAMEWORK,
        related="picking_id.company_id.tax_framework",
        string="Tax Framework")

    @api.onchange('product_id')
    def onchange_product_id(self):
        context = dict(self.env.context)
        parent_fiscal_category_id = context.get('parent_fiscal_category_id')
        if context.get('company_id'):
            company_id = context['company_id']
        else:
            company_id = self.env.user.company_id.id

        result = {'value': {}}
        result['value']['invoice_state'] = context.get('parent_invoice_state')

        if parent_fiscal_category_id and self.product_id and self.partner_id:

            kwargs = {
                'partner_id': self.partner_id,
                'product_id': self.product_id,
                'partner_invoice_id': self.partner_id,
                'partner_shipping_id': self.partner_id,
                'fiscal_category_id': parent_fiscal_category_id,
                'company_id': company_id,
                'context': context
            }

            result.update(self._fiscal_position_map(**kwargs))

        result_super = super(StockMove, self).onchange_product_id()
        if result_super.get('value'):
            result_super.get('value').update(result['value'])
        else:
            result_super.update(result)
        return result_super

    def _get_new_picking_values(self):
        """ Prepares a new picking for this move as it could not be assigned to
        another picking. This method is designed to be inherited. """
        result = super(StockMove, self)._get_new_picking_values()
        result.update({
            'operation_id': self.operation_id.id,
            # 'operation_line_id': self.operation_line_id.id,
        })
        return result
<commit_msg>[12.0][MIG][FIX] Map taxes.<commit_after># Copyright (C) 2014  Renato Lima - Akretion
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

from odoo import models, fields, api

from ...l10n_br_fiscal.constants.fiscal import (
    TAX_FRAMEWORK,
)

class StockPicking(models.Model):
    _name = "stock.picking"
    _inherit = [
        _name,
        "l10n_br_fiscal.document.mixin",
    ]

class StockMove(models.Model):
    _name = "stock.move"
    _inherit = [
        _name,
        "l10n_br_fiscal.document.line.mixin",
    ]

    fiscal_tax_ids = fields.Many2many(
        comodel_name='l10n_br_fiscal.tax',
        relation='fiscal_move_line_tax_rel',
        column1='document_id',
        column2='fiscal_tax_id',
        string="Fiscal Taxes")

    tax_framework = fields.Selection(
        selection=TAX_FRAMEWORK,
        related="picking_id.company_id.tax_framework",
        string="Tax Framework")

    # TODO - Is there any reason to keep it ?
    # @api.onchange('product_id')
    # def onchange_product_id(self):
    #     context = dict(self.env.context)
    #     parent_fiscal_category_id = context.get('parent_fiscal_category_id')
    #     if context.get('company_id'):
    #         company_id = context['company_id']
    #     else:
    #         company_id = self.env.user.company_id.id
    #
    #     result = {'value': {}}
    #     result['value']['invoice_state'] = context.get('parent_invoice_state')
    #
    #     if parent_fiscal_category_id and self.product_id and self.partner_id:
    #
    #         kwargs = {
    #             'partner_id': self.partner_id,
    #             'product_id': self.product_id,
    #             'partner_invoice_id': self.partner_id,
    #             'partner_shipping_id': self.partner_id,
    #             'fiscal_category_id': parent_fiscal_category_id,
    #             'company_id': company_id,
    #             'context': context
    #         }
    #
    #         result.update(self._fiscal_position_map(**kwargs))
    #
    #     result_super = super(StockMove, self).onchange_product_id()
    #     if result_super.get('value'):
    #         result_super.get('value').update(result['value'])
    #     else:
    #         result_super.update(result)
    #     return result_super

    def _get_new_picking_values(self):
        """ Prepares a new picking for this move as it could not be assigned to
        another picking. This method is designed to be inherited. """
        result = super(StockMove, self)._get_new_picking_values()
        result.update({'operation_id': self.operation_id.id})
        return result

    @api.onchange("operation_line_id")
    def _onchange_operation_line_id(self):

        # Reset Taxes
        self._remove_all_fiscal_tax_ids()
        if self.operation_line_id:
            mapping_result = self.operation_line_id.map_fiscal_taxes(
                # TODO - We need to inherit this method to identify company and
                #  the TAX FRAMEWORK. Check if there are a better way to do
                company=self.company_id or self.picking_id.company_id,
                partner=self.partner_id,
                product=self.product_id,
                ncm=self.ncm_id,
                nbm=self.nbm_id,
                nbs=self.nbs_id,
                cest=self.cest_id)

            self.cfop_id = mapping_result['cfop']
            taxes = self.env['l10n_br_fiscal.tax']
            for tax in mapping_result['taxes'].values():
                taxes |= tax
            self.fiscal_tax_ids = taxes
            self._update_taxes()

        if not self.operation_line_id:
            self.cfop_id = False
<|endoftext|>


<commit_before># Copyright 2016 Tecnativa - Antonio Espinosa
# Copyright 2012-2019 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from datetime import date
from odoo import api, fields, models
from odoo.tools import float_compare
from dateutil.relativedelta import relativedelta

class AccountAssetAsset(models.Model):
    _inherit = 'account.asset'

    annual_percentage = fields.Float(
        string='Annual depreciation percentage',
        digits=(3, 8),
        default=100.0,
    )
    method_percentage = fields.Float(
        string='Depreciation percentage',
        digits=(3, 8),
        compute="_compute_method_percentage",
        inverse="_inverse_method_percentage",
        store=True,
    )

    _sql_constraints = [
        ('annual_percentage',
         'CHECK (annual_percentage > 0 and annual_percentage <= 100)',
         'Wrong percentage!'),
    ]

    @api.depends('annual_percentage', 'method_period')
    def _compute_method_percentage(self):
        mapping = self.env['account.asset.profile'].METHOD_PERIOD_MAPPING
        for asset in self:
            asset.method_percentage = (
                asset.annual_percentage *
                mapping.get(asset.method_period, 12) / 12
            )

    @api.onchange('method_percentage')
    def _inverse_method_percentage(self):
        mapping = self.env['account.asset.profile'].METHOD_PERIOD_MAPPING
        for asset in self:
            new_percentage = (
                asset.method_percentage * 12 /
                mapping.get(asset.method_period, 12)
            )
            # Only change amount when significant delta
            if float_compare(new_percentage, self.annual_percentage, 2) != 0:
                self.annual_percentage = new_percentage

    @api.onchange('profile_id')
    def _onchange_profile_id(self):
        if self.profile_id:
            self.method_percentage = self.profile_id.method_percentage

    def _get_depreciation_stop_date(self, depreciation_start_date):
        """Compute stop date for the added method 'Percentage'."""
        if self.method_time == 'percentage':
            number = 0
            percentage = 100.0
            stop_date = depreciation_start_date
            while percentage > 0:
                if number == 0 and self.prorata:
                    days = (
                        date(stop_date.year, month=12, day=31) -
                        stop_date
                    ).days + 1
                    year_days = (
                        date(stop_date.year, month=12, day=31) -
                        date(stop_date.year, month=1, day=1)
                    ).days + 1
                    percentage -= self.annual_percentage * days / year_days
                    stop_date += relativedelta(day=31, month=12)
                else:
                    if (float_compare(
                            percentage - self.annual_percentage, 0.0, 8) >= 0):
                        stop_date += relativedelta(years=1)
                    else:
                        # Remaining percentage is not whole year
                        year_days = (
                            date(stop_date.year + 1, month=12, day=31) -
                            date(stop_date.year + 1, month=1, day=1)
                        ).days + 1
                        days = int(
                            year_days * percentage / self.annual_percentage
                        )
                        stop_date += relativedelta(days=days)
                    percentage -= self.annual_percentage
                number += 1
            return stop_date
        return super()._get_depreciation_stop_date(depreciation_start_date)

    def _compute_line_dates(self, table, start_date, stop_date):
        """Add last depreciation date when method is percentage."""
        line_dates = super()._compute_line_dates(table, start_date, stop_date)
        if self.method_time == 'percentage':
            if not line_dates or line_dates[-1] < stop_date:
                if self.method_period == 'month':
                    line_date = stop_date + relativedelta(day=31)
                if self.method_period == 'quarter':
                    m = [x for x in [3, 6, 9, 12] if x >= stop_date.month][0]
                    line_date = stop_date + relativedelta(month=m, day=31)
                elif self.method_period == 'year':
                    line_date = stop_date + relativedelta(month=12, day=31)
                line_dates.append(line_date)
        return line_dates

    def _compute_depreciation_amount_per_fiscal_year(
            self, table, line_dates, depreciation_start_date,
            depreciation_stop_date
    ):
        """"Simulate the computation like year one."""
        is_changed = self.method_time == 'percentage'
        if is_changed:
            self.method_time = 'year'
        table = super()._compute_depreciation_amount_per_fiscal_year(
            table, line_dates, depreciation_start_date,
            depreciation_stop_date,
        )
        if is_changed:
            self.method_time = 'percentage'
        return table

    def _compute_depreciation_table_lines(self, table, depreciation_start_date,
                                          depreciation_stop_date, line_dates):
        """"Simulate the computation like year one."""
        is_changed = self.method_time == 'percentage'
        if is_changed:
            self.method_time = 'year'
        super(
            AccountAssetAsset, self.with_context(
                use_percentage=True))._compute_depreciation_table_lines(
            table, depreciation_start_date, depreciation_stop_date, line_dates,
        )
        if is_changed:
            self.method_time = 'percentage'

    def _get_amount_linear(
            self, depreciation_start_date, depreciation_stop_date):
        if self.env.context.get('use_percentage', False):
            return self.depreciation_base * self.annual_percentage / 100
        return super(AccountAssetAsset, self)._get_amount_linear(
            depreciation_start_date, depreciation_stop_date)
<commit_msg>update arguments<commit_after># Copyright 2016 Tecnativa - Antonio Espinosa
# Copyright 2012-2019 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from datetime import date
from odoo import api, fields, models
from odoo.tools import float_compare
from dateutil.relativedelta import relativedelta

class AccountAssetAsset(models.Model):
    _inherit = 'account.asset'

    annual_percentage = fields.Float(
        string='Annual depreciation percentage',
        digits=(3, 8),
        default=100.0,
    )
    method_percentage = fields.Float(
        string='Depreciation percentage',
        digits=(3, 8),
        compute="_compute_method_percentage",
        inverse="_inverse_method_percentage",
        store=True,
    )

    _sql_constraints = [
        ('annual_percentage',
         'CHECK (annual_percentage > 0 and annual_percentage <= 100)',
         'Wrong percentage!'),
    ]

    @api.depends('annual_percentage', 'method_period')
    def _compute_method_percentage(self):
        mapping = self.env['account.asset.profile'].METHOD_PERIOD_MAPPING
        for asset in self:
            asset.method_percentage = (
                asset.annual_percentage *
                mapping.get(asset.method_period, 12) / 12
            )

    @api.onchange('method_percentage')
    def _inverse_method_percentage(self):
        mapping = self.env['account.asset.profile'].METHOD_PERIOD_MAPPING
        for asset in self:
            new_percentage = (
                asset.method_percentage * 12 /
                mapping.get(asset.method_period, 12)
            )
            # Only change amount when significant delta
            if float_compare(new_percentage, self.annual_percentage, 2) != 0:
                self.annual_percentage = new_percentage

    @api.onchange('profile_id')
    def _onchange_profile_id(self):
        if self.profile_id:
            self.method_percentage = self.profile_id.method_percentage

    def _get_depreciation_stop_date(self, depreciation_start_date):
        """Compute stop date for the added method 'Percentage'."""
        if self.method_time == 'percentage':
            number = 0
            percentage = 100.0
            stop_date = depreciation_start_date
            while percentage > 0:
                if number == 0 and self.prorata:
                    days = (
                        date(stop_date.year, month=12, day=31) -
                        stop_date
                    ).days + 1
                    year_days = (
                        date(stop_date.year, month=12, day=31) -
                        date(stop_date.year, month=1, day=1)
                    ).days + 1
                    percentage -= self.annual_percentage * days / year_days
                    stop_date += relativedelta(day=31, month=12)
                else:
                    if (float_compare(
                            percentage - self.annual_percentage, 0.0, 8) >= 0):
                        stop_date += relativedelta(years=1)
                    else:
                        # Remaining percentage is not whole year
                        year_days = (
                            date(stop_date.year + 1, month=12, day=31) -
                            date(stop_date.year + 1, month=1, day=1)
                        ).days + 1
                        days = int(
                            year_days * percentage / self.annual_percentage
                        )
                        stop_date += relativedelta(days=days)
                    percentage -= self.annual_percentage
                number += 1
            return stop_date
        return super()._get_depreciation_stop_date(depreciation_start_date)

    def _compute_line_dates(self, table, start_date, stop_date):
        """Add last depreciation date when method is percentage."""
        line_dates = super()._compute_line_dates(table, start_date, stop_date)
        if self.method_time == 'percentage':
            if not line_dates or line_dates[-1] < stop_date:
                if self.method_period == 'month':
                    line_date = stop_date + relativedelta(day=31)
                if self.method_period == 'quarter':
                    m = [x for x in [3, 6, 9, 12] if x >= stop_date.month][0]
                    line_date = stop_date + relativedelta(month=m, day=31)
                elif self.method_period == 'year':
                    line_date = stop_date + relativedelta(month=12, day=31)
                line_dates.append(line_date)
        return line_dates

    def _compute_depreciation_amount_per_fiscal_year(
            self, table, line_dates, depreciation_start_date,
            depreciation_stop_date
    ):
        """"Simulate the computation like year one."""
        is_changed = self.method_time == 'percentage'
        if is_changed:
            self.method_time = 'year'
        table = super()._compute_depreciation_amount_per_fiscal_year(
            table, line_dates, depreciation_start_date,
            depreciation_stop_date,
        )
        if is_changed:
            self.method_time = 'percentage'
        return table

    def _compute_depreciation_table_lines(self, table, depreciation_start_date,
                                          depreciation_stop_date, line_dates):
        """"Simulate the computation like year one."""
        is_changed = self.method_time == 'percentage'
        if is_changed:
            self.method_time = 'year'
        super(
            AccountAssetAsset, self.with_context(
                use_percentage=True))._compute_depreciation_table_lines(
            table, depreciation_start_date, depreciation_stop_date, line_dates,
        )
        if is_changed:
            self.method_time = 'percentage'

    def _get_amount_linear(
            self, depreciation_start_date, depreciation_stop_date, entry):
        if self.env.context.get('use_percentage', False):
            return self.depreciation_base * self.annual_percentage / 100
        return super(AccountAssetAsset, self)._get_amount_linear(
            depreciation_start_date, depreciation_stop_date, entry)
<|endoftext|>


<commit_before># Copyright 2017 Tecnativa - Luis M. Ontalba
# Copyright 2017 Eficent Business & IT Consult. Services <contact@eficent.com>
# Copyright 2018 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import api, fields, models

class AccountInvoice(models.Model):

    _inherit = 'account.invoice'

    eu_triangular_deal = fields.Boolean(
        string='EU Triangular deal',
        help='This invoice constitutes a triangular operation for the '
             'purposes of intra-community operations.',
        readonly=True,
        states={'draft': [('readonly', False)]},
    )

    @api.model
    def line_get_convert(self, line, part):
        """Copy from invoice to move lines"""
        res = super(AccountInvoice, self).line_get_convert(line, part)
        res['l10n_es_aeat_349_operation_key'] = line.get(
            'l10n_es_aeat_349_operation_key', False,
        )
        return res

    @api.model
    def invoice_line_move_line_get(self):
        """We pass on the operation key from invoice line to the move line"""
        ml_dicts = super(AccountInvoice, self).invoice_line_move_line_get()
        for ml_dict in ml_dicts:
            invl = self.env['account.invoice.line'].browse(ml_dict['invl_id'])
            ml_dict['l10n_es_aeat_349_operation_key'] = (
                invl.l10n_es_aeat_349_operation_key
            )
        return ml_dicts

class AccountInvoiceLine(models.Model):
    """Inheritance of account invoice line to add some fields:
    - AEAT_349_operation_key
    """
    _inherit = 'account.invoice.line'

    def _selection_operation_key(self):
        return self.env['account.move.line'].fields_get(
            allfields=['l10n_es_aeat_349_operation_key'],
        )['l10n_es_aeat_349_operation_key']['selection']

    l10n_es_aeat_349_operation_key = fields.Selection(
        selection=_selection_operation_key,
        string='AEAT 349 Operation key',
        compute='_compute_l10n_es_aeat_349_operation_key',
    )

    @api.depends('invoice_line_tax_ids', 'invoice_id.eu_triangular_deal')
    def _compute_l10n_es_aeat_349_operation_key(self):
        for rec in self:
            if rec.invoice_id.eu_triangular_deal:
                rec.l10n_es_aeat_349_operation_key = 'T'
            else:
                rec.l10n_es_aeat_349_operation_key = (
                    rec.invoice_line_tax_ids.filtered(
                        lambda x: x.l10n_es_aeat_349_operation_key
                    )[:1].l10n_es_aeat_349_operation_key
                )
<commit_msg>l10n_es_aeat_349: corrige error en el 349 cuando se generan apuntes contables asociados a una factura que no apuntan directamente a una línea de factura.<commit_after># Copyright 2017 Tecnativa - Luis M. Ontalba
# Copyright 2017 Eficent Business & IT Consult. Services <contact@eficent.com>
# Copyright 2018 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import api, fields, models

class AccountInvoice(models.Model):

    _inherit = 'account.invoice'

    eu_triangular_deal = fields.Boolean(
        string='EU Triangular deal',
        help='This invoice constitutes a triangular operation for the '
             'purposes of intra-community operations.',
        readonly=True,
        states={'draft': [('readonly', False)]},
    )

    @api.model
    def line_get_convert(self, line, part):
        """Copy from invoice to move lines"""
        res = super(AccountInvoice, self).line_get_convert(line, part)
        res['l10n_es_aeat_349_operation_key'] = line.get(
            'l10n_es_aeat_349_operation_key', False,
        )
        return res

    @api.model
    def invoice_line_move_line_get(self):
        """We pass on the operation key from invoice line to the move line"""
        ml_dicts = super(AccountInvoice, self).invoice_line_move_line_get()
        for ml_dict in ml_dicts:
            if 'invl_id' not in ml_dict:
                continue
            invl = self.env['account.invoice.line'].browse(ml_dict['invl_id'])
            ml_dict['l10n_es_aeat_349_operation_key'] = (
                invl.l10n_es_aeat_349_operation_key
            )
        return ml_dicts

class AccountInvoiceLine(models.Model):
    """Inheritance of account invoice line to add some fields:
    - AEAT_349_operation_key
    """
    _inherit = 'account.invoice.line'

    def _selection_operation_key(self):
        return self.env['account.move.line'].fields_get(
            allfields=['l10n_es_aeat_349_operation_key'],
        )['l10n_es_aeat_349_operation_key']['selection']

    l10n_es_aeat_349_operation_key = fields.Selection(
        selection=_selection_operation_key,
        string='AEAT 349 Operation key',
        compute='_compute_l10n_es_aeat_349_operation_key',
    )

    @api.depends('invoice_line_tax_ids', 'invoice_id.eu_triangular_deal')
    def _compute_l10n_es_aeat_349_operation_key(self):
        for rec in self:
            if rec.invoice_id.eu_triangular_deal:
                rec.l10n_es_aeat_349_operation_key = 'T'
            else:
                rec.l10n_es_aeat_349_operation_key = (
                    rec.invoice_line_tax_ids.filtered(
                        lambda x: x.l10n_es_aeat_349_operation_key
                    )[:1].l10n_es_aeat_349_operation_key
                )
<|endoftext|>


<commit_before># License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

{
    "name": "Romania - Partner Create by VAT",
    "category": "Localization",
    "summary": "Romania - Partner Create by VAT",
    "depends": ["l10n_ro_config"],
    "data": [],
    "license": "AGPL-3",
    "version": "14.0.1.2.0",
    "author": "NextERP Romania,"
    "Forest and Biomass Romania,"
    "Odoo Community Association (OCA)",
    "website": "https://github.com/OCA/l10n-romania",
    "installable": True,
    "development_status": "Mature",
    "maintainers": ["feketemihai"],
}
<commit_msg>l10n_ro_partner_create_by_vat 14.0.1.3.0<commit_after># License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

{
    "name": "Romania - Partner Create by VAT",
    "category": "Localization",
    "summary": "Romania - Partner Create by VAT",
    "depends": ["l10n_ro_config"],
    "data": [],
    "license": "AGPL-3",
    "version": "14.0.1.3.0",
    "author": "NextERP Romania,"
    "Forest and Biomass Romania,"
    "Odoo Community Association (OCA)",
    "website": "https://github.com/OCA/l10n-romania",
    "installable": True,
    "development_status": "Mature",
    "maintainers": ["feketemihai"],
}
<|endoftext|>


<commit_before>#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from wdom.tag import NewTagClass as NewTag
from wdom.tag import *

css_files = [
    '//cdn.jsdelivr.net/picnicss/5.1.0/picnic.min.css',
]

Button = NewTag('Button', bases=Button)
DefaultButton = NewTag('DefaultButton', 'button', Button)
PrimaryButton = NewTag('PrimaryButton', 'button', Button)
SuccessButton = NewTag('SuccessButton', 'button', Button, class_='success')
InfoButton = NewTag('InfoButton', 'button', Button)
WarningButton = NewTag('WarningButton', 'button', Button, class_='warning')
DangerButton = NewTag('DangerButton', 'button', Button, class_='error')
LinkButton = NewTag('LinkButton', 'button', Button, class_='pseudo')
<commit_msg>Add grid to picnic<commit_after>#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from wdom.tag import NewTagClass as NewTag
from wdom.tag import *

css_files = [
    '//cdn.jsdelivr.net/picnicss/5.1.0/picnic.min.css',
]

Button = NewTag('Button', bases=Button)
DefaultButton = NewTag('DefaultButton', 'button', Button)
PrimaryButton = NewTag('PrimaryButton', 'button', Button)
SuccessButton = NewTag('SuccessButton', 'button', Button, class_='success')
InfoButton = NewTag('InfoButton', 'button', Button)
WarningButton = NewTag('WarningButton', 'button', Button, class_='warning')
DangerButton = NewTag('DangerButton', 'button', Button, class_='error')
LinkButton = NewTag('LinkButton', 'button', Button, class_='pseudo')

Row = NewTag('Row', 'div', Row, class_='row')
Col1 = NewTag('Col1', 'div', Col)
Col2 = NewTag('Col2', 'div', Col)
Col3 = NewTag('Col3', 'div', Col, class_='fourth')
Col4 = NewTag('Col4', 'div', Col, class_='third')
Col5 = NewTag('Col5', 'div', Col)
Col6 = NewTag('Col6', 'div', Col, class_='half')
Col7 = NewTag('Col7', 'div', Col)
Col8 = NewTag('Col8', 'div', Col, class_='two-third')
Col9 = NewTag('Col9', 'div', Col, class_='three-fourth')
Col10 = NewTag('Col10', 'div', Col)
Col11 = NewTag('Col11', 'div', Col)
Col12 = NewTag('Col12', 'div', Col)
<|endoftext|>


<commit_before>from firedrake import *
from firedrake.petsc import PETSc
from argparse import ArgumentParser
import pandas as pd
import numpy as np
import sys

ref_to_dt = {3: 3000.0,
             4: 1500.0,
             5: 750.0,
             6: 375.0,
             7: 187.5,
             8: 93.75}

PETSc.Log.begin()
parser = ArgumentParser(description="""Run convergence test for Williamson test case 2""",
                        add_help=False)

parser.add_argument("--hybridization",
                    action="store_true",
                    help="Turn hybridization on.")

parser.add_argument("--verbose",
                    action="store_true",
                    help="Turn on energy and output print statements.")

parser.add_argument("--model_degree",
                    action="store",
                    type=int,
                    default=2,
                    help="Degree of the finite element model.")

parser.add_argument("--test",
                    action="store_true",
                    help=("Select 'True' or 'False' to enable a test run. "
                          "Default is False."))

parser.add_argument("--dumpfreq",
                    default=10,
                    type=int,
                    action="store",
                    help="Dump frequency of output.")

parser.add_argument("--help",
                    action="store_true",
                    help="Show help")

args, _ = parser.parse_known_args()

if args.help:
    help = parser.format_help()
    PETSc.Sys.Print("%s\n" % help)
    sys.exit(1)

def run_williamson2(refinement_level, dumpfreq=100, test=False,
                    verbose=True, model_degree=2, hybridization=False):

    if refinement_level not in ref_to_dt:
        raise ValueError("Refinement level must be one of "
                         "the following: [3, 4, 5, 6, 7, 8]")

    Dt = ref_to_dt[refinement_level]
    R = 6371220.
    H = Constant(5960.)
    day = 24.*60.*60.

    # Earth-sized mesh
    mesh_degree = 2
    mesh = OctahedralSphereMesh(R, refinement_level,
                                degree=mesh_degree,
                                hemisphere="both")

    global_normal = Expression(("x[0]", "x[1]", "x[2]"))
    mesh.init_cell_orientations(global_normal)

    x = SpatialCoordinate(mesh)

    # Maximum amplitude of zonal winds (m/s)
    u_0 = 2*pi*R/(12*day)
    bexpr = Expression("0.")  # No topography

    if test:
        tmax = 5*Dt
        PETSc.Sys.Print("Taking 5 time-steps\n")
    else:
        tmax = 5*day
        PETSc.Sys.Print("Running 5 day solid-body simulation\n")

    # Compatible FE spaces for velocity and depth
    Vu = FunctionSpace(mesh, "BDM", model_degree)
    VD = FunctionSpace(mesh, "DG", model_degree - 1)

    # State variables: velocity and depth
    un = Function(Vu, name="Velocity")
    Dn = Function(VD, name="Depth")

    outward_normals = CellNormal(mesh)

    def perp(u):
        return cross(outward_normals, u)

    # Initial conditions for velocity and depth (in geostrophic balance)
    u_max = Constant(u_0)
    R0 = Constant(R)
    uexpr = as_vector([-u_max*x[1]/R0, u_max*x[0]/R0, 0.0])
    h0 = Constant(H)
    Omega = Constant(7.292e-5)
    g = Constant(9.810616)
    Dexpr = h0 - ((R0 * Omega * u_max + u_max*u_max/2.0)*(x[2]*x[2]/(R0*R0)))/g
    Dn.interpolate(Dexpr)
    un.project(uexpr)
    b = Function(VD, name="Topography").interpolate(bexpr)
    Dn -= b

    # Coriolis expression (1/s)
    fexpr = 2*Omega*x[2]/R0
    Vm = FunctionSpace(mesh, "CG", mesh_degree)
    f = Function(Vm).interpolate(fexpr)

    # Build timestepping solver
    up = Function(Vu)
    Dp = Function(VD)
    dt = Constant(Dt)

    # Stage 1: Depth advection
    # DG upwinded advection for depth
    Dps = Function(VD)
    D = TrialFunction(VD)
    phi = TestFunction(VD)
    Dh = 0.5*(Dn + D)
    uh = 0.5*(un + up)
    n = FacetNormal(mesh)
    uup = 0.5*(dot(uh, n) + abs(dot(uh, n)))

    Deqn = (
        (D - Dn)*phi*dx - dt*inner(grad(phi), uh*Dh)*dx
        + dt*jump(phi)*(uup('+')*Dh('+')-uup('-')*Dh('-'))*dS
    )

    Dproblem = LinearVariationalProblem(lhs(Deqn), rhs(Deqn), Dps)
    Dsolver = LinearVariationalSolver(Dproblem,
                                      solver_parameters={'ksp_type': 'cg',
                                                         'pc_type': 'bjacobi',
                                                         'sub_pc_type': 'ilu'},
                                      options_prefix="D-advection")

    # Stage 2: U update
    Ups = Function(Vu)
    u = TrialFunction(Vu)
    v = TestFunction(Vu)
    Dh = 0.5*(Dn + Dp)
    ubar = 0.5*(un + up)
    uup = 0.5*(dot(ubar, n) + abs(dot(ubar, n)))
    uh = 0.5*(un + u)
    Upwind = 0.5*(sign(dot(ubar, n)) + 1)

    # Kinetic energy term (implicit midpoint)
    K = 0.5*(inner(0.5*(un + up), 0.5*(un + up)))
    both = lambda u: 2*avg(u)
    # u_t + gradperp.u + f)*perp(ubar) + grad(g*D + K)
    # <w, gradperp.u * perp(ubar)> = <perp(ubar).w, gradperp(u)>
    #                                = <-gradperp(w.perp(ubar))), u>
    #                                  +<< [[perp(n)(w.perp(ubar))]], u>>
    ueqn = (
        inner(u - un, v)*dx + dt*inner(perp(uh)*f, v)*dx
        - dt*inner(perp(grad(inner(v, perp(ubar)))), uh)*dx
        + dt*inner(both(perp(n)*inner(v, perp(ubar))), both(Upwind*uh))*dS
        - dt*div(v)*(g*(Dh + b) + K)*dx
    )

    Uproblem = LinearVariationalProblem(lhs(ueqn), rhs(ueqn), Ups)
    Usolver = LinearVariationalSolver(Uproblem,
                                      solver_parameters={'ksp_type': 'gmres',
                                                         'pc_type': 'bjacobi',
                                                         'sub_pc_type': 'ilu'},
                                      options_prefix="U-advection")

    # Stage 3: Implicit linear solve for u, D increments
    W = MixedFunctionSpace((Vu, VD))
    DU = Function(W)
    w, phi = TestFunctions(W)
    du, dD = split(DU)

    uDlhs = (
        inner(w, du + 0.5*dt*f*perp(du)) - 0.5*dt*div(w)*g*dD +
        phi*(dD + 0.5*dt*H*div(du))
    )*dx
    Dh = 0.5*(Dp + Dn)
    uh = 0.5*(un + up)

    uDrhs = -(
        inner(w, up - Ups)*dx
        + phi*(Dp - Dps)*dx
    )

    FuD = uDlhs - uDrhs
    DUproblem = NonlinearVariationalProblem(FuD, DU)

    if hybridization:
        parameters = {'snes_type': 'ksponly',
                      'ksp_type': 'preonly',
                      'pmat_type': 'matfree',
                      'pc_type': 'python',
                      'pc_python_type': 'scpc.HybridizationPC',
                      'hybridization': {'ksp_type': 'cg',
                                        'pc_type': 'gamg',
                                        'ksp_rtol': 1e-8,
                                        'mg_levels': {'ksp_type': 'chebyshev',
                                                      'ksp_max_it': 2,
                                                      'pc_type': 'bjacobi',
                                                      'sub_pc_type': 'ilu'}}}

    else:
        parameters = {'snes_type': 'ksponly',
                      'ksp_type': 'gmres',
                      'pc_type': 'fieldsplit',
                      'pc_fieldsplit_type': 'schur',
                      'ksp_type': 'gmres',
                      'ksp_max_it': 100,
                      'ksp_gmres_restart': 50,
                      'pc_fieldsplit_schur_fact_type': 'FULL',
                      'pc_fieldsplit_schur_precondition': 'selfp',
                      'fieldsplit_0': {'ksp_type': 'preonly',
                                       'pc_type': 'bjacobi',
                                       'sub_pc_type': 'ilu'},
                      'fieldsplit_1': {'ksp_type': 'cg',
                                       'pc_type': 'gamg',
                                       'ksp_rtol': 1e-8,
                                       'mg_levels': {'ksp_type': 'chebyshev',
                                                     'ksp_max_it': 2,
                                                     'pc_type': 'bjacobi',
                                                     'sub_pc_type': 'ilu'}}}

    DUsolver = NonlinearVariationalSolver(DUproblem,
                                          solver_parameters=parameters,
                                          options_prefix="implicit-solve")
    deltau, deltaD = DU.split()

    dumpcount = dumpfreq
    count = 0
    dirname = "results-W2/"
    if hybridization:
        dirname += "hybrid/"
    dirname += "refinement_" + str(refinement_level) + "/"
    Dfile = File(dirname + "w2_" + str(refinement_level) + ".pvd")
    eta = Function(VD, name="Surface Height")

    def dump(dumpcount, dumpfreq, count):
        dumpcount += 1
        if(dumpcount > dumpfreq):
            if verbose:
                PETSc.Sys.Print("Output: %s" % count)
            eta.assign(Dn+b)
            Dfile.write(un, Dn, eta, b)
            dumpcount -= dumpfreq
            count += 1
        return dumpcount

    # Initial output dump
    dumpcount = dump(dumpcount, dumpfreq, count)

    # Some diagnostics
    energy = []
    energy_t = assemble(0.5*inner(un, un)*Dn*dx +
                        0.5*g*(Dn + b)*(Dn + b)*dx)
    energy.append(energy_t)
    if verbose:
        PETSc.Sys.Print("Energy: %s" % energy_t)

    t = 0.0

    # Initialise u and D
    u0 = Function(Vu).assign(un)
    D0 = Function(VD).assign(Dn)

    while t < tmax - Dt/2:
        t += Dt

        # First guess for next timestep
        up.assign(un)
        Dp.assign(Dn)

        # Picard cycle
        for i in range(4):

            # Update layer depth
            Dsolver.solve()
            # Update velocity
            Usolver.solve()

            # Calculate increments for up, Dp
            DUsolver.solve()
            PETSc.Sys.Print(
                "Implicit solve finished for Picard iteration %s "
                "at t=%s.\n" % (i + 1, t)
            )

            up += deltau
            Dp += deltaD

        un.assign(up)
        Dn.assign(Dp)

        dumpcount = dump(dumpcount, dumpfreq, count)

        energy_t = assemble(0.5*inner(un, un)*Dn*dx +
                            0.5*g*(Dn + b)*(Dn + b)*dx)
        energy.append(energy_t)
        if verbose:
            PETSc.Sys.Print("Energy: %s" % energy_t)

    UerrL2 = errornorm(un, u0, norm_type="L2")
    DerrL2 = errornorm(Dn, D0, norm_type="L2")

    diffu = Function(Vu).assign(abs(un - u0))
    diffD = Function(VD).assign(abs(Dn - D0))

    # Normalized Linf error
    UerrLinf = diffu.dat.data.max() / u0.dat.data.max()
    DerrLinf = diffD.dat.data.max() / D0.dat.data.max()

    # Normalized L2 error
    UerrL2 = UerrL2/norm(u0, norm_type="L2")
    DerrL2 = DerrL2/norm(D0, norm_type="L2")

    return (UerrL2, DerrL2), (UerrLinf, DerrLinf), mesh

def compute_conv_rates(u):
    """Computes the convergence rate for this particular test case

    :arg u: a list of errors.

    Returns a list of convergence rates. Note the first element of
    the list will be empty, as there is no previous computation to
    compare with. '---' will be inserted into the first component.
    """

    u_array = np.array(u)
    rates = list(np.log2(u_array[:-1] / u_array[1:]))
    rates.insert(0, '---')
    return rates

# Collect errors and mesh information for convergence test
U_L2errs = []
D_L2errs = []
U_Linferrs = []
D_Linferrs = []
num_cells = []
for ref_level in [3, 4, 5, 6, 7]:
    L2errs, Linferrs, mesh = run_williamson2(refinement_level=ref_level,
                                             dumpfreq=args.dumpfreq,
                                             test=args.test,
                                             verbose=args.verbose,
                                             model_degree=args.model_degree,
                                             hybridization=args.hybridization)
    u_errL2, D_errL2 = L2errs
    u_errLinf, D_errLinf = Linferrs
    PETSc.Sys.Print("Normalized L2 error in velocity: %s" % u_errL2)
    PETSc.Sys.Print("Normalized L2 error in depth: %s" % D_errL2)
    PETSc.Sys.Print("Normalized Linf error in velocity: %s" % u_errLinf)
    PETSc.Sys.Print("Normalized Linf error in depth: %s" % D_errLinf)
    U_L2errs.append(u_errL2)
    D_L2errs.append(D_errL2)
    U_Linferrs.append(u_errLinf)
    D_Linferrs.append(D_errLinf)
    num_cells.append(mesh.num_cells())

u_L2rates = compute_conv_rates(U_L2errs)
D_L2rates = compute_conv_rates(D_L2errs)
u_Linfrates = compute_conv_rates(U_Linferrs)
D_Linfrates = compute_conv_rates(D_Linferrs)

data = {"NumCells": num_cells,
        "NormalizedVelocityL2Errors": U_L2errs,
        "NormalizedDepthL2Errors": D_L2errs,
        "VelocityL2Rates": u_L2rates,
        "DepthL2Rates": D_L2rates,
        "NormalizedVelocityLinfErrors": U_Linferrs,
        "NormalizedDepthLinfErrors": D_Linferrs,
        "VelocityLinfRates": u_Linfrates,
        "DepthLinfRates": D_Linfrates}

df = pd.DataFrame(data)
csv_result = "W2-convergence-test"

if args.hybridization:
    csv_result += "-hybridization"

df.to_csv(csv_result + ".csv", index=False, mode="w")
<commit_msg>Add level 8 refinement<commit_after>from firedrake import *
from firedrake.petsc import PETSc
from argparse import ArgumentParser
import pandas as pd
import numpy as np
import sys

ref_to_dt = {3: 3000.0,
             4: 1500.0,
             5: 750.0,
             6: 375.0,
             7: 187.5,
             8: 93.75}

PETSc.Log.begin()
parser = ArgumentParser(description="""Run convergence test for Williamson test case 2""",
                        add_help=False)

parser.add_argument("--hybridization",
                    action="store_true",
                    help="Turn hybridization on.")

parser.add_argument("--verbose",
                    action="store_true",
                    help="Turn on energy and output print statements.")

parser.add_argument("--model_degree",
                    action="store",
                    type=int,
                    default=2,
                    help="Degree of the finite element model.")

parser.add_argument("--test",
                    action="store_true",
                    help=("Select 'True' or 'False' to enable a test run. "
                          "Default is False."))

parser.add_argument("--dumpfreq",
                    default=10,
                    type=int,
                    action="store",
                    help="Dump frequency of output.")

parser.add_argument("--help",
                    action="store_true",
                    help="Show help")

args, _ = parser.parse_known_args()

if args.help:
    help = parser.format_help()
    PETSc.Sys.Print("%s\n" % help)
    sys.exit(1)

def run_williamson2(refinement_level, dumpfreq=100, test=False,
                    verbose=True, model_degree=2, hybridization=False):

    if refinement_level not in ref_to_dt:
        raise ValueError("Refinement level must be one of "
                         "the following: [3, 4, 5, 6, 7, 8]")

    Dt = ref_to_dt[refinement_level]
    R = 6371220.
    H = Constant(5960.)
    day = 24.*60.*60.

    # Earth-sized mesh
    mesh_degree = 2
    mesh = OctahedralSphereMesh(R, refinement_level,
                                degree=mesh_degree,
                                hemisphere="both")

    global_normal = Expression(("x[0]", "x[1]", "x[2]"))
    mesh.init_cell_orientations(global_normal)

    x = SpatialCoordinate(mesh)

    # Maximum amplitude of zonal winds (m/s)
    u_0 = 2*pi*R/(12*day)
    bexpr = Expression("0.")  # No topography

    if test:
        tmax = 5*Dt
        PETSc.Sys.Print("Taking 5 time-steps\n")
    else:
        tmax = 5*day
        PETSc.Sys.Print("Running 5 day solid-body simulation\n")

    # Compatible FE spaces for velocity and depth
    Vu = FunctionSpace(mesh, "BDM", model_degree)
    VD = FunctionSpace(mesh, "DG", model_degree - 1)

    # State variables: velocity and depth
    un = Function(Vu, name="Velocity")
    Dn = Function(VD, name="Depth")

    outward_normals = CellNormal(mesh)

    def perp(u):
        return cross(outward_normals, u)

    # Initial conditions for velocity and depth (in geostrophic balance)
    u_max = Constant(u_0)
    R0 = Constant(R)
    uexpr = as_vector([-u_max*x[1]/R0, u_max*x[0]/R0, 0.0])
    h0 = Constant(H)
    Omega = Constant(7.292e-5)
    g = Constant(9.810616)
    Dexpr = h0 - ((R0 * Omega * u_max + u_max*u_max/2.0)*(x[2]*x[2]/(R0*R0)))/g
    Dn.interpolate(Dexpr)
    un.project(uexpr)
    b = Function(VD, name="Topography").interpolate(bexpr)
    Dn -= b

    # Coriolis expression (1/s)
    fexpr = 2*Omega*x[2]/R0
    Vm = FunctionSpace(mesh, "CG", mesh_degree)
    f = Function(Vm).interpolate(fexpr)

    # Build timestepping solver
    up = Function(Vu)
    Dp = Function(VD)
    dt = Constant(Dt)

    # Stage 1: Depth advection
    # DG upwinded advection for depth
    Dps = Function(VD)
    D = TrialFunction(VD)
    phi = TestFunction(VD)
    Dh = 0.5*(Dn + D)
    uh = 0.5*(un + up)
    n = FacetNormal(mesh)
    uup = 0.5*(dot(uh, n) + abs(dot(uh, n)))

    Deqn = (
        (D - Dn)*phi*dx - dt*inner(grad(phi), uh*Dh)*dx
        + dt*jump(phi)*(uup('+')*Dh('+')-uup('-')*Dh('-'))*dS
    )

    Dproblem = LinearVariationalProblem(lhs(Deqn), rhs(Deqn), Dps)
    Dsolver = LinearVariationalSolver(Dproblem,
                                      solver_parameters={'ksp_type': 'cg',
                                                         'pc_type': 'bjacobi',
                                                         'sub_pc_type': 'ilu'},
                                      options_prefix="D-advection")

    # Stage 2: U update
    Ups = Function(Vu)
    u = TrialFunction(Vu)
    v = TestFunction(Vu)
    Dh = 0.5*(Dn + Dp)
    ubar = 0.5*(un + up)
    uup = 0.5*(dot(ubar, n) + abs(dot(ubar, n)))
    uh = 0.5*(un + u)
    Upwind = 0.5*(sign(dot(ubar, n)) + 1)

    # Kinetic energy term (implicit midpoint)
    K = 0.5*(inner(0.5*(un + up), 0.5*(un + up)))
    both = lambda u: 2*avg(u)
    # u_t + gradperp.u + f)*perp(ubar) + grad(g*D + K)
    # <w, gradperp.u * perp(ubar)> = <perp(ubar).w, gradperp(u)>
    #                                = <-gradperp(w.perp(ubar))), u>
    #                                  +<< [[perp(n)(w.perp(ubar))]], u>>
    ueqn = (
        inner(u - un, v)*dx + dt*inner(perp(uh)*f, v)*dx
        - dt*inner(perp(grad(inner(v, perp(ubar)))), uh)*dx
        + dt*inner(both(perp(n)*inner(v, perp(ubar))), both(Upwind*uh))*dS
        - dt*div(v)*(g*(Dh + b) + K)*dx
    )

    Uproblem = LinearVariationalProblem(lhs(ueqn), rhs(ueqn), Ups)
    Usolver = LinearVariationalSolver(Uproblem,
                                      solver_parameters={'ksp_type': 'gmres',
                                                         'pc_type': 'bjacobi',
                                                         'sub_pc_type': 'ilu'},
                                      options_prefix="U-advection")

    # Stage 3: Implicit linear solve for u, D increments
    W = MixedFunctionSpace((Vu, VD))
    DU = Function(W)
    w, phi = TestFunctions(W)
    du, dD = split(DU)

    uDlhs = (
        inner(w, du + 0.5*dt*f*perp(du)) - 0.5*dt*div(w)*g*dD +
        phi*(dD + 0.5*dt*H*div(du))
    )*dx
    Dh = 0.5*(Dp + Dn)
    uh = 0.5*(un + up)

    uDrhs = -(
        inner(w, up - Ups)*dx
        + phi*(Dp - Dps)*dx
    )

    FuD = uDlhs - uDrhs
    DUproblem = NonlinearVariationalProblem(FuD, DU)

    if hybridization:
        parameters = {'snes_type': 'ksponly',
                      'ksp_type': 'preonly',
                      'pmat_type': 'matfree',
                      'pc_type': 'python',
                      'pc_python_type': 'scpc.HybridizationPC',
                      'hybridization': {'ksp_type': 'cg',
                                        'pc_type': 'gamg',
                                        'ksp_rtol': 1e-8,
                                        'mg_levels': {'ksp_type': 'chebyshev',
                                                      'ksp_max_it': 2,
                                                      'pc_type': 'bjacobi',
                                                      'sub_pc_type': 'ilu'}}}

    else:
        parameters = {'snes_type': 'ksponly',
                      'ksp_type': 'gmres',
                      'pc_type': 'fieldsplit',
                      'pc_fieldsplit_type': 'schur',
                      'ksp_type': 'gmres',
                      'ksp_max_it': 100,
                      'ksp_gmres_restart': 50,
                      'pc_fieldsplit_schur_fact_type': 'FULL',
                      'pc_fieldsplit_schur_precondition': 'selfp',
                      'fieldsplit_0': {'ksp_type': 'preonly',
                                       'pc_type': 'bjacobi',
                                       'sub_pc_type': 'ilu'},
                      'fieldsplit_1': {'ksp_type': 'cg',
                                       'pc_type': 'gamg',
                                       'ksp_rtol': 1e-8,
                                       'mg_levels': {'ksp_type': 'chebyshev',
                                                     'ksp_max_it': 2,
                                                     'pc_type': 'bjacobi',
                                                     'sub_pc_type': 'ilu'}}}

    DUsolver = NonlinearVariationalSolver(DUproblem,
                                          solver_parameters=parameters,
                                          options_prefix="implicit-solve")
    deltau, deltaD = DU.split()

    dumpcount = dumpfreq
    count = 0
    dirname = "results-W2/"
    if hybridization:
        dirname += "hybrid/"
    dirname += "refinement_" + str(refinement_level) + "/"
    Dfile = File(dirname + "w2_" + str(refinement_level) + ".pvd")
    eta = Function(VD, name="Surface Height")

    def dump(dumpcount, dumpfreq, count):
        dumpcount += 1
        if(dumpcount > dumpfreq):
            if verbose:
                PETSc.Sys.Print("Output: %s" % count)
            eta.assign(Dn+b)
            Dfile.write(un, Dn, eta, b)
            dumpcount -= dumpfreq
            count += 1
        return dumpcount

    # Initial output dump
    dumpcount = dump(dumpcount, dumpfreq, count)

    # Some diagnostics
    energy = []
    energy_t = assemble(0.5*inner(un, un)*Dn*dx +
                        0.5*g*(Dn + b)*(Dn + b)*dx)
    energy.append(energy_t)
    if verbose:
        PETSc.Sys.Print("Energy: %s" % energy_t)

    t = 0.0

    # Initialise u and D
    u0 = Function(Vu).assign(un)
    D0 = Function(VD).assign(Dn)

    while t < tmax - Dt/2:
        t += Dt

        # First guess for next timestep
        up.assign(un)
        Dp.assign(Dn)

        # Picard cycle
        for i in range(4):

            # Update layer depth
            Dsolver.solve()
            # Update velocity
            Usolver.solve()

            # Calculate increments for up, Dp
            DUsolver.solve()
            PETSc.Sys.Print(
                "Implicit solve finished for Picard iteration %s "
                "at t=%s.\n" % (i + 1, t)
            )

            up += deltau
            Dp += deltaD

        un.assign(up)
        Dn.assign(Dp)

        dumpcount = dump(dumpcount, dumpfreq, count)

        energy_t = assemble(0.5*inner(un, un)*Dn*dx +
                            0.5*g*(Dn + b)*(Dn + b)*dx)
        energy.append(energy_t)
        if verbose:
            PETSc.Sys.Print("Energy: %s" % energy_t)

    UerrL2 = errornorm(un, u0, norm_type="L2")
    DerrL2 = errornorm(Dn, D0, norm_type="L2")

    diffu = Function(Vu).assign(abs(un - u0))
    diffD = Function(VD).assign(abs(Dn - D0))

    # Normalized Linf error
    UerrLinf = diffu.dat.data.max() / u0.dat.data.max()
    DerrLinf = diffD.dat.data.max() / D0.dat.data.max()

    # Normalized L2 error
    UerrL2 = UerrL2/norm(u0, norm_type="L2")
    DerrL2 = DerrL2/norm(D0, norm_type="L2")

    return (UerrL2, DerrL2), (UerrLinf, DerrLinf), mesh

def compute_conv_rates(u):
    """Computes the convergence rate for this particular test case

    :arg u: a list of errors.

    Returns a list of convergence rates. Note the first element of
    the list will be empty, as there is no previous computation to
    compare with. '---' will be inserted into the first component.
    """

    u_array = np.array(u)
    rates = list(np.log2(u_array[:-1] / u_array[1:]))
    rates.insert(0, '---')
    return rates

# Collect errors and mesh information for convergence test
U_L2errs = []
D_L2errs = []
U_Linferrs = []
D_Linferrs = []
num_cells = []
for ref_level in [3, 4, 5, 6, 7, 8]:
    L2errs, Linferrs, mesh = run_williamson2(refinement_level=ref_level,
                                             dumpfreq=args.dumpfreq,
                                             test=args.test,
                                             verbose=args.verbose,
                                             model_degree=args.model_degree,
                                             hybridization=args.hybridization)
    u_errL2, D_errL2 = L2errs
    u_errLinf, D_errLinf = Linferrs
    PETSc.Sys.Print("Normalized L2 error in velocity: %s" % u_errL2)
    PETSc.Sys.Print("Normalized L2 error in depth: %s" % D_errL2)
    PETSc.Sys.Print("Normalized Linf error in velocity: %s" % u_errLinf)
    PETSc.Sys.Print("Normalized Linf error in depth: %s" % D_errLinf)
    U_L2errs.append(u_errL2)
    D_L2errs.append(D_errL2)
    U_Linferrs.append(u_errLinf)
    D_Linferrs.append(D_errLinf)
    num_cells.append(mesh.num_cells())

u_L2rates = compute_conv_rates(U_L2errs)
D_L2rates = compute_conv_rates(D_L2errs)
u_Linfrates = compute_conv_rates(U_Linferrs)
D_Linfrates = compute_conv_rates(D_Linferrs)

data = {"NumCells": num_cells,
        "NormalizedVelocityL2Errors": U_L2errs,
        "NormalizedDepthL2Errors": D_L2errs,
        "VelocityL2Rates": u_L2rates,
        "DepthL2Rates": D_L2rates,
        "NormalizedVelocityLinfErrors": U_Linferrs,
        "NormalizedDepthLinfErrors": D_Linferrs,
        "VelocityLinfRates": u_Linfrates,
        "DepthLinfRates": D_Linfrates}

df = pd.DataFrame(data)
csv_result = "W2-convergence-test"

if args.hybridization:
    csv_result += "-hybridization"

df.to_csv(csv_result + ".csv", index=False, mode="w")
<|endoftext|>


<commit_before>import os
import subprocess

# Run this from root repo directory

root = 'Dataset'
#destination top level directory
dst_tld = 'JPG-PNG-to-MNIST-NN-Format'

split = 0.75
classes = len(os.listdir(root))

for i in range(classes):
  os.system("mkdir %s/training-images/%d" % (dst_tld, i))
  os.system("rm %s/training-images/%d/*" % (dst_tld, i))
  os.system("mkdir %s/test-images/%d" % (dst_tld, i))
  os.system("rm %s/test-images/%d/*" % (dst_tld, i))

for label_ind, label_type in enumerate(os.listdir(root)):
  if "." in label_type:
    continue
  label_path = "%s/%s" % (root, label_type)
  train_index = int(split * len(os.listdir(label_path)))
  for img_ind, img_name in enumerate(os.listdir(label_path)):
    if "JPG" not in img_name.upper():
      continue
    src = "%s/%s" % (label_path, img_name)
    if img_ind < train_index:
      train_or_test = "training-images"
    else:
      train_or_test = "test-images"
    dst = "%s/%s/%d/%d.jpg" % (dst_tld, train_or_test, label_ind, img_ind)
    os.system("cp '%s' '%s'" % (src, dst))

os.system("./%s/resize-script.sh" % dst_tld)
os.system("cp %s/train-images-idx3-ubyte.gz caffe/data/mnist" % dst_tld)
os.system("cp %s/test-images-idx3-ubyte.gz caffe/data/mnist" % dst_tld)
os.system("cp %s/test-labels-idx1-ubyte.gz caffe/data/mnist" % dst_tld)
os.system("cp %s/train-labels-idx1-ubyte.gz caffe/data/mnist" % dst_tld)
<commit_msg>remember to make training images and test images directories<commit_after>import os
import subprocess

# Run this from root repo directory

root = 'Dataset'
#destination top level directory
dst_tld = 'JPG-PNG-to-MNIST-NN-Format'

os.system("mkdir %s/training-images/" % dst_tld)
os.system("mkdir %s/test-images/" % dst_tld)

split = 0.75
classes = len(os.listdir(root))

for i in range(classes):
  os.system("mkdir %s/training-images/%d" % (dst_tld, i))
  os.system("rm %s/training-images/%d/*" % (dst_tld, i))
  os.system("mkdir %s/test-images/%d" % (dst_tld, i))
  os.system("rm %s/test-images/%d/*" % (dst_tld, i))

for label_ind, label_type in enumerate(os.listdir(root)):
  if "." in label_type:
    continue
  label_path = "%s/%s" % (root, label_type)
  train_index = int(split * len(os.listdir(label_path)))
  for img_ind, img_name in enumerate(os.listdir(label_path)):
    if "JPG" not in img_name.upper():
      continue
    src = "%s/%s" % (label_path, img_name)
    if img_ind < train_index:
      train_or_test = "training-images"
    else:
      train_or_test = "test-images"
    dst = "%s/%s/%d/%d.jpg" % (dst_tld, train_or_test, label_ind, img_ind)
    os.system("cp '%s' '%s'" % (src, dst))

os.system("./%s/resize-script.sh" % dst_tld)
os.system("cp %s/train-images-idx3-ubyte.gz caffe/data/mnist" % dst_tld)
os.system("cp %s/test-images-idx3-ubyte.gz caffe/data/mnist" % dst_tld)
os.system("cp %s/test-labels-idx1-ubyte.gz caffe/data/mnist" % dst_tld)
os.system("cp %s/train-labels-idx1-ubyte.gz caffe/data/mnist" % dst_tld)
<|endoftext|>


<commit_before>
from lastfm_stats import HttpClient, TrackParser, Datastore, Aggregator
from sqlalchemy import create_engine

class UserStats():

    def __init__(self, username, api_key):
        self.username = username
        self.client = HttpClient(api_key)
        self.ds = Datastore(create_engine('sqlite:///%s.db' % (username,)))

    def analyse(self):
        # Call API
        self.get_task_history()

        # Aggregate data from datastore
        aggregator = Aggregator(self.ds)
        self.unique_tracks(aggregator)
        self.top_five_favorite_artists(aggregator)
        self.daily_average_tracks(aggregator)
        self.most_active_weekday(aggregator)

    def save_tracks_history(self, before=None):
        json_blob = self.client.get_recent_tracks_for(self.username, before)
        if json_blob is not None:
            self.ds.save_track_list(TrackParser.parse(json_blob))

    def get_task_history(self, max_api_calls=5):
        # Retrieve recently listened to tracks data from API
        self.save_tracks_history()

        # Identify oldest saved track for user, then retrieve historical listens
        # This is done exactly 4 times
        for _ in range(max_api_calls-1):
            uts = self.ds.oldest_listening_uts()
            self.save_tracks_history(uts)

    def unique_tracks(self, aggregator):
        unique_tracks = aggregator.count_unique_tracks()
        if unique_tracks != 0:
            print 'You have listened to a total of %d tracks.' % (unique_tracks,)
        else:
            print 'You never listened to any track so far.'

    def top_five_favorite_artists(self, aggregator):
        top_five = aggregator.top_five_favorite_artists()
        if top_five:
            print 'Your top 5 favorite artists: %s.' % (", ".join(top_five),)
        else:
            print 'You haven\'t got favorite artists yet.'

    def daily_average_tracks(self, aggregator):
        print 'You listen to an average of %d tracks a day.' % \
              (aggregator.daily_average_tracks(),)

    def most_active_weekday(self, aggregator):
        day = aggregator.most_active_weekday()
        if day is not None:
            print 'Your most active day is %s.' % (day,)
        else:
            print 'You haven\'t had a most active day yet.'<commit_msg>Refactoring and introduce check that avoids useless API calls<commit_after>
from lastfm_stats import HttpClient, TrackParser, Datastore, Aggregator
from sqlalchemy import create_engine

class UserStats():

    def __init__(self, username, api_key):
        self.username = username
        self.client = HttpClient(api_key)
        self.ds = Datastore(create_engine('sqlite:///%s.db' % (username,)))

    def acquire_track_history(self, before=None):
        json_blob = self.client.get_recent_tracks_for(self.username, before)
        if json_blob is not None:
            self.ds.save_track_list(TrackParser.parse(json_blob))

    def update_user_task_history(self, max_api_calls=5):
        # Retrieve recently listened to tracks data from API
        self.acquire_track_history()
        for _ in range(max_api_calls-1):
            # Identify oldest saved track for user
            uts = self.ds.oldest_listening_uts()
            if uts is None: # API has no data for this user: stop calling it
                break
            self.acquire_track_history(uts) # Backfill history of tracks

    def unique_tracks(self, aggregator):
        unique_tracks = aggregator.count_unique_tracks()
        if unique_tracks != 0:
            print 'You have listened to a total of %d tracks.' % (unique_tracks,)
        else:
            print 'You never listened to any track so far.'

    def top_five_favorite_artists(self, aggregator):
        top_five = aggregator.top_five_favorite_artists()
        if top_five:
            print 'Your top 5 favorite artists: %s.' % (", ".join(top_five),)
        else:
            print 'You haven\'t got favorite artists yet.'

    def daily_average_tracks(self, aggregator):
        print 'You listen to an average of %d tracks a day.' % \
              (aggregator.daily_average_tracks(),)

    def most_active_weekday(self, aggregator):
        day = aggregator.most_active_weekday()
        if day is not None:
            print 'Your most active day is %s.' % (day,)
        else:
            print 'You haven\'t had a most active day yet.'

    def analyse(self):
        # Acquire user raw data and save it
        self.update_user_task_history()

        # Aggregate data from datastore
        aggregator = Aggregator(self.ds)
        self.unique_tracks(aggregator)
        self.top_five_favorite_artists(aggregator)
        self.daily_average_tracks(aggregator)
        self.most_active_weekday(aggregator)<|endoftext|>


<commit_before>VERSION = (0, 3)
<commit_msg>Version 0.3.1<commit_after>VERSION = (0, 3, 1)
<|endoftext|>


<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
This bot retreives a list of anonymous editors on the wiki in the
last few hours and tries to identify proxies within that list.
"""
#
# (C) User:Huji, 2020
#
# Distributed under the terms of the CC-BY-SA 4.0 license.
#

import pywikibot
import re
from pywikibot.data import api

class ANBcounter():
    def __init__(self):
        self.site = pywikibot.Site()
        self.summary = 'روزآمدسازی آمار'
        self.last_updated = 'ویکی‌پدیا:تابلوی اعلانات مدیران/آخرین شمارش'
        self.level2pages = [
            'ویکی‌پدیا:تابلوی اعلانات مدیران/نام‌های کاربری نامناسب',
            'ویکی‌پدیا:تابلوی اعلانات مدیران/نقض ۳ برگردان',
            'ویکی‌پدیا:درخواست انتقال',
            'ویکی‌پدیا:درخواست ادغام تاریخچه',
            'ویکی‌پدیا:درخواست برای دسترسی/گشت‌زن',
            'ویکی‌پدیا:درخواست برای دسترسی/گشت خودکار',
            'ویکی‌پدیا:درخواست احیا'
        ]
        self.level3pages = [
            'ویکی‌پدیا:درخواست برای دسترسی/واگردان',
            'ویکی‌پدیا:درخواست برای دسترسی/معافیت از قطع دسترسی ' +
            'نشانی اینترنتی',
            'ویکی‌پدیا:درخواست برای دسترسی/ویرایشگر خودکار',
            'ویکی‌پدیا:درخواست برای دسترسی/ویرایشگر الگو'
        ]
        self.protection_requests = 'ویکی‌پدیا:درخواست محافظت صفحه'

    def get_sections(self, text, level=2):
        if level == 3:
            pat = '\n===[^=]+===\n'
        else:
            pat = '\n==[^=]+==\n'

        sections = re.split(pat, text)
        sections = sections[1:]
        return sections

    def count_open(self, sections):
        count = 0
        for s in sections:
            if not re.match(r'\{\{بسته', s.strip()):
                count += 1

        return count

    def update_count(self, title, count, suffix=''):
        stat_title = title + '/شمار' + suffix
        stat_page = pywikibot.Page(self.site, stat_title)
        stat_page.text = '{{subst:formatnum:' + str(count) + '}}'
        stat_page.save(summary=self.summary, minor=False, botflag=False)

    def run_each(self):
        for title in self.level2pages:
            page = pywikibot.Page(self.site, title)
            sections = self.get_sections(page.text, 2)
            count = self.count_open(sections)
            self.update_count(title, count)

        for title in self.level3pages:
            page = pywikibot.Page(self.site, title)
            sections = self.get_sections(page.text, 3)
            count = self.count_open(sections)
            self.update_count(title, count)

    def run_protection_requests(self):
        page = pywikibot.Page(self.site, self.protection_requests)
        parent = self.get_sections(page.text, 2)
        # protection requests
        sections = self.get_sections(parent[0], 3)
        count = self.count_open(sections)
        self.update_count(self.protection_requests, count)
        # unprotection requests
        sections = self.get_sections(parent[1], 3)
        count = self.count_open(sections)
        self.update_count(self.protection_requests, count, '/۲')

    def run(self):
        self.run_each()
        self.run_protection_requests()

        page = pywikibot.Page(self.site, self.last_updated)
        page.text = '~~~~~'
        page.save(summary=self.summary, minor=False, botflag=False)

robot = ANBcounter()
robot.run()
<commit_msg>Adding the admin/bureaucrat noticeboards<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
This bot retreives a list of anonymous editors on the wiki in the
last few hours and tries to identify proxies within that list.
"""
#
# (C) User:Huji, 2020
#
# Distributed under the terms of the CC-BY-SA 4.0 license.
#

import pywikibot
import re
from pywikibot.data import api

class ANBcounter():
    def __init__(self):
        self.site = pywikibot.Site()
        self.summary = 'روزآمدسازی آمار'
        self.last_updated = 'ویکی‌پدیا:تابلوی اعلانات مدیران/آخرین شمارش'
        self.level2pages = [
            'ویکی‌پدیا:تابلوی اعلانات مدیران/نام‌های کاربری نامناسب',
            'ویکی‌پدیا:تابلوی اعلانات مدیران/نقض ۳ برگردان',
            'ویکی‌پدیا:درخواست انتقال',
            'ویکی‌پدیا:درخواست ادغام تاریخچه',
            'ویکی‌پدیا:درخواست برای دسترسی/گشت‌زن',
            'ویکی‌پدیا:درخواست برای دسترسی/گشت خودکار',
            'ویکی‌پدیا:درخواست احیا',
            'ویکی‌پدیا:تابلوی اعلانات مدیران',
            'ویکی‌پدیا:تابلوی اعلانات دیوان‌سالاران'
        ]
        self.level3pages = [
            'ویکی‌پدیا:درخواست برای دسترسی/واگردان',
            'ویکی‌پدیا:درخواست برای دسترسی/معافیت از قطع دسترسی ' +
            'نشانی اینترنتی',
            'ویکی‌پدیا:درخواست برای دسترسی/ویرایشگر خودکار',
            'ویکی‌پدیا:درخواست برای دسترسی/ویرایشگر الگو'
        ]
        self.protection_requests = 'ویکی‌پدیا:درخواست محافظت صفحه'

    def get_sections(self, text, level=2):
        if level == 3:
            pat = '\n===[^=]+===\n'
        else:
            pat = '\n==[^=]+==\n'

        sections = re.split(pat, text)
        sections = sections[1:]
        return sections

    def count_open(self, sections):
        count = 0
        for s in sections:
            if not re.match(r'\{\{بسته', s.strip()):
                count += 1

        return count

    def update_count(self, title, count, suffix=''):
        stat_title = title + '/شمار' + suffix
        stat_page = pywikibot.Page(self.site, stat_title)
        stat_page.text = '{{subst:formatnum:' + str(count) + '}}'
        stat_page.save(summary=self.summary, minor=False, botflag=False)

    def run_each(self):
        for title in self.level2pages:
            page = pywikibot.Page(self.site, title)
            sections = self.get_sections(page.text, 2)
            count = self.count_open(sections)
            self.update_count(title, count)

        for title in self.level3pages:
            page = pywikibot.Page(self.site, title)
            sections = self.get_sections(page.text, 3)
            count = self.count_open(sections)
            self.update_count(title, count)

    def run_protection_requests(self):
        page = pywikibot.Page(self.site, self.protection_requests)
        parent = self.get_sections(page.text, 2)
        # protection requests
        sections = self.get_sections(parent[0], 3)
        count = self.count_open(sections)
        self.update_count(self.protection_requests, count)
        # unprotection requests
        sections = self.get_sections(parent[1], 3)
        count = self.count_open(sections)
        self.update_count(self.protection_requests, count, '/۲')

    def run(self):
        self.run_each()
        self.run_protection_requests()

        page = pywikibot.Page(self.site, self.last_updated)
        page.text = '~~~~~'
        page.save(summary=self.summary, minor=False, botflag=False)

robot = ANBcounter()
robot.run()
<|endoftext|>


<commit_before>import tempfile
import socket
import os
import signal
from shutil import rmtree
from time import sleep
from datetime import datetime
from subprocess import Popen, PIPE

import requests

__all__ = ['ElasticSearchServer']

def _unused_port():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost', 0))
    _, port = sock.getsockname()
    sock.close()
    return port

class ElasticSearchServer(object):
    def __init__(self, root=None, cmd=None, foreground=True):
        """
        root:  Root directory for elasticsearch data and logs. This directory will
               contain index data and logs for this instance of elasticsearch.

               http://www.elastic.co/guide/en/elasticsearch/reference/current/setup-dir-layout.html

               If you specify a `root` directory, it will not be removed on
               exit. This gives you a chance to look at logs and preserve (or
               reuse) data.
        cmd: The `elasticsearch` command to run if `elasticsearch` is not in $PATH.

        Usage of this class:

            with ElasticSearch(root="/tmp/testing.elasticsearch") as es:
                es = YourElasticSearchClient(es.uri())

            # elasticsearch terminated here when context exits
        """
        if cmd is None:
            es_check = Popen(['which', 'elasticsearch'], stdout=PIPE)
            cmd = es_check.stdout.read().strip()
        self._cmd = cmd

        self._foreground = foreground

        self._use_tmp_dir = False
        self._root = root
        self._es_pid = None
        self._owner_pid = os.getpid()

        self._bind_host = None
        self._bind_port = None

    def __del__(self):
        self.stop()

    def __enter__(self):
        self.start()
        return self

    def __exit__(self, *args):
        self.stop()

    def uri(self):
        """
        Returns the elasticsearch uri for the testing instance.
        """
        if not self._bind_host or not self._bind_port:
            return
        return "http://{0._bind_host}:{0._bind_port}".format(self)

    def _configure(self):
        """
        Configure this instance of elasticsearch before trying to start the
        server.

        This method exists mainly for unit test hooks so that we can prepare
        to start the elasticsearch server without actually making it start up,
        which takes a relatively long time.
        """
        # setup home dir
        if not self._root:
            self._use_tmp_dir = True
            self._root = tempfile.mkdtemp(suffix='-elastic')

        self._data_path = os.path.join(self._root, 'data')
        self._logs_path = os.path.join(self._root, 'logs')

        self._bind_host = "127.0.0.1"
        self._bind_port = _unused_port()

    def start(self):
        """
        Start the test elasticsearch instance.
        """
        if self._es_pid:
            # already started
            return

        self._configure()

        pid = os.fork()
        if pid == 0:
            bind_host = '-Des.network.bind_host=%s' % self._bind_host
            network_host = '-Des.network.host=%s' % self._bind_host
            bind_port = '-Des.http.port=%s' % self._bind_port
            data_path = '-Des.path.data=%s' % self._data_path
            logs_path = '-Des.path.logs=%s' % self._logs_path

            # Older version of elastic don't automatically stay in the foreground
            # and need to be instructed with '-f'
            foreground = ""
            if self._foreground:
                foreground = "-f"

            try:
                os.execl(
                    self._cmd,
                    self._cmd,
                    bind_host,
                    network_host,
                    bind_port,
                    data_path,
                    logs_path,

                    # Disable this instance from trying to join a cluster.
                    "-Des.node.master=true",
                    "-Des.node.local=true",
                    "-Des.discovery.zen.ping.multicast.enabled=false",
                    "-Des.logger.level=DEBUG",
                    foreground
                )
            except Exception:
                raise RuntimeError("Could not start elasticsearch.")
        else:
            while True:
                try:
                    result = requests.get(self.uri())
                    if result.status_code == 200:
                        break
                except requests.exceptions.ConnectionError:
                    # service not up yet, ignore.
                    pass

                if os.waitpid(pid, os.WNOHANG)[0] != 0:
                    raise RuntimeError("Failed to start elasticsearch.")

                sleep(0.5)
            self._es_pid = pid

    def stop(self):
        """
        Stop the test elasticsearch instance.
        """
        if self._owner_pid == os.getpid() and self._es_pid:
            self._terminate()
            self._cleanup()

    def _terminate(self):
        os.kill(self._es_pid, signal.SIGTERM)
        killed_at = datetime.now()

        try:
            while (os.waitpid(self._es_pid, os.WNOHANG)):
                if (datetime.now() - killed_at).seconds > 10.0:
                    os.kill(self._es_pid, signal.SIGKILL)
                    raise RuntimeError("Unable to cleanly stop elasticsearch.")
                sleep(0.1)
        except:
            # Child process already terminated.
            pass

        self._bind_host = None
        self._bind_port = None
        self._es_pid = None

    def _cleanup(self):
        if self._use_tmp_dir and os.path.exists(self._root):
            rmtree(self._root, ignore_errors=True)
<commit_msg>check for elasticsearch on path<commit_after>import tempfile
import socket
import os
import signal
from shutil import rmtree
from time import sleep
from datetime import datetime
from subprocess import Popen, PIPE

import requests

__all__ = ['ElasticSearchServer']

def _unused_port():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost', 0))
    _, port = sock.getsockname()
    sock.close()
    return port

class ElasticSearchServer(object):
    def __init__(self, root=None, cmd=None, foreground=True):
        """
        root:  Root directory for elasticsearch data and logs. This directory will
               contain index data and logs for this instance of elasticsearch.

               http://www.elastic.co/guide/en/elasticsearch/reference/current/setup-dir-layout.html

               If you specify a `root` directory, it will not be removed on
               exit. This gives you a chance to look at logs and preserve (or
               reuse) data.
        cmd: The `elasticsearch` command to run if `elasticsearch` is not in $PATH.

        Usage of this class:

            with ElasticSearch(root="/tmp/testing.elasticsearch") as es:
                es = YourElasticSearchClient(es.uri())

            # elasticsearch terminated here when context exits
        """
        if cmd is None:
            es_check = Popen(['which', 'elasticsearch'], stdout=PIPE)
            cmd = es_check.stdout.read().strip()
        if not cmd or len(cmd) == 0:
            raise RuntimeError("Failed to find elasticsearch please add to PATH or provide location in cmd")

        self._cmd = cmd

        self._foreground = foreground

        self._use_tmp_dir = False
        self._root = root
        self._es_pid = None
        self._owner_pid = os.getpid()

        self._bind_host = None
        self._bind_port = None

    def __del__(self):
        self.stop()

    def __enter__(self):
        self.start()
        return self

    def __exit__(self, *args):
        self.stop()

    def uri(self):
        """
        Returns the elasticsearch uri for the testing instance.
        """
        if not self._bind_host or not self._bind_port:
            return
        return "http://{0._bind_host}:{0._bind_port}".format(self)

    def _configure(self):
        """
        Configure this instance of elasticsearch before trying to start the
        server.

        This method exists mainly for unit test hooks so that we can prepare
        to start the elasticsearch server without actually making it start up,
        which takes a relatively long time.
        """
        # setup home dir
        if not self._root:
            self._use_tmp_dir = True
            self._root = tempfile.mkdtemp(suffix='-elastic')

        self._data_path = os.path.join(self._root, 'data')
        self._logs_path = os.path.join(self._root, 'logs')

        self._bind_host = "127.0.0.1"
        self._bind_port = _unused_port()

    def start(self):
        """
        Start the test elasticsearch instance.
        """
        if self._es_pid:
            # already started
            return

        self._configure()

        pid = os.fork()
        if pid == 0:
            bind_host = '-Des.network.bind_host=%s' % self._bind_host
            network_host = '-Des.network.host=%s' % self._bind_host
            bind_port = '-Des.http.port=%s' % self._bind_port
            data_path = '-Des.path.data=%s' % self._data_path
            logs_path = '-Des.path.logs=%s' % self._logs_path

            # Older version of elastic don't automatically stay in the foreground
            # and need to be instructed with '-f'
            foreground = ""
            if self._foreground:
                foreground = "-f"

            try:
                os.execl(
                    self._cmd,
                    self._cmd,
                    bind_host,
                    network_host,
                    bind_port,
                    data_path,
                    logs_path,

                    # Disable this instance from trying to join a cluster.
                    "-Des.node.master=true",
                    "-Des.node.local=true",
                    "-Des.discovery.zen.ping.multicast.enabled=false",
                    "-Des.logger.level=DEBUG",
                    foreground
                )
            except Exception:
                raise RuntimeError("Could not start elasticsearch.")
        else:
            while True:
                try:
                    result = requests.get(self.uri())
                    if result.status_code == 200:
                        break
                except requests.exceptions.ConnectionError:
                    # service not up yet, ignore.
                    pass

                if os.waitpid(pid, os.WNOHANG)[0] != 0:
                    raise RuntimeError("Failed to start elasticsearch.")

                sleep(0.5)
            self._es_pid = pid

    def stop(self):
        """
        Stop the test elasticsearch instance.
        """
        if self._owner_pid == os.getpid() and self._es_pid:
            self._terminate()
            self._cleanup()

    def _terminate(self):
        os.kill(self._es_pid, signal.SIGTERM)
        killed_at = datetime.now()

        try:
            while (os.waitpid(self._es_pid, os.WNOHANG)):
                if (datetime.now() - killed_at).seconds > 10.0:
                    os.kill(self._es_pid, signal.SIGKILL)
                    raise RuntimeError("Unable to cleanly stop elasticsearch.")
                sleep(0.1)
        except:
            # Child process already terminated.
            pass

        self._bind_host = None
        self._bind_port = None
        self._es_pid = None

    def _cleanup(self):
        if self._use_tmp_dir and os.path.exists(self._root):
            rmtree(self._root, ignore_errors=True)
<|endoftext|>