<commit_before>#
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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 unittest

import svn.core, svn.client
import utils

class SubversionCoreTestCase(unittest.TestCase):
  """Test cases for the basic SWIG Subversion core"""

  def test_SubversionException(self):
    self.assertEqual(svn.core.SubversionException().args, ())
    self.assertEqual(svn.core.SubversionException('error message').args,
                     ('error message',))
    self.assertEqual(svn.core.SubversionException(None, 1).args, (None, 1))
    self.assertEqual(svn.core.SubversionException('error message', 1).args,
                     ('error message', 1))
    self.assertEqual(svn.core.SubversionException('error message', 1).apr_err,
                     1)
    self.assertEqual(svn.core.SubversionException('error message', 1).message,
                     'error message')

  def test_mime_type_is_binary(self):
    self.assertEqual(0, svn.core.svn_mime_type_is_binary("text/plain"))
    self.assertEqual(1, svn.core.svn_mime_type_is_binary("image/png"))

  def test_mime_type_validate(self):
    self.assertRaises(svn.core.SubversionException,
            svn.core.svn_mime_type_validate, "this\nis\ninvalid\n")
    svn.core.svn_mime_type_validate("unknown/but-valid; charset=utf8")

  def test_exception_interoperability(self):
    """Test if SubversionException is correctly converted into svn_error_t
    and vice versa."""
    t = utils.Temper()
    (_, _, repos_uri) = t.alloc_empty_repo(suffix='-core')
    rev = svn.core.svn_opt_revision_t()
    rev.kind = svn.core.svn_opt_revision_head
    ctx = svn.client.create_context()

    class Receiver:
      def __call__(self, path, info, pool):
        raise self.e

    rec = Receiver()
    args = (repos_uri, rev, rev, rec, svn.core.svn_depth_empty, None, ctx)

    try:
      # ordinary Python exceptions must be passed through
      rec.e = TypeError()
      self.assertRaises(TypeError, svn.client.info2, *args)

      # SubversionException will be translated into an svn_error_t, propagated
      # through the call chain and translated back to SubversionException.
      rec.e = svn.core.SubversionException("Bla bla bla.",
                                           svn.core.SVN_ERR_INCORRECT_PARAMS,
                                           file=__file__, line=866)
      rec.e.child = svn.core.SubversionException("Yada yada.",
                                             svn.core.SVN_ERR_INCOMPLETE_DATA)
      self.assertRaises(svn.core.SubversionException, svn.client.info2, *args)

      # It must remain unchanged through the process.
      try:
        svn.client.info2(*args)
      except svn.core.SubversionException, exc:
        # find the original exception
        while exc.file != rec.e.file: exc = exc.child

        self.assertEqual(exc.message, rec.e.message)
        self.assertEqual(exc.apr_err, rec.e.apr_err)
        self.assertEqual(exc.line, rec.e.line)
        self.assertEqual(exc.child.message, rec.e.child.message)
        self.assertEqual(exc.child.apr_err, rec.e.child.apr_err)
        self.assertEqual(exc.child.child, None)
        self.assertEqual(exc.child.file, None)
        self.assertEqual(exc.child.line, 0)

      # Incomplete SubversionExceptions must trigger Python exceptions, which
      # will be passed through.
      rec.e = svn.core.SubversionException("No fields except message.")
      # e.apr_err is None but should be an int
      self.assertRaises(TypeError, svn.client.info2, args)
    finally:
      # This would happen without the finally block as well, but we expliticly
      # order the operations so that the cleanup is not hindered by any open
      # handles.
      del ctx
      t.cleanup()

  def test_config_enumerate2(self):
    cfg = svn.core.svn_config_create(False)
    entries = {
      'one': 'one-value',
      'two': 'two-value',
      'three': 'three-value'
    }

    for (name, value) in entries.iteritems():
      svn.core.svn_config_set(cfg, "section", name, value)

    received_entries = {}
    def enumerator(name, value, pool):
      received_entries[name] = value
      return len(received_entries) < 2

    svn.core.svn_config_enumerate2(cfg, "section", enumerator)

    self.assertEqual(len(received_entries), 2)
    for (name, value) in received_entries.iteritems():
      self.assertTrue(name in entries)
      self.assertEqual(value, entries[name])

  def test_config_enumerate2_exception(self):
    cfg = svn.core.svn_config_create(False)
    svn.core.svn_config_set(cfg, "section", "one", "one-value")
    svn.core.svn_config_set(cfg, "section", "two", "two-value")

    received_entries = {}

    def enumerator(name, value, pool):
      received_entries[name] = value
      raise Exception

    svn.core.svn_config_enumerate2(cfg, "section", enumerator)
    # the exception is swallowed, but enumeration must be stopped
    self.assertEqual(len(received_entries), 1)

def suite():
    return unittest.defaultTestLoader.loadTestsFromTestCase(
      SubversionCoreTestCase)

if __name__ == '__main__':
    runner = unittest.TextTestRunner()
    runner.run(suite())
<commit_msg>* subversion/bindings/swig/python/tests/core.py:   (SubversionCoreTestCase.test_exception_interoperability): Fix a typo that     made the test pass for the wrong reasons.<commit_after>#
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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 unittest

import svn.core, svn.client
import utils

class SubversionCoreTestCase(unittest.TestCase):
  """Test cases for the basic SWIG Subversion core"""

  def test_SubversionException(self):
    self.assertEqual(svn.core.SubversionException().args, ())
    self.assertEqual(svn.core.SubversionException('error message').args,
                     ('error message',))
    self.assertEqual(svn.core.SubversionException(None, 1).args, (None, 1))
    self.assertEqual(svn.core.SubversionException('error message', 1).args,
                     ('error message', 1))
    self.assertEqual(svn.core.SubversionException('error message', 1).apr_err,
                     1)
    self.assertEqual(svn.core.SubversionException('error message', 1).message,
                     'error message')

  def test_mime_type_is_binary(self):
    self.assertEqual(0, svn.core.svn_mime_type_is_binary("text/plain"))
    self.assertEqual(1, svn.core.svn_mime_type_is_binary("image/png"))

  def test_mime_type_validate(self):
    self.assertRaises(svn.core.SubversionException,
            svn.core.svn_mime_type_validate, "this\nis\ninvalid\n")
    svn.core.svn_mime_type_validate("unknown/but-valid; charset=utf8")

  def test_exception_interoperability(self):
    """Test if SubversionException is correctly converted into svn_error_t
    and vice versa."""
    t = utils.Temper()
    (_, _, repos_uri) = t.alloc_empty_repo(suffix='-core')
    rev = svn.core.svn_opt_revision_t()
    rev.kind = svn.core.svn_opt_revision_head
    ctx = svn.client.create_context()

    class Receiver:
      def __call__(self, path, info, pool):
        raise self.e

    rec = Receiver()
    args = (repos_uri, rev, rev, rec, svn.core.svn_depth_empty, None, ctx)

    try:
      # ordinary Python exceptions must be passed through
      rec.e = TypeError()
      self.assertRaises(TypeError, svn.client.info2, *args)

      # SubversionException will be translated into an svn_error_t, propagated
      # through the call chain and translated back to SubversionException.
      rec.e = svn.core.SubversionException("Bla bla bla.",
                                           svn.core.SVN_ERR_INCORRECT_PARAMS,
                                           file=__file__, line=866)
      rec.e.child = svn.core.SubversionException("Yada yada.",
                                             svn.core.SVN_ERR_INCOMPLETE_DATA)
      self.assertRaises(svn.core.SubversionException, svn.client.info2, *args)

      # It must remain unchanged through the process.
      try:
        svn.client.info2(*args)
      except svn.core.SubversionException, exc:
        # find the original exception
        while exc.file != rec.e.file: exc = exc.child

        self.assertEqual(exc.message, rec.e.message)
        self.assertEqual(exc.apr_err, rec.e.apr_err)
        self.assertEqual(exc.line, rec.e.line)
        self.assertEqual(exc.child.message, rec.e.child.message)
        self.assertEqual(exc.child.apr_err, rec.e.child.apr_err)
        self.assertEqual(exc.child.child, None)
        self.assertEqual(exc.child.file, None)
        self.assertEqual(exc.child.line, 0)

      # Incomplete SubversionExceptions must trigger Python exceptions, which
      # will be passed through.
      rec.e = svn.core.SubversionException("No fields except message.")
      # e.apr_err is None but should be an int
      self.assertRaises(TypeError, svn.client.info2, *args)
    finally:
      # This would happen without the finally block as well, but we expliticly
      # order the operations so that the cleanup is not hindered by any open
      # handles.
      del ctx
      t.cleanup()

  def test_config_enumerate2(self):
    cfg = svn.core.svn_config_create(False)
    entries = {
      'one': 'one-value',
      'two': 'two-value',
      'three': 'three-value'
    }

    for (name, value) in entries.iteritems():
      svn.core.svn_config_set(cfg, "section", name, value)

    received_entries = {}
    def enumerator(name, value, pool):
      received_entries[name] = value
      return len(received_entries) < 2

    svn.core.svn_config_enumerate2(cfg, "section", enumerator)

    self.assertEqual(len(received_entries), 2)
    for (name, value) in received_entries.iteritems():
      self.assertTrue(name in entries)
      self.assertEqual(value, entries[name])

  def test_config_enumerate2_exception(self):
    cfg = svn.core.svn_config_create(False)
    svn.core.svn_config_set(cfg, "section", "one", "one-value")
    svn.core.svn_config_set(cfg, "section", "two", "two-value")

    received_entries = {}

    def enumerator(name, value, pool):
      received_entries[name] = value
      raise Exception

    svn.core.svn_config_enumerate2(cfg, "section", enumerator)
    # the exception is swallowed, but enumeration must be stopped
    self.assertEqual(len(received_entries), 1)

def suite():
    return unittest.defaultTestLoader.loadTestsFromTestCase(
      SubversionCoreTestCase)

if __name__ == '__main__':
    runner = unittest.TextTestRunner()
    runner.run(suite())
<|endoftext|>


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

"""
This module contains an algorithm to solve the Linear Assignment Problem
"""

from __future__ import division

__author__ = "Will Richards"
__copyright__ = "Copyright 2011, The Materials Project"
__version__ = "1.0"
__maintainer__ = "Will Richards"
__email__ = "wrichards@mit.edu"
__date__ = "Jan 28, 2013"

import numpy as np

class LinearAssignment(object):
    """
    This class finds the solution to the Linear Assignment Problem.
    It finds a minimum cost matching between two sets, given a cost
    matrix.

    This class is an implementation of the LAPJV algorithm described in:
    R. Jonker, A. Volgenant. A Shortest Augmenting Path Algorithm for
    Dense and Sparse Linear Assignment Problems. Computing 38, 325-340
    (1987)

    .. attribute: min_cost:

        The minimum cost of the matching

    .. attribute: solution:

        The matching of the rows to columns. i.e solution = [1, 2, 0]
        would match row 0 to column 1, row 1 to column 2 and row 2
        to column 0. Total cost would be c[0, 1] + c[1, 2] + c[2, 0]
    """

    def __init__(self, costs):
        """
        Args:
            costs:
                The cost matrix of the problem. cost[i,j] should be the
                cost of matching x[i] to y[j].
        """
        self.c = np.array(costs)
        self.n = len(costs)

        #initialize solution vectors
        self._x = np.zeros(self.n, dtype=np.int) - 1
        self._y = np.zeros(self.n, dtype=np.int) - 1

        #if column reduction doesn't find a solution, augment with shortest
        #paths until one is found
        if self._column_reduction():
            self._augmenting_row_reduction()
            #initialize the reduced costs
            self._update_cred()
            while np.min(self._x) < 0:
                self._augment()

        self.solution = self._x
        self._min_cost = None

    @property
    def min_cost(self):
        """
        Returns the cost of the best assignment
        """
        if self._min_cost:
            return self._min_cost

        self._min_cost = np.sum(self.c[np.arange(len(self.c)), self.solution])
        return self._min_cost

    def _column_reduction(self):
        """
        Column reduction and reduction transfer steps from LAPJV algorithm
        """
        #assign each column to its lowest cost row, ensuring that only row
        #or column is assigned once
        i1, j = np.unique(np.argmin(self.c, axis=0), return_index=True)
        self._x[i1] = j

        #if problem is solved, return
        if len(i1) == self.n:
            return False

        self._y[j] = i1

        #reduction_transfer
        #tempc is array with previously assigned matchings masked
        self._v = np.min(self.c, axis=0)
        tempc = self.c.copy()
        tempc[i1, j] = np.max(tempc.flatten()) * 10
        mu = np.min(tempc[i1, :] - self._v[None, :], axis=1)
        self._v[j] -= mu
        return True

    def _augmenting_row_reduction(self):
        """
        Augmenting row reduction step from LAPJV algorithm
        """
        unassigned = np.where(self._x == -1)[0]
        for i in unassigned:
            while True:
                #find smallest 2 values and indices
                temp = self.c[i] - self._v
                j1 = np.argmin(temp)
                u1 = temp[j1]
                temp[j1] = np.max(temp) + 1
                j2 = np.argmin(temp)
                u2 = temp[j2]

                if u1 < u2:
                    self._v[j1] -= u2 - u1
                elif self._y[j1] != -1:
                    j1 = j2
                k = self._y[j1]
                if k != -1:
                    self._x[k] = -1
                    self._x[i] = j1
                    self._y[j1] = i
                    i = k
                if np.allclose(u1, u2) or k == -1:
                    break

    def _update_cred(self):
        """
        Updates the reduced costs with the values from the
        dual solution
        """
        ui = np.diag(self.c[:, self._x]) - self._v[self._x]
        self.cred = self.c - ui[:, None] - self._v[None, :]

    def _augment(self):
        """
        Finds a minimum cost path and adds it to the matching
        """
        #build a minimum cost tree
        self._build_tree()

        #update prices
        delta = self._d[self._ready] - self._mu
        self._v[self._ready] += delta

        #augment the solution with the minimum cost path from the
        #tree. Follows an alternating path along matched, unmatched
        #edges from X to Y
        while True:
            self._i = self._pred[self._j]
            self._y[self._j] = self._i
            k = self._j
            self._j = self._x[self._i]
            self._x[self._i] = k
            if self._i == self._istar:
                break
        self._update_cred()

    def _build_tree(self):
        """
        Builds the tree finding an augmenting path. Alternates along
        matched and unmatched edges between X and Y. The paths are
        stored in self._pred (new predecessor of nodes in Y), and
        self._x and self._y
        """
        #find unassigned i*
        self._istar = np.argmin(self._x)

        #compute distances
        self._d = self.c[self._istar] - self._v
        self._pred = np.zeros(self.n, dtype=np.int) + self._istar

        #initialize sets
        #READY: set of nodes visited and in the path (whose price gets
        #updated in augment)
        #SCAN: set of nodes at the bottom of the tree, which we need to
        #look at
        #T0DO: unvisited nodes
        self._ready = np.zeros(self.n, dtype=np.bool)
        self._scan = np.zeros(self.n, dtype=np.bool)
        self._todo = np.zeros(self.n, dtype=np.bool) + True

        while True:
            #populate scan with minimum reduced distances
            if np.max(self._scan) == 0:
                self._mu = np.min(self._d[self._todo])
                self._scan[np.where(self._d == self._mu)] = 1
                self._todo[self._scan] = 0
                if np.min(self._y * self._scan) < 0:
                    self._j = np.argmin(self._y * self._scan)
                    return

            #pick jstar from scan (scan always has at least 1)
            self._jstar = np.argmax(self._scan)

            #pick i associated with jstar
            self._i = self._y[self._jstar]

            self._scan[self._jstar] = 0
            self._ready[self._jstar] = 1

            #find shorter distances
            newdists = self._mu + self.cred[self._i, :]
            shorter = (newdists < self._d) * self._todo

            #update distances
            self._d[shorter] = newdists[shorter]

            #update predecessors
            self._pred[shorter] = self._i

            for self._j in np.argwhere((self._d == self._mu)
                                       * self._todo).flatten():
                if self._y[self._j] == -1:
                    return
                self._scan[self._j] = 1
                self._todo[self._j] = 0
<commit_msg>Added check to ensure cost matrix is square in linear assignment<commit_after>#!/usr/bin/env python

"""
This module contains an algorithm to solve the Linear Assignment Problem
"""

from __future__ import division

__author__ = "Will Richards"
__copyright__ = "Copyright 2011, The Materials Project"
__version__ = "1.0"
__maintainer__ = "Will Richards"
__email__ = "wrichards@mit.edu"
__date__ = "Jan 28, 2013"

import numpy as np

class LinearAssignment(object):
    """
    This class finds the solution to the Linear Assignment Problem.
    It finds a minimum cost matching between two sets, given a cost
    matrix.

    This class is an implementation of the LAPJV algorithm described in:
    R. Jonker, A. Volgenant. A Shortest Augmenting Path Algorithm for
    Dense and Sparse Linear Assignment Problems. Computing 38, 325-340
    (1987)

    .. attribute: min_cost:

        The minimum cost of the matching

    .. attribute: solution:

        The matching of the rows to columns. i.e solution = [1, 2, 0]
        would match row 0 to column 1, row 1 to column 2 and row 2
        to column 0. Total cost would be c[0, 1] + c[1, 2] + c[2, 0]
    """

    def __init__(self, costs):
        """
        Args:
            costs:
                The cost matrix of the problem. cost[i,j] should be the
                cost of matching x[i] to y[j]. The cost matrix must be
                square
        """
        self.c = np.array(costs)
        self.n = len(costs)

        #check that cost matrix is square
        if self.c.shape != (self.n, self.n):
            raise ValueError("cost matrix is not square")

        #initialize solution vectors
        self._x = np.zeros(self.n, dtype=np.int) - 1
        self._y = np.zeros(self.n, dtype=np.int) - 1

        #if column reduction doesn't find a solution, augment with shortest
        #paths until one is found
        if self._column_reduction():
            self._augmenting_row_reduction()
            #initialize the reduced costs
            self._update_cred()
            while np.min(self._x) < 0:
                self._augment()

        self.solution = self._x
        self._min_cost = None

    @property
    def min_cost(self):
        """
        Returns the cost of the best assignment
        """
        if self._min_cost:
            return self._min_cost

        self._min_cost = np.sum(self.c[np.arange(len(self.c)), self.solution])
        return self._min_cost

    def _column_reduction(self):
        """
        Column reduction and reduction transfer steps from LAPJV algorithm
        """
        #assign each column to its lowest cost row, ensuring that only row
        #or column is assigned once
        i1, j = np.unique(np.argmin(self.c, axis=0), return_index=True)
        self._x[i1] = j

        #if problem is solved, return
        if len(i1) == self.n:
            return False

        self._y[j] = i1

        #reduction_transfer
        #tempc is array with previously assigned matchings masked
        self._v = np.min(self.c, axis=0)
        tempc = self.c.copy()
        tempc[i1, j] = np.max(tempc.flatten()) * 10
        mu = np.min(tempc[i1, :] - self._v[None, :], axis=1)
        self._v[j] -= mu
        return True

    def _augmenting_row_reduction(self):
        """
        Augmenting row reduction step from LAPJV algorithm
        """
        unassigned = np.where(self._x == -1)[0]
        for i in unassigned:
            while True:
                #find smallest 2 values and indices
                temp = self.c[i] - self._v
                j1 = np.argmin(temp)
                u1 = temp[j1]
                temp[j1] = np.max(temp) + 1
                j2 = np.argmin(temp)
                u2 = temp[j2]

                if u1 < u2:
                    self._v[j1] -= u2 - u1
                elif self._y[j1] != -1:
                    j1 = j2
                k = self._y[j1]
                if k != -1:
                    self._x[k] = -1
                    self._x[i] = j1
                    self._y[j1] = i
                    i = k
                if np.allclose(u1, u2) or k == -1:
                    break

    def _update_cred(self):
        """
        Updates the reduced costs with the values from the
        dual solution
        """
        ui = np.diag(self.c[:, self._x]) - self._v[self._x]
        self.cred = self.c - ui[:, None] - self._v[None, :]

    def _augment(self):
        """
        Finds a minimum cost path and adds it to the matching
        """
        #build a minimum cost tree
        self._build_tree()

        #update prices
        delta = self._d[self._ready] - self._mu
        self._v[self._ready] += delta

        #augment the solution with the minimum cost path from the
        #tree. Follows an alternating path along matched, unmatched
        #edges from X to Y
        while True:
            self._i = self._pred[self._j]
            self._y[self._j] = self._i
            k = self._j
            self._j = self._x[self._i]
            self._x[self._i] = k
            if self._i == self._istar:
                break
        self._update_cred()

    def _build_tree(self):
        """
        Builds the tree finding an augmenting path. Alternates along
        matched and unmatched edges between X and Y. The paths are
        stored in self._pred (new predecessor of nodes in Y), and
        self._x and self._y
        """
        #find unassigned i*
        self._istar = np.argmin(self._x)

        #compute distances
        self._d = self.c[self._istar] - self._v
        self._pred = np.zeros(self.n, dtype=np.int) + self._istar

        #initialize sets
        #READY: set of nodes visited and in the path (whose price gets
        #updated in augment)
        #SCAN: set of nodes at the bottom of the tree, which we need to
        #look at
        #T0DO: unvisited nodes
        self._ready = np.zeros(self.n, dtype=np.bool)
        self._scan = np.zeros(self.n, dtype=np.bool)
        self._todo = np.zeros(self.n, dtype=np.bool) + True

        while True:
            #populate scan with minimum reduced distances
            if np.max(self._scan) == 0:
                self._mu = np.min(self._d[self._todo])
                self._scan[np.where(self._d == self._mu)] = 1
                self._todo[self._scan] = 0
                if np.min(self._y * self._scan) < 0:
                    self._j = np.argmin(self._y * self._scan)
                    return

            #pick jstar from scan (scan always has at least 1)
            self._jstar = np.argmax(self._scan)

            #pick i associated with jstar
            self._i = self._y[self._jstar]

            self._scan[self._jstar] = 0
            self._ready[self._jstar] = 1

            #find shorter distances
            newdists = self._mu + self.cred[self._i, :]
            shorter = (newdists < self._d) * self._todo

            #update distances
            self._d[shorter] = newdists[shorter]

            #update predecessors
            self._pred[shorter] = self._i

            for self._j in np.argwhere((self._d == self._mu)
                                       * self._todo).flatten():
                if self._y[self._j] == -1:
                    return
                self._scan[self._j] = 1
                self._todo[self._j] = 0
<|endoftext|>


<commit_before>import numpy as np
import pandas as pd
from . import SignalDecomposition_AR as tsar
from . import Utils as tsutil

import sys

class cAbstract_Scikit_Model(tsar.cAbstractAR):
    def __init__(self , cycle_residue_name, P , iExogenousInfo = None):
        super().__init__(cycle_residue_name, iExogenousInfo)
        self.mNbLags = P;
        self.mNbExogenousLags = P;
        self.mScikitModel = None;

    def dumpCoefficients(self, iMax=10):
        # print(self.mScikitModel.__dict__);
        pass

    def build_Scikit_Model(self):
        assert(0);

    def set_name(self):
        assert(0);

    def fit(self):
        #  print("ESTIMATE_SCIKIT_MODEL_START" , self.mCycleResidueName);

        self.build_Scikit_Model();
        self.set_name();

        series = self.mCycleResidueName;
        self.mTime = self.mTimeInfo.mTime;
        self.mSignal = self.mTimeInfo.mSignal;
        lAREstimFrame = self.mTimeInfo.getEstimPart(self.mARFrame)

        # print("mAREstimFrame columns :" , self.mAREstimFrame.columns);
        lARInputs = lAREstimFrame[self.mInputNames].values
        lARTarget = lAREstimFrame[series].values
        # print(len(self.mInputNames), lARInputs.shape , lARTarget.shape)
        assert(lARInputs.shape[1] > 0);
        assert(lARTarget.shape[0] > 0);

        from sklearn.feature_selection import SelectKBest
        from sklearn.feature_selection import f_regression
        lMaxFeatures = self.mOptions.mMaxFeatureForAutoreg;
        if(lMaxFeatures >= lARInputs.shape[1]):
            lMaxFeatures = lARInputs.shape[1];
        if(lMaxFeatures >= (lARInputs.shape[0] // 4)):
            lMaxFeatures = lARInputs.shape[0] // 4;
        self.mFeatureSelector =  SelectKBest(f_regression, k= lMaxFeatures);
        try:
            self.mFeatureSelector.fit(lARInputs, lARTarget);
        except Exception as e:
            print("SCIKIT_MODEL_FEATURE_SELECTION_FAILURE" , self.mOutName, lARInputs.shape, e);
            if(self.mOptions.mDebug):
                df1 = pd.DataFrame(lARInputs);
                df1.columns = self.mInputNames
                df1['TGT'] = lARTarget;
                # df1.to_csv("SCIKIT_MODEL_FEATURE_SELECTION_FAILURE.csv.gz" , compression='gzip');
            # issue  #72 : ignore feature selection in case of failure.
            self.mFeatureSelector = None

        if(self.mFeatureSelector):
            lARInputsAfterSelection =  self.mFeatureSelector.transform(lARInputs);
            # print(self.mInputNames , self.mFeatureSelector.get_support(indices=True));
            lSupport = self.mFeatureSelector.get_support(indices=True);
            self.mInputNamesAfterSelection = [self.mInputNames[k] for k in lSupport];
        else:
            lARInputsAfterSelection = lARInputs;
            self.mInputNamesAfterSelection = self.mInputNames;

        assert(len(self.mInputNamesAfterSelection) == lARInputsAfterSelection.shape[1]);
        # print("FEATURE_SELECTION" , self.mOutName, lARInputs.shape[1] , lARInputsAfterSelection.shape[1]);
        del lARInputs;

        try:
            self.mScikitModel.fit(lARInputsAfterSelection, lARTarget)
        except Exception as e:
            print("SCIKIT_MODEL_FIT_FAILURE" , self.mOutName, lARInputsAfterSelection.shape, e);
            if(self.mOptions.mDebug):
                df1 = pd.DataFrame(lARInputsAfterSelection);
                df1.columns = self.mInputNamesAfterSelection
                df1['TGT'] = lARTarget;
                # df1.to_csv("SCIKIT_MODEL_FIT_FAILURE.csv.gz" , compression='gzip');
            del self.mScikitModel
            self.mScikitModel = None;

        del lARInputsAfterSelection;
        del lARTarget;
        del lAREstimFrame;

        if(self.mScikitModel is not None):
            lFullARInputs = self.mARFrame[self.mInputNames].values;
            lFullARInputsAfterSelection =  self.mFeatureSelector.transform(lFullARInputs) if self.mFeatureSelector else lFullARInputs;
            lPredicted = self.mScikitModel.predict(lFullARInputsAfterSelection);
            self.mARFrame[self.mOutName] = lPredicted
        else:
            # issue_34 failure SVD does not converge
            self.mARFrame[self.mOutName] = self.mDefaultValues[series]

        self.mARFrame[self.mOutName + '_residue'] =  self.mARFrame[series] - self.mARFrame[self.mOutName]

        # print("ESTIMATE_SCIKIT_MODEL_END" , self.mOutName);

    def transformDataset(self, df):
        series = self.mCycleResidueName;
        if(self.mExogenousInfo is not None):
            df = self.mExogenousInfo.transformDataset(df);
        # print(df.columns);
        # print(df.info());
        # print(df.head());
        # print(df.tail());
        lag_df = self.generateLagsForForecast(df);
        # print(self.mInputNames);
        # print(self.mFormula, "\n", lag_df.columns);
        # lag_df.to_csv("LAGGED_ " + str(self.mNbLags) + ".csv");
        inputs = lag_df[self.mInputNames].values
        inputs_after_feat_selection = self.mFeatureSelector.transform(inputs) if self.mFeatureSelector else inputs;
        if(self.mScikitModel is not None):
            pred = self.mScikitModel.predict(inputs_after_feat_selection)
            df[self.mOutName] = pred;
        else:
            df[self.mOutName] = self.mDefaultValues[series];

        target = df[series].values
        df[self.mOutName + '_residue'] = target - df[self.mOutName].values
        return df;

class cAutoRegressiveModel(cAbstract_Scikit_Model):
    def __init__(self , cycle_residue_name, P , iExogenousInfo = None):
        super().__init__(cycle_residue_name, P, iExogenousInfo)
        self.mComplexity = P;

    def dumpCoefficients(self, iMax=10):
        logger = tsutil.get_pyaf_logger();
        lDict = dict(zip(self.mInputNamesAfterSelection , self.mScikitModel.coef_));
        lDict1 = dict(zip(self.mInputNamesAfterSelection , abs(self.mScikitModel.coef_)));
        i = 1;
        lOrderedVariables = sorted(lDict1.keys(), key=lDict1.get, reverse=True);
        for k in lOrderedVariables[0:iMax]:
            logger.info("AR_MODEL_COEFF " + str(i) + " " + str(k) + " " + str(lDict[k]));
            i = i + 1;

    def build_Scikit_Model(self):
        import sklearn.linear_model as linear_model
        # issue_22 : warning about singular matrix => change the solver by default.
        self.mScikitModel = linear_model.Ridge(solver='svd')

    def set_name(self):
        self.mOutName = self.mCycleResidueName +  '_AR(' + str(self.mNbLags) + ")";
        self.mFormula = "AR(" + str(self.mNbLags) + ")";
        if(self.mExogenousInfo is not None):
            self.mOutName = self.mCycleResidueName +  '_ARX(' + str(self.mNbLags) + ")";
            self.mFormula = "ARX(" + str(self.mNbExogenousLags) + ")";

class cSVR_Model(cAbstract_Scikit_Model):
    def __init__(self , cycle_residue_name, P , iExogenousInfo = None):
        super().__init__(cycle_residue_name, P, iExogenousInfo)
        self.mComplexity = 2*P;

    def dumpCoefficients(self, iMax=10):
        pass

    def build_Scikit_Model(self):
        import sklearn.svm as svm
        self.mScikitModel = svm.SVR(kernel='rbf')

    def set_name(self):
        self.mOutName = self.mCycleResidueName +  '_SVR(' + str(self.mNbLags) + ")";
        self.mFormula = "SVR(" + str(self.mNbLags) + ")";
        if(self.mExogenousInfo is not None):
            self.mOutName = self.mCycleResidueName +  '_SVRX(' + str(self.mNbLags) + ")";
            self.mFormula = "SVRX(" + str(self.mNbExogenousLags) + ")";
<commit_msg>Add XGBoost based models #98 Added cXGBoost_Model<commit_after>import numpy as np
import pandas as pd
from . import SignalDecomposition_AR as tsar
from . import Utils as tsutil

import sys

class cAbstract_Scikit_Model(tsar.cAbstractAR):
    def __init__(self , cycle_residue_name, P , iExogenousInfo = None):
        super().__init__(cycle_residue_name, iExogenousInfo)
        self.mNbLags = P;
        self.mNbExogenousLags = P;
        self.mScikitModel = None;

    def dumpCoefficients(self, iMax=10):
        # print(self.mScikitModel.__dict__);
        pass

    def build_Scikit_Model(self):
        assert(0);

    def set_name(self):
        assert(0);

    def fit(self):
        #  print("ESTIMATE_SCIKIT_MODEL_START" , self.mCycleResidueName);

        self.build_Scikit_Model();
        self.set_name();

        series = self.mCycleResidueName;
        self.mTime = self.mTimeInfo.mTime;
        self.mSignal = self.mTimeInfo.mSignal;
        lAREstimFrame = self.mTimeInfo.getEstimPart(self.mARFrame)

        # print("mAREstimFrame columns :" , self.mAREstimFrame.columns);
        lARInputs = lAREstimFrame[self.mInputNames].values
        lARTarget = lAREstimFrame[series].values
        # print(len(self.mInputNames), lARInputs.shape , lARTarget.shape)
        assert(lARInputs.shape[1] > 0);
        assert(lARTarget.shape[0] > 0);

        from sklearn.feature_selection import SelectKBest
        from sklearn.feature_selection import f_regression
        lMaxFeatures = self.mOptions.mMaxFeatureForAutoreg;
        if(lMaxFeatures >= lARInputs.shape[1]):
            lMaxFeatures = lARInputs.shape[1];
        if(lMaxFeatures >= (lARInputs.shape[0] // 4)):
            lMaxFeatures = lARInputs.shape[0] // 4;
        self.mFeatureSelector =  SelectKBest(f_regression, k= lMaxFeatures);
        try:
            self.mFeatureSelector.fit(lARInputs, lARTarget);
        except Exception as e:
            print("SCIKIT_MODEL_FEATURE_SELECTION_FAILURE" , self.mOutName, lARInputs.shape, e);
            if(self.mOptions.mDebug):
                df1 = pd.DataFrame(lARInputs);
                df1.columns = self.mInputNames
                df1['TGT'] = lARTarget;
                # df1.to_csv("SCIKIT_MODEL_FEATURE_SELECTION_FAILURE.csv.gz" , compression='gzip');
            # issue  #72 : ignore feature selection in case of failure.
            self.mFeatureSelector = None

        if(self.mFeatureSelector):
            lARInputsAfterSelection =  self.mFeatureSelector.transform(lARInputs);
            # print(self.mInputNames , self.mFeatureSelector.get_support(indices=True));
            lSupport = self.mFeatureSelector.get_support(indices=True);
            self.mInputNamesAfterSelection = [self.mInputNames[k] for k in lSupport];
        else:
            lARInputsAfterSelection = lARInputs;
            self.mInputNamesAfterSelection = self.mInputNames;

        assert(len(self.mInputNamesAfterSelection) == lARInputsAfterSelection.shape[1]);
        # print("FEATURE_SELECTION" , self.mOutName, lARInputs.shape[1] , lARInputsAfterSelection.shape[1]);
        del lARInputs;

        try:
            self.mScikitModel.fit(lARInputsAfterSelection, lARTarget)
        except Exception as e:
            print("SCIKIT_MODEL_FIT_FAILURE" , self.mOutName, lARInputsAfterSelection.shape, e);
            if(self.mOptions.mDebug):
                df1 = pd.DataFrame(lARInputsAfterSelection);
                df1.columns = self.mInputNamesAfterSelection
                df1['TGT'] = lARTarget;
                # df1.to_csv("SCIKIT_MODEL_FIT_FAILURE.csv.gz" , compression='gzip');
            del self.mScikitModel
            self.mScikitModel = None;

        del lARInputsAfterSelection;
        del lARTarget;
        del lAREstimFrame;

        if(self.mScikitModel is not None):
            lFullARInputs = self.mARFrame[self.mInputNames].values;
            lFullARInputsAfterSelection =  self.mFeatureSelector.transform(lFullARInputs) if self.mFeatureSelector else lFullARInputs;
            lPredicted = self.mScikitModel.predict(lFullARInputsAfterSelection);
            self.mARFrame[self.mOutName] = lPredicted
        else:
            # issue_34 failure SVD does not converge
            self.mARFrame[self.mOutName] = self.mDefaultValues[series]

        self.mARFrame[self.mOutName + '_residue'] =  self.mARFrame[series] - self.mARFrame[self.mOutName]

        # print("ESTIMATE_SCIKIT_MODEL_END" , self.mOutName);

    def transformDataset(self, df):
        series = self.mCycleResidueName;
        if(self.mExogenousInfo is not None):
            df = self.mExogenousInfo.transformDataset(df);
        # print(df.columns);
        # print(df.info());
        # print(df.head());
        # print(df.tail());
        lag_df = self.generateLagsForForecast(df);
        # print(self.mInputNames);
        # print(self.mFormula, "\n", lag_df.columns);
        # lag_df.to_csv("LAGGED_ " + str(self.mNbLags) + ".csv");
        inputs = lag_df[self.mInputNames].values
        inputs_after_feat_selection = self.mFeatureSelector.transform(inputs) if self.mFeatureSelector else inputs;
        if(self.mScikitModel is not None):
            pred = self.mScikitModel.predict(inputs_after_feat_selection)
            df[self.mOutName] = pred;
        else:
            df[self.mOutName] = self.mDefaultValues[series];

        target = df[series].values
        df[self.mOutName + '_residue'] = target - df[self.mOutName].values
        return df;

class cAutoRegressiveModel(cAbstract_Scikit_Model):
    def __init__(self , cycle_residue_name, P , iExogenousInfo = None):
        super().__init__(cycle_residue_name, P, iExogenousInfo)
        self.mComplexity = P;

    def dumpCoefficients(self, iMax=10):
        logger = tsutil.get_pyaf_logger();
        lDict = dict(zip(self.mInputNamesAfterSelection , self.mScikitModel.coef_));
        lDict1 = dict(zip(self.mInputNamesAfterSelection , abs(self.mScikitModel.coef_)));
        i = 1;
        lOrderedVariables = sorted(lDict1.keys(), key=lDict1.get, reverse=True);
        for k in lOrderedVariables[0:iMax]:
            logger.info("AR_MODEL_COEFF " + str(i) + " " + str(k) + " " + str(lDict[k]));
            i = i + 1;

    def build_Scikit_Model(self):
        import sklearn.linear_model as linear_model
        # issue_22 : warning about singular matrix => change the solver by default.
        self.mScikitModel = linear_model.Ridge(solver='svd')

    def set_name(self):
        self.mOutName = self.mCycleResidueName +  '_AR(' + str(self.mNbLags) + ")";
        self.mFormula = "AR(" + str(self.mNbLags) + ")";
        if(self.mExogenousInfo is not None):
            self.mOutName = self.mCycleResidueName +  '_ARX(' + str(self.mNbLags) + ")";
            self.mFormula = "ARX(" + str(self.mNbExogenousLags) + ")";

class cSVR_Model(cAbstract_Scikit_Model):
    def __init__(self , cycle_residue_name, P , iExogenousInfo = None):
        super().__init__(cycle_residue_name, P, iExogenousInfo)
        self.mComplexity = 2*P;

    def dumpCoefficients(self, iMax=10):
        pass

    def build_Scikit_Model(self):
        import sklearn.svm as svm
        self.mScikitModel = svm.SVR(kernel='rbf')

    def set_name(self):
        self.mOutName = self.mCycleResidueName +  '_SVR(' + str(self.mNbLags) + ")";
        self.mFormula = "SVR(" + str(self.mNbLags) + ")";
        if(self.mExogenousInfo is not None):
            self.mOutName = self.mCycleResidueName +  '_SVRX(' + str(self.mNbLags) + ")";
            self.mFormula = "SVRX(" + str(self.mNbExogenousLags) + ")";

class cXGBoost_Model(cAbstract_Scikit_Model):
    def __init__(self , cycle_residue_name, P , iExogenousInfo = None):
        super().__init__(cycle_residue_name, P, iExogenousInfo)
        self.mComplexity = 2*P;

    def dumpCoefficients(self, iMax=10):
        pass

    def build_Scikit_Model(self):
        import xgboost as xgb

        import sklearn.svm as svm
        # need to find a way to set these options from pyaf
        self.mScikitModel = xgb.XGBRegressor(n_estimators=10,
                                             nthread=1,
                                             min_child_weight=10,
                                             max_depth=3,
                                             seed=1960)

    def set_name(self):
        self.mOutName = self.mCycleResidueName +  '_XGB(' + str(self.mNbLags) + ")";
        self.mFormula = "XGB(" + str(self.mNbLags) + ")";
        if(self.mExogenousInfo is not None):
            self.mOutName = self.mCycleResidueName +  '_XGBX(' + str(self.mNbLags) + ")";
            self.mFormula = "XGBX(" + str(self.mNbExogenousLags) + ")";
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2012 OpenERP - Team de Localización Argentina.
# https://launchpad.net/~openerp-l10n-ar-localization
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import fields, osv
from openerp.tools.translate import _
from datetime import datetime
import logging

_logger = logging.getLogger(__name__)
_schema = logging.getLogger(__name__ + '.schema')

_queries = {
    'by number': "[['number','=',invoice_number]]",
    'by nearest draft': "[['state','=','draft'],['partner_id.document_type_id.afip_code','=',DocTipo],['partner_id.document_number','=',DocNro],['amount_total','=',ImpTotal]]",
}
_update_domain = [
    ('by number', 'By invoice number'),
    ('by nearest draft', 'Nearest draft invoice'),
]

class query_invoices(osv.osv_memory):
    _name = 'l10n_ar_wsafip_fe.query_invoices'
    _description = 'Query for invoices in AFIP web services'
    _columns = {
        'journal_id': fields.many2one('account.journal', 'Journal', required=True),
        'first_invoice_number': fields.integer('First invoice number', required=True),
        'last_invoice_number': fields.integer('Last invoice number', required=True),
        'update_invoices': fields.boolean('Update CAE if invoice exists'),
        'update_domain': fields.selection(_update_domain, string="Update relation"),
        'create_invoices': fields.boolean('Create invoice in draft if not exists'),
    }
    _defaults = {
        'first_invoice_number': 1,
        'last_invoice_number': 1,
        'update_domain': "by number",
    }

    def onchange_journal_id(self, cr, uid, ids, first_invoice_number, journal_id):
        journal_obj = self.pool.get('account.journal')
        res = {}

        if journal_id:
            num_items = journal_obj.browse(cr, uid, journal_id).afip_items_generated
            res['value'] = {
                'first_invoice_number': min(first_invoice_number, num_items),
                'last_invoice_number': num_items,
            }

        return res

    def execute(self, cr, uid, ids, context=None):
        context = context or {}
        invoice_obj = self.pool.get('account.invoice')
        partner_obj = self.pool.get('res.partner')
        document_type_obj = self.pool.get('afip.document_type')
        v_r = []

        for qi in self.browse(cr, uid, ids):
            conn = qi.journal_id.afip_connection_id
            serv = qi.journal_id.afip_connection_id.server_id

            sequence = qi.journal_id.sequence_id
            interpolation_dict = sequence._interpolation_dict()
            interpolated_prefix = sequence._interpolate(sequence.prefix or "", interpolation_dict)
            interpolated_suffix = sequence._interpolate(sequence.suffix or "", interpolation_dict)
            number_format = "%s%%0%sd%s" % (interpolated_prefix, qi.journal_id.sequence_id.padding , interpolated_suffix)

            if qi.first_invoice_number > qi.last_invoice_number:
                raise osv.except_osv(_(u'Qrong invoice range numbers'), _('Please, first invoice number must be less than last invoice'))

            def _fch_(s):
                if s and len(s) == 8:
                    return datetime.strptime(s, "%Y%m%d").strftime('%Y-%m-%d %H:%M:%S')
                elif s and len(s) > 8:
                    return datetime.strptime(s, "%Y%m%d%H%M%S").strftime('%Y-%m-%d %H:%M:%S')
                else:
                    return False

            for inv_number in range(qi.first_invoice_number, qi.last_invoice_number+1):
                r = serv.wsfe_query_invoice(conn.id,
                                            qi.journal_id.journal_class_id.afip_code,
                                            inv_number,
                                            qi.journal_id.point_of_sale)

                r = r[serv.id]

                if r['EmisionTipo'] == 'CAE':
                    invoice_domain = eval(_queries[qi.update_domain], {}, dict(r.items() + [['invoice_number',number_format % inv_number]]))
                    inv_ids = invoice_obj.search(cr, uid, [('journal_id','=',qi.journal_id.id)] + invoice_domain)

                    if inv_ids and qi.update_invoices and len(inv_ids) == 1:
                        # Update Invoice
                        _logger.debug("Update invoice number: %s" % (number_format % inv_number))
                        invoice_obj.write(cr, uid, inv_ids, {
                            'date_invoice': _fch_(r['CbteFch']),
                            'internal_number': number_format % inv_number,
                            'afip_cae': r['CodAutorizacion'],
                            'afip_cae_due': _fch_(r['FchProceso']),
                            'afip_service_start': _fch_(r['FchServDesde']),
                            'afip_service_end': _fch_(r['FchServHasta']),
                            'amount_total': r['ImpTotal'],
                        })
                        msg = 'Updated from AFIP (%s)' % (number_format % inv_number)
                        invoice_obj.message_post(cr, uid, inv_ids, body=msg, subtype="l10n_ar_wsafip_fe.mt_invoice_ws_action", context=context)
                        v_r.extend(inv_ids)
                    elif inv_ids and qi.update_invoices and len(inv_ids) > 1:
                        # Duplicated Invoices
                        _logger.info("Duplicated invoice number: %s %s" % (number_format % inv_number, tuple(inv_ids)))
                        msg = 'Posible duplication from AFIP (%s)' % (number_format % inv_number)
                        for inv_id in inv_ids:
                            invoice_obj.message_post(cr, uid, inv_id, body=msg, subtype="l10n_ar_wsafip_fe.mt_invoice_ws_action", context=context)
                    elif not inv_ids and qi.create_invoices:
                        partner_id = partner_obj.search(cr, uid, [
                            ('document_type_id.afip_code','=',r['DocTipo']),
                            ('document_number','=',r['DocNro']),
                        ])
                        if partner_id:
                            # Take partner
                            partner_id = partner_id[0]
                        else:
                            # Create partner
                            _logger.debug("Creating partner doc number: %s" % r['DocNro'])
                            document_type_id = document_type_obj.search(cr, uid, [
                                ('afip_code','=',r['DocTipo']),
                            ])
                            assert len(document_type_id) == 1
                            document_type_id = document_type_id[0]
                            partner_id = partner_obj.create(cr, uid, {
                                'name': r['DocNro'],
                                'document_type_id': document_type_id,
                                'document_number': r['DocNro'],
                            })
                        _logger.debug("Creating invoice number: %s" % (number_format % inv_number))
                        partner = partner_obj.browse(cr, uid, partner_id)
                        if not partner.property_account_receivable.id:
                            raise osv.except_osv(_(u'Partner has not set a receivable account'), _('Please, first set the receivable account for %s') % partner.name)

                        inv_id = invoice_obj.create(cr, uid, {
                            'company_id': qi.journal_id.company_id.id,
                            'account_id': partner.property_account_receivable.id,
                            'internal_number': number_format % inv_number,
                            'name': 'Created from AFIP (%s)' % number_format % inv_number,
                            'journal_id': qi.journal_id.id,
                            'partner_id': partner_id,
                            'date_invoice': _fch_(r['CbteFch']),
                            'afip_cae': r['CodAutorizacion'],
                            'afip_cae_due': _fch_(r['FchProceso']),
                            'afip_service_start': _fch_(r['FchServDesde']),
                            'afip_service_end': _fch_(r['FchServHasta']),
                            'amount_total': r['ImpTotal'],
                            'state': 'draft',
                        })
                        msg = 'Created from AFIP (%s)' % (number_format % inv_number)
                        invoice_obj.message_post(cr, uid, inv_id, body=msg, subtype="l10n_ar_wsafip_fe.mt_invoice_ws_action", context=context)
                        v_r.append(inv_id)
                    else:
                        _logger.debug("Ignoring invoice: %s" % (number_format % inv_number))

        return {
            'name': _('Invoices'),
            'domain': [('id', 'in', _ids)],
            'res_model': 'account.invoice',
            'type': 'ir.actions.act_window',
            'view_id': False,
            'view_mode': 'tree,form',
            'view_type': 'form',
            'limit': 80,
        }

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<commit_msg>[FIX] NameError: global name _ids is not defined<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2012 OpenERP - Team de Localización Argentina.
# https://launchpad.net/~openerp-l10n-ar-localization
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import fields, osv
from openerp.tools.translate import _
from datetime import datetime
import logging

_logger = logging.getLogger(__name__)
_schema = logging.getLogger(__name__ + '.schema')

_queries = {
    'by number': "[['number','=',invoice_number]]",
    'by nearest draft': "[['state','=','draft'],['partner_id.document_type_id.afip_code','=',DocTipo],['partner_id.document_number','=',DocNro],['amount_total','=',ImpTotal]]",
}
_update_domain = [
    ('by number', 'By invoice number'),
    ('by nearest draft', 'Nearest draft invoice'),
]

class query_invoices(osv.osv_memory):
    _name = 'l10n_ar_wsafip_fe.query_invoices'
    _description = 'Query for invoices in AFIP web services'
    _columns = {
        'journal_id': fields.many2one('account.journal', 'Journal', required=True),
        'first_invoice_number': fields.integer('First invoice number', required=True),
        'last_invoice_number': fields.integer('Last invoice number', required=True),
        'update_invoices': fields.boolean('Update CAE if invoice exists'),
        'update_domain': fields.selection(_update_domain, string="Update relation"),
        'create_invoices': fields.boolean('Create invoice in draft if not exists'),
    }
    _defaults = {
        'first_invoice_number': 1,
        'last_invoice_number': 1,
        'update_domain': "by number",
    }

    def onchange_journal_id(self, cr, uid, ids, first_invoice_number, journal_id):
        journal_obj = self.pool.get('account.journal')
        res = {}

        if journal_id:
            num_items = journal_obj.browse(cr, uid, journal_id).afip_items_generated
            res['value'] = {
                'first_invoice_number': min(first_invoice_number, num_items),
                'last_invoice_number': num_items,
            }

        return res

    def execute(self, cr, uid, ids, context=None):
        context = context or {}
        invoice_obj = self.pool.get('account.invoice')
        partner_obj = self.pool.get('res.partner')
        document_type_obj = self.pool.get('afip.document_type')
        v_r = []

        for qi in self.browse(cr, uid, ids):
            conn = qi.journal_id.afip_connection_id
            serv = qi.journal_id.afip_connection_id.server_id

            sequence = qi.journal_id.sequence_id
            interpolation_dict = sequence._interpolation_dict()
            interpolated_prefix = sequence._interpolate(sequence.prefix or "", interpolation_dict)
            interpolated_suffix = sequence._interpolate(sequence.suffix or "", interpolation_dict)
            number_format = "%s%%0%sd%s" % (interpolated_prefix, qi.journal_id.sequence_id.padding , interpolated_suffix)

            if qi.first_invoice_number > qi.last_invoice_number:
                raise osv.except_osv(_(u'Qrong invoice range numbers'), _('Please, first invoice number must be less than last invoice'))

            def _fch_(s):
                if s and len(s) == 8:
                    return datetime.strptime(s, "%Y%m%d").strftime('%Y-%m-%d %H:%M:%S')
                elif s and len(s) > 8:
                    return datetime.strptime(s, "%Y%m%d%H%M%S").strftime('%Y-%m-%d %H:%M:%S')
                else:
                    return False

            for inv_number in range(qi.first_invoice_number, qi.last_invoice_number+1):
                r = serv.wsfe_query_invoice(conn.id,
                                            qi.journal_id.journal_class_id.afip_code,
                                            inv_number,
                                            qi.journal_id.point_of_sale)

                r = r[serv.id]

                if r['EmisionTipo'] == 'CAE':
                    invoice_domain = eval(_queries[qi.update_domain], {}, dict(r.items() + [['invoice_number',number_format % inv_number]]))
                    inv_ids = invoice_obj.search(cr, uid, [('journal_id','=',qi.journal_id.id)] + invoice_domain)

                    if inv_ids and qi.update_invoices and len(inv_ids) == 1:
                        # Update Invoice
                        _logger.debug("Update invoice number: %s" % (number_format % inv_number))
                        invoice_obj.write(cr, uid, inv_ids, {
                            'date_invoice': _fch_(r['CbteFch']),
                            'internal_number': number_format % inv_number,
                            'afip_cae': r['CodAutorizacion'],
                            'afip_cae_due': _fch_(r['FchProceso']),
                            'afip_service_start': _fch_(r['FchServDesde']),
                            'afip_service_end': _fch_(r['FchServHasta']),
                            'amount_total': r['ImpTotal'],
                        })
                        msg = 'Updated from AFIP (%s)' % (number_format % inv_number)
                        invoice_obj.message_post(cr, uid, inv_ids, body=msg, subtype="l10n_ar_wsafip_fe.mt_invoice_ws_action", context=context)
                        v_r.extend(inv_ids)
                    elif inv_ids and qi.update_invoices and len(inv_ids) > 1:
                        # Duplicated Invoices
                        _logger.info("Duplicated invoice number: %s %s" % (number_format % inv_number, tuple(inv_ids)))
                        msg = 'Posible duplication from AFIP (%s)' % (number_format % inv_number)
                        for inv_id in inv_ids:
                            invoice_obj.message_post(cr, uid, inv_id, body=msg, subtype="l10n_ar_wsafip_fe.mt_invoice_ws_action", context=context)
                    elif not inv_ids and qi.create_invoices:
                        partner_id = partner_obj.search(cr, uid, [
                            ('document_type_id.afip_code','=',r['DocTipo']),
                            ('document_number','=',r['DocNro']),
                        ])
                        if partner_id:
                            # Take partner
                            partner_id = partner_id[0]
                        else:
                            # Create partner
                            _logger.debug("Creating partner doc number: %s" % r['DocNro'])
                            document_type_id = document_type_obj.search(cr, uid, [
                                ('afip_code','=',r['DocTipo']),
                            ])
                            assert len(document_type_id) == 1
                            document_type_id = document_type_id[0]
                            partner_id = partner_obj.create(cr, uid, {
                                'name': r['DocNro'],
                                'document_type_id': document_type_id,
                                'document_number': r['DocNro'],
                            })
                        _logger.debug("Creating invoice number: %s" % (number_format % inv_number))
                        partner = partner_obj.browse(cr, uid, partner_id)
                        if not partner.property_account_receivable.id:
                            raise osv.except_osv(_(u'Partner has not set a receivable account'), _('Please, first set the receivable account for %s') % partner.name)

                        inv_id = invoice_obj.create(cr, uid, {
                            'company_id': qi.journal_id.company_id.id,
                            'account_id': partner.property_account_receivable.id,
                            'internal_number': number_format % inv_number,
                            'name': 'Created from AFIP (%s)' % number_format % inv_number,
                            'journal_id': qi.journal_id.id,
                            'partner_id': partner_id,
                            'date_invoice': _fch_(r['CbteFch']),
                            'afip_cae': r['CodAutorizacion'],
                            'afip_cae_due': _fch_(r['FchProceso']),
                            'afip_service_start': _fch_(r['FchServDesde']),
                            'afip_service_end': _fch_(r['FchServHasta']),
                            'amount_total': r['ImpTotal'],
                            'state': 'draft',
                        })
                        msg = 'Created from AFIP (%s)' % (number_format % inv_number)
                        invoice_obj.message_post(cr, uid, inv_id, body=msg, subtype="l10n_ar_wsafip_fe.mt_invoice_ws_action", context=context)
                        v_r.append(inv_id)
                    else:
                        _logger.debug("Ignoring invoice: %s" % (number_format % inv_number))

        return {
            'name': _('Invoices'),
            'domain': [('id', 'in', inv_ids)],
            'res_model': 'account.invoice',
            'type': 'ir.actions.act_window',
            'view_id': False,
            'view_mode': 'tree,form',
            'view_type': 'form',
            'limit': 80,
        }

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

"""FDC Report."""

from string import Template

class Report(object):

    """Report is build from indicator list and template
    and generate a report.
    """

    def __init__(self, indicator_list, template_string=None, template_file=None):
        """ Initialize a report.

        In template variables are named:
                $name_q1, $name_q2 $name_q3, $name_q4, $name_value

        Args:
                indicator_list (list): list of fdc.Indicator
                template_string (str): Template string of the report to use (iff there is no template_file)
                template_file (file): File containing the template string to use to generate the report
        """
        self.template = Template(template_string)
        self.indicator_values = dict()
        if template_string is None and template_file is None:
            raise ValueError(
                "template_string or template_file argument needs to be used.")
        if template_file is not None:
            self.template = self._read_template_file(template_file)
        self._fill_indicator_contents(indicator_list)

    def _read_template_file(self, template_file):
        with open(template_file, 'r') as f:
            return Template(f.read())

    def _fill_indicator_contents(self, indicator_list):
        for indicator in indicator_list:
            for key in indicator.values.keys():
                var_name = "%s_%s" % (indicator.name, key)
                if indicator.values[key] is None:
                    self.indicator_values[var_name] = ""
                else:
                    self.indicator_values[var_name] = indicator.values[key]

    def generate(self):
        """ Generate report from template and indicators.
        """
        return self.template.safe_substitute(self.indicator_values)
<commit_msg>Improved docstring style.<commit_after># -*- coding: utf-8 -*-

"""FDC Report."""

from string import Template

class Report(object):

    """Built from indicator list and template and generate a report."""

    def __init__(self, indicator_list, template_string=None, template_file=None):
        """Initialize a report.

        In template variables are named:
                $name_q1, $name_q2 $name_q3, $name_q4, $name_value

        Args:
            indicator_list (list): list of fdc.Indicator
            template_string (str): Template string of the report to use (iff there is no template_file)
            template_file (file): File containing the template string to use to generate the report
        """
        self.template = Template(template_string)
        self.indicator_values = dict()
        if template_string is None and template_file is None:
            raise ValueError(
                "template_string or template_file argument needs to be used.")
        if template_file is not None:
            self.template = self._read_template_file(template_file)
        self._fill_indicator_contents(indicator_list)

    def _read_template_file(self, template_file):
        """Read template file."""
        with open(template_file, 'r') as f:
            return Template(f.read())

    def _fill_indicator_contents(self, indicator_list):
        """Fill the indicator values dictionary."""
        for indicator in indicator_list:
            for key in indicator.values.keys():
                var_name = "%s_%s" % (indicator.name, key)
                if indicator.values[key] is None:
                    self.indicator_values[var_name] = ""
                else:
                    self.indicator_values[var_name] = indicator.values[key]

    def generate(self):
        """Generate report from template and indicators."""
        return self.template.safe_substitute(self.indicator_values)
<|endoftext|>


<commit_before>import sublime
import sublime_plugin
import os
import glob
import platform
from datetime import datetime as dt
import difflib
import filecmp
import shutil
from threading import Thread

#==============#
#   Settings   #
#==============#
settings = sublime.load_settings("LocalHistory.sublime-settings")
history_location = settings.get("history_location", "~")
if history_location == "~":
    history_location = os.path.expanduser("~")
HISTORY_PATH = os.path.join(os.path.abspath(history_location), ".sublime", "history")
HISTORY_LIMIT = settings.get("history_limit", 50)
FILE_SIZE_LIMIT = settings.get("file_size_limit", 262144)

def show_diff(window, from_file, to_file):
    # From
    from_file = from_file.encode("utf-8")
    with open(from_file, "r") as f:
        from_content = f.readlines()

    # To
    to_file = to_file.encode("utf-8")
    with open(to_file, "r") as f:
        to_content = f.readlines()

    # Compare and show diff
    diff = difflib.unified_diff(from_content, to_content, from_file, to_file)
    diff = "".join(diff).decode("utf-8")
    panel = window.new_file()
    panel.set_scratch(True)
    panel.set_syntax_file("Packages/Diff/Diff.tmLanguage")
    panel_edit = panel.begin_edit()
    panel.insert(panel_edit, 0, diff)
    panel.end_edit(panel_edit)

def get_filedir(file_path):
    file_dir = os.path.dirname(file_path)
    if platform.system() == "Windows":
        if file_dir.find("\\") == 0:
            file_dir = file_dir[2:]  # Strip the network \\ starting path
        if file_dir.find(":") == 1:
            file_dir = file_dir.replace(":", "", 1)
    else:
        file_dir = file_dir[file_dir.find(os.sep) + 1:]  # Trim the root
    return os.path.join(HISTORY_PATH, file_dir)

class HistorySave(sublime_plugin.EventListener):

    def on_post_save(self, view):

        def run(file_path):
            file_path = file_path.encode("utf-8")
            # Return if file exceeds the size limit
            if os.path.getsize(file_path) > FILE_SIZE_LIMIT:
                print "WARNING: Local History did not save a copy of this file \
                    because it has exceeded {0}KB limit.".format(FILE_SIZE_LIMIT / 1024)
                return

            # Get history directory
            file_name = os.path.basename(file_path)
            history_dir = get_filedir(file_path)
            if not os.path.exists(history_dir):
                # Create directory structure
                os.makedirs(history_dir)

            # Get history files
            os.chdir(history_dir)
            history_files = glob.glob("*" + file_name)
            history_files.sort(key=lambda f: os.path.getmtime(f), reverse=True)

            # Skip if no changes
            if history_files:
                if filecmp.cmp(file_path, os.path.join(history_dir, history_files[0])):
                    return

            # Store history
            shutil.copyfile(file_path, os.path.join(history_dir, "{0}.{1}".
                format(dt.now().strftime("%b.%d.%Y_%H.%M.%S"), file_name)))

            # Remove old files
            for file in history_files[HISTORY_LIMIT - 1:]:  # -1 as we just added a new file
                os.remove(file)

        # Process in a thread
        t = Thread(target=run, args=(view.file_name(),))
        t.start()

class HistoryOpen(sublime_plugin.TextCommand):

    def run(self, edit):
        # Get history directory
        file_name = os.path.basename(self.view.file_name())
        history_dir = get_filedir(self.view.file_name())

        # Get history files
        try:
            os.chdir(history_dir)
        except OSError:
            sublime.status_message("No Local History Found")
            return
        history_files = glob.glob("*" + file_name)
        history_files.sort(key=lambda f: os.path.getmtime(f), reverse=True)
        if not history_files:
            sublime.status_message("No Local History Found")
            return

        def on_done(index):
            # Escape
            if index == -1:
                return

            # Open
            self.view.window().open_file(os.path.join(history_dir, history_files[index]))

        self.view.window().show_quick_panel(history_files, on_done)

class HistoryCompare(sublime_plugin.TextCommand):

    def run(self, edit):
        # Get history directory
        file_name = os.path.basename(self.view.file_name())
        history_dir = get_filedir(self.view.file_name())

        # Get history files
        os.chdir(history_dir)
        history_files = glob.glob("*" + file_name)
        history_files.sort(key=lambda f: os.path.getmtime(f), reverse=True)
        # Skip the first one as its always identical
        history_files = history_files[1:]

        if not history_files:
            sublime.status_message("No Local History Found")
            return

        def on_done(index):
            # Escape
            if index == -1:
                return

            # Trigger save before comparing, if required!
            if self.view.is_dirty():
                self.view.run_command("save")

            # Show diff
            from_file = history_files[index]
            to_file = self.view.file_name()
            show_diff(self.view.window(), from_file, to_file)

        self.view.window().show_quick_panel(history_files, on_done)

class HistoryReplace(sublime_plugin.TextCommand):

    def run(self, edit):
        # Get history directory
        file_name = os.path.basename(self.view.file_name())
        history_dir = get_filedir(self.view.file_name())

        # Get history files
        os.chdir(history_dir)
        history_files = glob.glob("*" + file_name)
        history_files.sort(key=lambda f: os.path.getmtime(f), reverse=True)
        # Skip the first one as its always identical
        history_files = history_files[1:]

        if not history_files:
            sublime.status_message("No Local History Found")
            return

        def on_done(index):
            # Escape
            if index == -1:
                return

            # Replace
            file = history_files[index]
            with open(file) as f:
                self.view.replace(edit, sublime.Region(0, self.view.size()), \
                    f.read().decode("utf-8"))
            self.view.run_command("save")

        self.view.window().show_quick_panel(history_files, on_done)

class HistoryIncrementalDiff(sublime_plugin.TextCommand):

    def run(self, edit, **kwargs):
        # Get history directory
        file_name = os.path.basename(self.view.file_name())
        history_dir = get_filedir(self.view.file_name())

        # Get history files
        os.chdir(history_dir)
        history_files = glob.glob("*" + file_name)
        history_files.sort(key=lambda f: os.path.getmtime(f), reverse=True)
        if len(history_files) < 2:
            sublime.status_message("No Incremental Diff Found")
            return

        def on_done(index):
            # Escape
            if index == -1:
                return

            # Selected the last file
            if index == len(history_files) - 1:
                sublime.status_message("No Incremental Diff Found")
                return

            # Show diff
            from_file = history_files[index + 1]
            to_file = history_files[index]
            show_diff(self.view.window(), from_file, to_file)

        self.view.window().show_quick_panel(history_files, on_done)

class HistoryDeleteAll(sublime_plugin.TextCommand):

    def run(self, edit):
        shutil.rmtree(HISTORY_PATH)
        sublime.status_message("All Local History Deleted")
<commit_msg>added parens to fix issue<commit_after>import sublime
import sublime_plugin
import os
import glob
import platform
from datetime import datetime as dt
import difflib
import filecmp
import shutil
from threading import Thread

#==============#
#   Settings   #
#==============#
settings = sublime.load_settings("LocalHistory.sublime-settings")
history_location = settings.get("history_location", "~")
if history_location == "~":
    history_location = os.path.expanduser("~")
HISTORY_PATH = os.path.join(os.path.abspath(history_location), ".sublime", "history")
HISTORY_LIMIT = settings.get("history_limit", 50)
FILE_SIZE_LIMIT = settings.get("file_size_limit", 262144)

def show_diff(window, from_file, to_file):
    # From
    from_file = from_file.encode("utf-8")
    with open(from_file, "r") as f:
        from_content = f.readlines()

    # To
    to_file = to_file.encode("utf-8")
    with open(to_file, "r") as f:
        to_content = f.readlines()

    # Compare and show diff
    diff = difflib.unified_diff(from_content, to_content, from_file, to_file)
    diff = "".join(diff).decode("utf-8")
    panel = window.new_file()
    panel.set_scratch(True)
    panel.set_syntax_file("Packages/Diff/Diff.tmLanguage")
    panel_edit = panel.begin_edit()
    panel.insert(panel_edit, 0, diff)
    panel.end_edit(panel_edit)

def get_filedir(file_path):
    file_dir = os.path.dirname(file_path)
    if platform.system() == "Windows":
        if file_dir.find("\\") == 0:
            file_dir = file_dir[2:]  # Strip the network \\ starting path
        if file_dir.find(":") == 1:
            file_dir = file_dir.replace(":", "", 1)
    else:
        file_dir = file_dir[file_dir.find(os.sep) + 1:]  # Trim the root
    return os.path.join(HISTORY_PATH, file_dir)

class HistorySave(sublime_plugin.EventListener):

    def on_post_save(self, view):

        def run(file_path):
            file_path = file_path.encode("utf-8")
            # Return if file exceeds the size limit
            if os.path.getsize(file_path) > FILE_SIZE_LIMIT:
                print ("WARNING: Local History did not save a copy of this file \
                    because it has exceeded {0}KB limit.".format(FILE_SIZE_LIMIT / 1024))
                return

            # Get history directory
            file_name = os.path.basename(file_path)
            history_dir = get_filedir(file_path)
            if not os.path.exists(history_dir):
                # Create directory structure
                os.makedirs(history_dir)

            # Get history files
            os.chdir(history_dir)
            history_files = glob.glob("*" + file_name)
            history_files.sort(key=lambda f: os.path.getmtime(f), reverse=True)

            # Skip if no changes
            if history_files:
                if filecmp.cmp(file_path, os.path.join(history_dir, history_files[0])):
                    return

            # Store history
            shutil.copyfile(file_path, os.path.join(history_dir, "{0}.{1}".
                format(dt.now().strftime("%b.%d.%Y_%H.%M.%S"), file_name)))

            # Remove old files
            for file in history_files[HISTORY_LIMIT - 1:]:  # -1 as we just added a new file
                os.remove(file)

        # Process in a thread
        t = Thread(target=run, args=(view.file_name(),))
        t.start()

class HistoryOpen(sublime_plugin.TextCommand):

    def run(self, edit):
        # Get history directory
        file_name = os.path.basename(self.view.file_name())
        history_dir = get_filedir(self.view.file_name())

        # Get history files
        try:
            os.chdir(history_dir)
        except OSError:
            sublime.status_message("No Local History Found")
            return
        history_files = glob.glob("*" + file_name)
        history_files.sort(key=lambda f: os.path.getmtime(f), reverse=True)
        if not history_files:
            sublime.status_message("No Local History Found")
            return

        def on_done(index):
            # Escape
            if index == -1:
                return

            # Open
            self.view.window().open_file(os.path.join(history_dir, history_files[index]))

        self.view.window().show_quick_panel(history_files, on_done)

class HistoryCompare(sublime_plugin.TextCommand):

    def run(self, edit):
        # Get history directory
        file_name = os.path.basename(self.view.file_name())
        history_dir = get_filedir(self.view.file_name())

        # Get history files
        os.chdir(history_dir)
        history_files = glob.glob("*" + file_name)
        history_files.sort(key=lambda f: os.path.getmtime(f), reverse=True)
        # Skip the first one as its always identical
        history_files = history_files[1:]

        if not history_files:
            sublime.status_message("No Local History Found")
            return

        def on_done(index):
            # Escape
            if index == -1:
                return

            # Trigger save before comparing, if required!
            if self.view.is_dirty():
                self.view.run_command("save")

            # Show diff
            from_file = history_files[index]
            to_file = self.view.file_name()
            show_diff(self.view.window(), from_file, to_file)

        self.view.window().show_quick_panel(history_files, on_done)

class HistoryReplace(sublime_plugin.TextCommand):

    def run(self, edit):
        # Get history directory
        file_name = os.path.basename(self.view.file_name())
        history_dir = get_filedir(self.view.file_name())

        # Get history files
        os.chdir(history_dir)
        history_files = glob.glob("*" + file_name)
        history_files.sort(key=lambda f: os.path.getmtime(f), reverse=True)
        # Skip the first one as its always identical
        history_files = history_files[1:]

        if not history_files:
            sublime.status_message("No Local History Found")
            return

        def on_done(index):
            # Escape
            if index == -1:
                return

            # Replace
            file = history_files[index]
            with open(file) as f:
                self.view.replace(edit, sublime.Region(0, self.view.size()), \
                    f.read().decode("utf-8"))
            self.view.run_command("save")

        self.view.window().show_quick_panel(history_files, on_done)

class HistoryIncrementalDiff(sublime_plugin.TextCommand):

    def run(self, edit, **kwargs):
        # Get history directory
        file_name = os.path.basename(self.view.file_name())
        history_dir = get_filedir(self.view.file_name())

        # Get history files
        os.chdir(history_dir)
        history_files = glob.glob("*" + file_name)
        history_files.sort(key=lambda f: os.path.getmtime(f), reverse=True)
        if len(history_files) < 2:
            sublime.status_message("No Incremental Diff Found")
            return

        def on_done(index):
            # Escape
            if index == -1:
                return

            # Selected the last file
            if index == len(history_files) - 1:
                sublime.status_message("No Incremental Diff Found")
                return

            # Show diff
            from_file = history_files[index + 1]
            to_file = history_files[index]
            show_diff(self.view.window(), from_file, to_file)

        self.view.window().show_quick_panel(history_files, on_done)

class HistoryDeleteAll(sublime_plugin.TextCommand):

    def run(self, edit):
        shutil.rmtree(HISTORY_PATH)
        sublime.status_message("All Local History Deleted")
<|endoftext|>


<commit_before>################################################################################
# Copyright (C) 2016 Advanced Micro Devices, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell cop-
# ies of the Software, and to permit persons to whom the Software is furnished
# to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM-
# PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNE-
# CTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
################################################################################

# hardcoded tensile version; also in Tensile/Source/TensileConfigVersion.cmake
__version__ = "3.0.0"
<commit_msg>incrementing patch version after master release<commit_after>################################################################################
# Copyright (C) 2016 Advanced Micro Devices, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell cop-
# ies of the Software, and to permit persons to whom the Software is furnished
# to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM-
# PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNE-
# CTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
################################################################################

# hardcoded tensile version; also in Tensile/Source/TensileConfigVersion.cmake
__version__ = "3.0.1"
<|endoftext|>


<commit_before>##########################################################################
#
#  Copyright (c) 2013, Image Engine Design Inc. All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions are
#  met:
#
#      * Redistributions of source code must retain the above
#        copyright notice, this list of conditions and the following
#        disclaimer.
#
#      * Redistributions in binary form must reproduce the above
#        copyright notice, this list of conditions and the following
#        disclaimer in the documentation and/or other materials provided with
#        the distribution.
#
#      * Neither the name of John Haddon nor the names of
#        any other contributors to this software may be used to endorse or
#        promote products derived from this software without specific prior
#        written permission.
#
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
#  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
#  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
#  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
#  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
#  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
#  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
#  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
#  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
##########################################################################

import Gaffer
import GafferUI

import GafferScene

Gaffer.Metadata.registerNodeDescription(

GafferScene.CustomAttributes,

"""Applies arbitrary user-defined attributes to locations in the scene. Note
that for most common cases the StandardAttributes, OpenGLAttributes, RenderManAttributes,
and ArnoldAttributes nodes should be used in preference - they provide predefined
sets of attributes with customised user interfaces. The CustomAttributes node is of most use when
needing to set a custom attribute not supported by the specialised nodes.
""",

"attributes",
"""The attributes to be applied - arbitrary numbers of user defined attributes may be added
as children of this plug via the user interface, or using the CompoundDataPlug API via
python.""",

)

GafferUI.PlugValueWidget.registerCreator( GafferScene.CustomAttributes, "attributes", GafferUI.CompoundDataPlugValueWidget, collapsed=None )
<commit_msg>CustomAttributesUI : Updated to use Metadata.registerNode().<commit_after>##########################################################################
#
#  Copyright (c) 2013, Image Engine Design Inc. All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions are
#  met:
#
#      * Redistributions of source code must retain the above
#        copyright notice, this list of conditions and the following
#        disclaimer.
#
#      * Redistributions in binary form must reproduce the above
#        copyright notice, this list of conditions and the following
#        disclaimer in the documentation and/or other materials provided with
#        the distribution.
#
#      * Neither the name of John Haddon nor the names of
#        any other contributors to this software may be used to endorse or
#        promote products derived from this software without specific prior
#        written permission.
#
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
#  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
#  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
#  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
#  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
#  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
#  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
#  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
#  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
#  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
##########################################################################

import Gaffer
import GafferUI

import GafferScene

Gaffer.Metadata.registerNode(

	GafferScene.CustomAttributes,

	"description",
	"""
	Applies arbitrary user-defined attributes to locations in the scene. Note
	that for most common cases the StandardAttributes, OpenGLAttributes, RenderManAttributes,
	and ArnoldAttributes nodes should be used in preference - they provide predefined
	sets of attributes with customised user interfaces. The CustomAttributes node is of most use when
	needing to set a custom attribute not supported by the specialised nodes.
	""",

)

GafferUI.PlugValueWidget.registerCreator( GafferScene.CustomAttributes, "attributes", GafferUI.CompoundDataPlugValueWidget, collapsed=None )
<|endoftext|>