<commit_before>import pytest
import numpy as np
import openpnm as op
from time import sleep

class UtilsTest:

    def setup_class(self):
        self.net = op.network.Cubic(shape=[3, 3, 3])
        self.geo = op.geometry.StickAndBall(
            network=self.net, pores=self.net.Ps, throats=self.net.Ts)

    def teardown_class(self):
        ws = op.Workspace()
        ws.clear()

    def test_tic_toc(self):
        with pytest.raises(Exception):
            op.utils.toc()
        op.utils.tic()
        sleep(0.5)
        t1 = op.utils.toc(quiet=True)
        assert t1 >= 0
        op.utils.tic()
        sleep(0.5)
        t2 = op.utils.toc()
        assert t2 >= 0

    def test_nested_dict(self):
        d = op.utils.NestedDict()
        d['top']['middle']['bottom'] = 1
        assert d == {'top': {'middle': {'bottom': 1}}}
        s = d.__str__()
        assert s == '-top\n--middle\n---bottom\n'
        a = d.to_dict()
        assert isinstance(a, dict)

    def test_printable_list(self):
        L = op.utils.PrintableList(['item1', 'item2', 'item2'])
        s = L.__str__().split('\n')
        assert len(s) == 5

    def test_printable_dict(self):
        D = op.utils.PrintableDict(**{'item1': 1, 'item2': 2,
                                      'item3': np.array([1, 2])})
        s = D.__str__().split('\n')
        assert len(s) == 7
        r = D.__repr__()
        assert r == "{'item1': 1, 'item2': 2, 'item3': array([1, 2])}"

    def test_is_symmetric_w_rtol(self):
        A = np.array([[1, 2, 3], [2, 4, 6], [3.000001, 6, 99]])
        is_sym = op.utils.misc.is_symmetric(A, rtol=1e-4)
        assert is_sym
        is_sym = op.utils.misc.is_symmetric(A, rtol=1e-6)
        assert not is_sym

    def test_is_symmetric_FickianDiffusion_must_be_symmetric(self):
        net = op.network.Cubic(shape=[5, 5, 5])
        geom = op.geometry.StickAndBall(network=net,
                                        pores=net.Ps,
                                        throats=net.Ts)
        air = op.phases.Air(network=net)
        _ = op.physics.Standard(network=net, phase=air, geometry=geom)
        fd = op.algorithms.FickianDiffusion(network=net, phase=air)
        fd.set_value_BC(pores=net.pores("left"), values=1.0)
        fd.set_value_BC(pores=net.pores("right"), values=0.1)
        assert op.utils.misc.is_symmetric(fd.A)

    def test_is_symmetric_AdvectionDiffusion_must_be_nonsymmetric(self):
        net = op.network.Cubic(shape=[5, 5, 5])
        geom = op.geometry.StickAndBall(network=net,
                                        pores=net.Ps,
                                        throats=net.Ts)
        air = op.phases.Air(network=net)
        phys = op.physics.Standard(network=net, phase=air, geometry=geom)
        ad = op.algorithms.AdvectionDiffusion(network=net, phase=air)
        ad.set_value_BC(pores=net.pores("left"), values=1.0)
        ad.set_value_BC(pores=net.pores("right"), values=0.1)
        # Uniform pressure field --> no advection --> still symmetric
        assert op.utils.misc.is_symmetric(ad.A)
        sf = op.algorithms.StokesFlow(network=net, phase=air)
        sf.set_value_BC(pores=net.pores("left"), values=1.0)
        sf.set_value_BC(pores=net.pores("right"), values=0.0)
        sf.run()
        air.update(sf.results())
        phys.regenerate_models()
        ad.settings.update({"cache_A": False, "cache_b": False})
        ad._build_A()
        # Non-uniform pressure field --> positive advection --> non-symmetric
        assert not op.utils.misc.is_symmetric(ad.A)

    def test_is_valid_propname(self):
        assert op.utils.misc.is_valid_propname("pore.foo")
        assert op.utils.misc.is_valid_propname("pore.zed.foo")
        assert op.utils.misc.is_valid_propname("throat.bar")
        assert op.utils.misc.is_valid_propname("throat.bar.foo")
        assert not op.utils.misc.is_valid_propname("pores.blah")
        assert not op.utils.misc.is_valid_propname("foo.blah")
        assert not op.utils.misc.is_valid_propname("pore")
        assert not op.utils.misc.is_valid_propname("throat")
        assert not op.utils.misc.is_valid_propname("pore.")
        assert not op.utils.misc.is_valid_propname("throat.")
        assert not op.utils.misc.is_valid_propname("pore.foo..bar")

if __name__ == '__main__':

    t = UtilsTest()
    self = t
    t.setup_class()
    for item in t.__dir__():
        if item.startswith('test'):
            print('running test: '+item)
            t.__getattribute__(item)()
<commit_msg>Commented out a test about __repr__ that no longer is necessary<commit_after>import pytest
import numpy as np
import openpnm as op
from time import sleep

class UtilsTest:

    def setup_class(self):
        self.net = op.network.Cubic(shape=[3, 3, 3])
        self.geo = op.geometry.StickAndBall(
            network=self.net, pores=self.net.Ps, throats=self.net.Ts)

    def teardown_class(self):
        ws = op.Workspace()
        ws.clear()

    def test_tic_toc(self):
        with pytest.raises(Exception):
            op.utils.toc()
        op.utils.tic()
        sleep(0.5)
        t1 = op.utils.toc(quiet=True)
        assert t1 >= 0
        op.utils.tic()
        sleep(0.5)
        t2 = op.utils.toc()
        assert t2 >= 0

    def test_nested_dict(self):
        d = op.utils.NestedDict()
        d['top']['middle']['bottom'] = 1
        assert d == {'top': {'middle': {'bottom': 1}}}
        s = d.__str__()
        assert s == '-top\n--middle\n---bottom\n'
        a = d.to_dict()
        assert isinstance(a, dict)

    def test_printable_list(self):
        L = op.utils.PrintableList(['item1', 'item2', 'item2'])
        s = L.__str__().split('\n')
        assert len(s) == 5

    def test_printable_dict(self):
        D = op.utils.PrintableDict(**{'item1': 1, 'item2': 2,
                                      'item3': np.array([1, 2])})
        s = D.__str__().split('\n')
        assert len(s) == 7
        # r = D.__repr__()
        # assert r == "{'item1': 1, 'item2': 2, 'item3': array([1, 2])}"

    def test_is_symmetric_w_rtol(self):
        A = np.array([[1, 2, 3], [2, 4, 6], [3.000001, 6, 99]])
        is_sym = op.utils.misc.is_symmetric(A, rtol=1e-4)
        assert is_sym
        is_sym = op.utils.misc.is_symmetric(A, rtol=1e-6)
        assert not is_sym

    def test_is_symmetric_FickianDiffusion_must_be_symmetric(self):
        net = op.network.Cubic(shape=[5, 5, 5])
        geom = op.geometry.StickAndBall(network=net,
                                        pores=net.Ps,
                                        throats=net.Ts)
        air = op.phases.Air(network=net)
        _ = op.physics.Standard(network=net, phase=air, geometry=geom)
        fd = op.algorithms.FickianDiffusion(network=net, phase=air)
        fd.set_value_BC(pores=net.pores("left"), values=1.0)
        fd.set_value_BC(pores=net.pores("right"), values=0.1)
        assert op.utils.misc.is_symmetric(fd.A)

    def test_is_symmetric_AdvectionDiffusion_must_be_nonsymmetric(self):
        net = op.network.Cubic(shape=[5, 5, 5])
        geom = op.geometry.StickAndBall(network=net,
                                        pores=net.Ps,
                                        throats=net.Ts)
        air = op.phases.Air(network=net)
        phys = op.physics.Standard(network=net, phase=air, geometry=geom)
        ad = op.algorithms.AdvectionDiffusion(network=net, phase=air)
        ad.set_value_BC(pores=net.pores("left"), values=1.0)
        ad.set_value_BC(pores=net.pores("right"), values=0.1)
        # Uniform pressure field --> no advection --> still symmetric
        assert op.utils.misc.is_symmetric(ad.A)
        sf = op.algorithms.StokesFlow(network=net, phase=air)
        sf.set_value_BC(pores=net.pores("left"), values=1.0)
        sf.set_value_BC(pores=net.pores("right"), values=0.0)
        sf.run()
        air.update(sf.results())
        phys.regenerate_models()
        ad.settings.update({"cache_A": False, "cache_b": False})
        ad._build_A()
        # Non-uniform pressure field --> positive advection --> non-symmetric
        assert not op.utils.misc.is_symmetric(ad.A)

    def test_is_valid_propname(self):
        assert op.utils.misc.is_valid_propname("pore.foo")
        assert op.utils.misc.is_valid_propname("pore.zed.foo")
        assert op.utils.misc.is_valid_propname("throat.bar")
        assert op.utils.misc.is_valid_propname("throat.bar.foo")
        assert not op.utils.misc.is_valid_propname("pores.blah")
        assert not op.utils.misc.is_valid_propname("foo.blah")
        assert not op.utils.misc.is_valid_propname("pore")
        assert not op.utils.misc.is_valid_propname("throat")
        assert not op.utils.misc.is_valid_propname("pore.")
        assert not op.utils.misc.is_valid_propname("throat.")
        assert not op.utils.misc.is_valid_propname("pore.foo..bar")

if __name__ == '__main__':

    t = UtilsTest()
    self = t
    t.setup_class()
    for item in t.__dir__():
        if item.startswith('test'):
            print('running test: '+item)
            t.__getattribute__(item)()
<|endoftext|>


<commit_before>import os
import re
import hashlib
import yaml

class TestFile(object):
    ROOT = os.path.abspath("%s/../../" % os.path.dirname(os.path.realpath(__file__)))

    def test_all_files_are_snake_case(self):
        for subdir, dirs, files in os.walk(self.ROOT):
            for file in filter(lambda file: file.endswith(".py") or file.endswith(".sls"), files):
                assert file.islower(), "%s/%s name needs to be lower case" % (subdir, file)
                assert re.compile('^[a-z0-9_\.]+$').match(file) is not None, "%s/%s needs to be snake case" % (subdir, file)

    def test_all_pillars_have_root_key_same_as_file_name(self, __envs__):
        pillar_root = "%s/salt/pillars" % self.ROOT
        for env in __envs__:
            pillar_env_path = "%s/%s" % (pillar_root, env)
            for subdir, dirs, files in os.walk(pillar_env_path):
                for file in filter(lambda file: file.endswith(".sls"), files):
                    folder = os.path.basename(subdir.split(pillar_env_path)[-1])
                    path = "%s/%s" % (subdir, file)
                    if folder is not '':
                        key = folder
                        assert SyntaxChecker(file=path, key=key).check(), "Top level pillar is not same as base name for %s" % path
                    else:
                        key = os.path.basename(file).split('.')[0]
                        assert SyntaxChecker(file=path, key=key).check(), "Top level pillar is not same as base name for %s" % path

    def test_common_pillars_in_base_env(self):
        pillar_root = "%s/salt/pillars" % self.ROOT
        md5_hash = {}
        for subdir, dirs, files in os.walk(pillar_root):
            for file in files:
                path = "%s/%s" % (subdir, file)
                md5 = hashlib.md5(open(path, 'rb').read()).hexdigest()
                if md5 in md5_hash.keys():
                    assert False, "%s file and %s file is exactly the same, move them to base env" % (path, md5_hash[md5])
                else:
                    md5_hash[md5] = path

    def test_top_files_has_all_pillars(self, __envs__):
        pillar_root = "%s/salt/pillars" % self.ROOT
        top_file = "%s/top.sls" % pillar_root
        yml = yaml.load(open(top_file, 'r'))
        assert yml.keys().sort() == __envs__.sort(), "Environment mismatch!"

        for env, target_dict in yml.iteritems():
            pillars = map(lambda file: os.path.basename(file).split('.')[0] , os.listdir("%s/%s" % (pillar_root, env)))
            for target, target_pillars in target_dict.iteritems():
                assert set(target_pillars).intersection(set(pillars)) == set(pillars), "%s not listed in top file" % (set(pillars).difference(set(target_pillars)))
                assert set(pillars).intersection(set(target_pillars)) == set(target_pillars), "%s not listed in pillar directory" % (set(target_pillars).difference(set(pillars)))

    def test_ensure_state_files_are_symlinked_if_similar(self):
        pass

    def test_ensure_state_has_core_files(self, __envs__):
        state_path = "%s/salt/states" % self.ROOT
        core_files = ('init.sls', 'verify.sls', 'map.jinja', 'default.yaml')
        for env in __envs__:
            env_path = "%s/%s" % (state_path, env)
            if os.path.exists(env_path):
                for state in os.listdir(env_path):
                    files = os.listdir("%s/%s" % (env_path, state))
                    assert set(core_files).intersection(set(files)) == set(core_files)

    def test_ensure_external_module_has_test_file(self):
        external_module_path = "%s/salt/ext" % self.ROOT
        test_path = "%s/tests/unit" % self.ROOT
        for subdir, dirs, files in os.walk(external_module_path):
            for file in filter(lambda file: file.endswith(".py") and file != "__init__.py", files):
                ext_module_file_path = "%s/test_%s" % (subdir, file)
                test_module_file_path = ext_module_file_path.replace(external_module_path, test_path)
                assert os.path.exists(test_module_file_path), "%s file is missing" % test_module_file_path

class SyntaxChecker(object):
    def __init__(self, file, key):
        self.file = file
        self.key = key

    def check(self):
        with open(self.file, "r") as file:
            lines = file.readlines()
            lines = filter(lambda line: self.is_top_level(line), lines)
            lines = filter(lambda line: not self.is_jinja(line), lines)
            lines = filter(lambda line: not self.is_include(line), lines)
            if len(lines) == 1 and self.top_level_key(lines[0]):
                return True
            elif len(lines) == 0:
                return True
            else:
                return False

    def is_include(self, line):
        return line.startswith('include:')

    def is_jinja(self, line):
        return line.startswith('{{') or line.startswith('{%')

    def is_top_level(self, line):
        return not line.startswith(' ')

    def top_level_key(self, line):
        return line.startswith("%s:" % self.key)
<commit_msg>Add symlink tests<commit_after>import os
import re
import hashlib
import yaml

class TestFile(object):
    ROOT = os.path.abspath("%s/../../" % os.path.dirname(os.path.realpath(__file__)))

    def test_all_files_are_snake_case(self):
        for subdir, dirs, files in os.walk(self.ROOT):
            for file in filter(lambda file: file.endswith(".py") or file.endswith(".sls"), files):
                assert file.islower(), "%s/%s name needs to be lower case" % (subdir, file)
                assert re.compile('^[a-z0-9_\.]+$').match(file) is not None, "%s/%s needs to be snake case" % (subdir, file)

    def test_all_pillars_have_root_key_same_as_file_name(self, __envs__):
        pillar_root = "%s/salt/pillars" % self.ROOT
        for env in __envs__:
            pillar_env_path = "%s/%s" % (pillar_root, env)
            for subdir, dirs, files in os.walk(pillar_env_path):
                for file in filter(lambda file: file.endswith(".sls"), files):
                    folder = os.path.basename(subdir.split(pillar_env_path)[-1])
                    path = "%s/%s" % (subdir, file)
                    if folder is not '':
                        key = folder
                        assert SyntaxChecker(file=path, key=key).check(), "Top level pillar is not same as base name for %s" % path
                    else:
                        key = os.path.basename(file).split('.')[0]
                        assert SyntaxChecker(file=path, key=key).check(), "Top level pillar is not same as base name for %s" % path

    def test_common_pillars_in_base_env(self):
        pillar_root = "%s/salt/pillars" % self.ROOT
        md5_hash = {}
        for subdir, dirs, files in os.walk(pillar_root):
            for file in files:
                path = "%s/%s" % (subdir, file)
                md5 = hashlib.md5(open(path, 'rb').read()).hexdigest()
                if md5 in md5_hash.keys():
                    assert False, "%s file and %s file is exactly the same, move them to base env" % (path, md5_hash[md5])
                else:
                    md5_hash[md5] = path

    def test_top_files_has_all_pillars(self, __envs__):
        pillar_root = "%s/salt/pillars" % self.ROOT
        top_file = "%s/top.sls" % pillar_root
        yml = yaml.load(open(top_file, 'r'))
        assert yml.keys().sort() == __envs__.sort(), "Environment mismatch!"

        for env, target_dict in yml.iteritems():
            pillars = map(lambda file: os.path.basename(file).split('.')[0] , os.listdir("%s/%s" % (pillar_root, env)))
            for target, target_pillars in target_dict.iteritems():
                assert set(target_pillars).intersection(set(pillars)) == set(pillars), "%s not listed in top file" % (set(pillars).difference(set(target_pillars)))
                assert set(pillars).intersection(set(target_pillars)) == set(target_pillars), "%s not listed in pillar directory" % (set(target_pillars).difference(set(pillars)))

    def test_ensure_state_files_are_symlinked_if_similar(self, __envs__):
        production_env = 'prd'
        state_path = "%s/salt/states" % self.ROOT
        production_env_path = "%s/%s" % (state_path, production_env)
        for env in filter(lambda env: env != production_env, __envs__):
            env_path = "%s/%s" % (state_path, env)
            if os.path.exists(env_path):
                for state in os.listdir(env_path):
                    state_full_path = "%s/%s" % (env_path, state)
                    state_prd_full_path = "%s/%s" % (production_env_path, state)
                    if not os.path.islink(state_full_path):
                        assert Hasher(state_full_path).hash() != Hasher(state_prd_full_path).hash(), "prd and another environment state file collision, make it a symlink!"

    def test_ensure_state_has_core_files(self, __envs__):
        state_path = "%s/salt/states" % self.ROOT
        core_files = ('init.sls', 'verify.sls', 'map.jinja', 'default.yaml')
        for env in __envs__:
            env_path = "%s/%s" % (state_path, env)
            if os.path.exists(env_path):
                for state in os.listdir(env_path):
                    files = os.listdir("%s/%s" % (env_path, state))
                    assert set(core_files).intersection(set(files)) == set(core_files)

    def test_ensure_external_module_has_test_file(self):
        external_module_path = "%s/salt/ext" % self.ROOT
        test_path = "%s/tests/unit" % self.ROOT
        for subdir, dirs, files in os.walk(external_module_path):
            for file in filter(lambda file: file.endswith(".py") and file != "__init__.py", files):
                ext_module_file_path = "%s/test_%s" % (subdir, file)
                test_module_file_path = ext_module_file_path.replace(external_module_path, test_path)
                assert os.path.exists(test_module_file_path), "%s file is missing" % test_module_file_path

class Hasher(object):
    def __init__(self, path):
        self.path = path

    def hash(self):
        hasher = hashlib.md5()
        for subdir, dirs, files in os.walk(self.path):
            for file in files:
                file_path = os.path.join(subdir, file)
                with open(str(file_path), 'rb') as afile:
                    hasher.update(afile.read())
        return hasher.hexdigest()

class SyntaxChecker(object):
    def __init__(self, file, key):
        self.file = file
        self.key = key

    def check(self):
        with open(self.file, "r") as file:
            lines = file.readlines()
            lines = filter(lambda line: self.is_top_level(line), lines)
            lines = filter(lambda line: not self.is_jinja(line), lines)
            lines = filter(lambda line: not self.is_include(line), lines)
            if len(lines) == 1 and self.top_level_key(lines[0]):
                return True
            elif len(lines) == 0:
                return True
            else:
                return False

    def is_include(self, line):
        return line.startswith('include:')

    def is_jinja(self, line):
        return line.startswith('{{') or line.startswith('{%')

    def is_top_level(self, line):
        return not line.startswith(' ')

    def top_level_key(self, line):
        return line.startswith("%s:" % self.key)
<|endoftext|>


<commit_before>import re

DISTRO_CODENAME_MAP = {
    "ubuntu": {
        "18.04": "bionic",
        "17.10": "artful",
        "17.04": "zesty",
        "16.10": "yakkety",
        "16.04": "xenial",
        "15.10": "wily",
        "15.04": "vivid",
        "14.10": "utopic",
        "14.04": "trusty",
        "13.10": "saucy",
        "12.04": "precise",
    },
    "debian": {
        "7": "wheezy",
        "8": "jessie",
        "9": "stretch",
    },
    "rhel": {
        "8": "ootpa",
        "7": "maipo",
        "6": "santiago",
    },
    "centos": {
        "8": "core",
        "7": "core",
        "6": "core",
    },
    "fedora": {
        "28": "28",
        "27": "27",
        "26": "26",
        "25": "25",
        "24": "24",
        "23": "23",
        "22": "22",
        "21": "21",
        "20": "heisenbug",
    },
    "opensuse": {
        "15.0": "leap",
        "15.1": "leap",
        "15.2": "leap",
        "42.2": "leap",
        "42.3": "leap",
    },
    "sle": {
        "12.1": "sle",
        "12.2": "sle",
        "12.3": "sle",
        "15.0": "sle",
        "15.1": "sle",
        "15.2": "sle",
    },
}

DEFAULT_OS_VERSION = dict(
    ubuntu="18.04",
    fedora="25",
    centos="7.6",
    opensuse="15.0",
    sle="15.0",
    rhel="7.6",
    debian='8.0'
)

class OS(object):
    """
    Class that parses either /etc/os-release or the output of 'lsb_release -a'
    and provides OS name and version information.

    Must be initialized with OS.from_lsb_release or OS.from_os_release
    """

    __slots__ = ['name', 'version', 'codename', 'package_type']

    _deb_distros = ('debian', 'ubuntu')
    _rpm_distros = ('fedora', 'rhel', 'centos', 'opensuse', 'sle')

    def __init__(self, name=None, version=None, codename=None):
        self.name = name
        self.version = version or self._codename_to_version(name, codename)
        self.codename = codename or self._version_to_codename(name, version)
        self._set_package_type()

    @staticmethod
    def _version_to_codename(name, version):
        for (_version, codename) in DISTRO_CODENAME_MAP[name].items():
            if str(version) == _version or str(version).split('.')[0] == _version:
                return codename

    @staticmethod
    def _codename_to_version(name, codename):
        for (version, _codename) in DISTRO_CODENAME_MAP[name].items():
            if codename == _codename:
                return version
        raise RuntimeError("No version found for %s %s !" % (
            name,
            codename,
        ))

    @classmethod
    def from_lsb_release(cls, lsb_release_str):
        """
        Parse output from lsb_release -a and populate attributes

        Given output like:
            Distributor ID: Ubuntu
            Description:    Ubuntu 12.04.4 LTS
            Release:        12.04
            Codename:       precise

        Attributes will be:
            name = 'ubuntu'
            version = '12.04'
            codename = 'precise'
        Additionally, we set the package type:
            package_type = 'deb'
        """
        str_ = lsb_release_str.strip()
        name = cls._get_value(str_, 'Distributor ID')
        if name == 'RedHatEnterpriseServer':
            name = 'rhel'
        elif name.startswith('openSUSE'):
            name = 'opensuse'
        elif name.startswith('SUSE'):
            name = 'sle'
        name = name.lower()

        version = cls._get_value(str_, 'Release')
        codename = cls._get_value(str_, 'Codename').lower()
        obj = cls(name=name, version=version, codename=codename)

        return obj

    @classmethod
    def from_os_release(cls, os_release_str):
        """
        Parse /etc/os-release and populate attributes

        Given output like:
            NAME="Ubuntu"
            VERSION="12.04.4 LTS, Precise Pangolin"
            ID=ubuntu
            ID_LIKE=debian
            PRETTY_NAME="Ubuntu precise (12.04.4 LTS)"
            VERSION_ID="12.04"

        Attributes will be:
            name = 'ubuntu'
            version = '12.04'
            codename = None
        Additionally, we set the package type:
            package_type = 'deb'
        """
        str_ = os_release_str.strip()
        name = cls._get_value(str_, 'ID').lower()
        if name == 'sles':
            name = 'sle'
        elif name == 'opensuse-leap':
            name = 'opensuse'
        version = cls._get_value(str_, 'VERSION_ID')
        obj = cls(name=name, version=version)

        return obj

    @classmethod
    def version_codename(cls, name, version_or_codename):
        """
        Return (version, codename) based on one input, trying to infer
        which we're given
        """
        codename = None
        version = None

        try:
            codename = OS._version_to_codename(name, version_or_codename)
        except KeyError:
            pass

        try:
            version = OS._codename_to_version(name, version_or_codename)
        except (KeyError, RuntimeError):
            pass

        if version:
            codename = version_or_codename
        elif codename:
            version = version_or_codename
        else:
            raise KeyError('%s not a %s version or codename' %
                           (version_or_codename, name))
        return version, codename

    @staticmethod
    def _get_value(str_, name):
        regex = '^%s[:=](.+)' % name
        match = re.search(regex, str_, flags=re.M)
        if match:
            return match.groups()[0].strip(' \t"\'')
        return ''

    def _set_package_type(self):
        if self.name in self._deb_distros:
            self.package_type = "deb"
        elif self.name in self._rpm_distros:
            self.package_type = "rpm"

    def to_dict(self):
        return dict(
            name=self.name,
            version=self.version,
            codename=self.codename,
        )

    def __str__(self):
        return " ".join([self.name, self.version]).strip()

    def __repr__(self):
        return "OS(name={name}, version={version}, codename={codename})"\
            .format(name=repr(self.name),
                    version=repr(self.version),
                    codename=repr(self.codename))

    def __eq__(self, other):
        for slot in self.__slots__:
            if not getattr(self, slot) == getattr(other, slot):
                return False
        return True
<commit_msg>opsys: Add Focal Fossa<commit_after>import re

DISTRO_CODENAME_MAP = {
    "ubuntu": {
        "20.04": "focal",
        "18.04": "bionic",
        "17.10": "artful",
        "17.04": "zesty",
        "16.10": "yakkety",
        "16.04": "xenial",
        "15.10": "wily",
        "15.04": "vivid",
        "14.10": "utopic",
        "14.04": "trusty",
        "13.10": "saucy",
        "12.04": "precise",
    },
    "debian": {
        "7": "wheezy",
        "8": "jessie",
        "9": "stretch",
    },
    "rhel": {
        "8": "ootpa",
        "7": "maipo",
        "6": "santiago",
    },
    "centos": {
        "8": "core",
        "7": "core",
        "6": "core",
    },
    "fedora": {
        "28": "28",
        "27": "27",
        "26": "26",
        "25": "25",
        "24": "24",
        "23": "23",
        "22": "22",
        "21": "21",
        "20": "heisenbug",
    },
    "opensuse": {
        "15.0": "leap",
        "15.1": "leap",
        "15.2": "leap",
        "42.2": "leap",
        "42.3": "leap",
    },
    "sle": {
        "12.1": "sle",
        "12.2": "sle",
        "12.3": "sle",
        "15.0": "sle",
        "15.1": "sle",
        "15.2": "sle",
    },
}

DEFAULT_OS_VERSION = dict(
    ubuntu="18.04",
    fedora="25",
    centos="7.6",
    opensuse="15.0",
    sle="15.0",
    rhel="7.6",
    debian='8.0'
)

class OS(object):
    """
    Class that parses either /etc/os-release or the output of 'lsb_release -a'
    and provides OS name and version information.

    Must be initialized with OS.from_lsb_release or OS.from_os_release
    """

    __slots__ = ['name', 'version', 'codename', 'package_type']

    _deb_distros = ('debian', 'ubuntu')
    _rpm_distros = ('fedora', 'rhel', 'centos', 'opensuse', 'sle')

    def __init__(self, name=None, version=None, codename=None):
        self.name = name
        self.version = version or self._codename_to_version(name, codename)
        self.codename = codename or self._version_to_codename(name, version)
        self._set_package_type()

    @staticmethod
    def _version_to_codename(name, version):
        for (_version, codename) in DISTRO_CODENAME_MAP[name].items():
            if str(version) == _version or str(version).split('.')[0] == _version:
                return codename

    @staticmethod
    def _codename_to_version(name, codename):
        for (version, _codename) in DISTRO_CODENAME_MAP[name].items():
            if codename == _codename:
                return version
        raise RuntimeError("No version found for %s %s !" % (
            name,
            codename,
        ))

    @classmethod
    def from_lsb_release(cls, lsb_release_str):
        """
        Parse output from lsb_release -a and populate attributes

        Given output like:
            Distributor ID: Ubuntu
            Description:    Ubuntu 12.04.4 LTS
            Release:        12.04
            Codename:       precise

        Attributes will be:
            name = 'ubuntu'
            version = '12.04'
            codename = 'precise'
        Additionally, we set the package type:
            package_type = 'deb'
        """
        str_ = lsb_release_str.strip()
        name = cls._get_value(str_, 'Distributor ID')
        if name == 'RedHatEnterpriseServer':
            name = 'rhel'
        elif name.startswith('openSUSE'):
            name = 'opensuse'
        elif name.startswith('SUSE'):
            name = 'sle'
        name = name.lower()

        version = cls._get_value(str_, 'Release')
        codename = cls._get_value(str_, 'Codename').lower()
        obj = cls(name=name, version=version, codename=codename)

        return obj

    @classmethod
    def from_os_release(cls, os_release_str):
        """
        Parse /etc/os-release and populate attributes

        Given output like:
            NAME="Ubuntu"
            VERSION="12.04.4 LTS, Precise Pangolin"
            ID=ubuntu
            ID_LIKE=debian
            PRETTY_NAME="Ubuntu precise (12.04.4 LTS)"
            VERSION_ID="12.04"

        Attributes will be:
            name = 'ubuntu'
            version = '12.04'
            codename = None
        Additionally, we set the package type:
            package_type = 'deb'
        """
        str_ = os_release_str.strip()
        name = cls._get_value(str_, 'ID').lower()
        if name == 'sles':
            name = 'sle'
        elif name == 'opensuse-leap':
            name = 'opensuse'
        version = cls._get_value(str_, 'VERSION_ID')
        obj = cls(name=name, version=version)

        return obj

    @classmethod
    def version_codename(cls, name, version_or_codename):
        """
        Return (version, codename) based on one input, trying to infer
        which we're given
        """
        codename = None
        version = None

        try:
            codename = OS._version_to_codename(name, version_or_codename)
        except KeyError:
            pass

        try:
            version = OS._codename_to_version(name, version_or_codename)
        except (KeyError, RuntimeError):
            pass

        if version:
            codename = version_or_codename
        elif codename:
            version = version_or_codename
        else:
            raise KeyError('%s not a %s version or codename' %
                           (version_or_codename, name))
        return version, codename

    @staticmethod
    def _get_value(str_, name):
        regex = '^%s[:=](.+)' % name
        match = re.search(regex, str_, flags=re.M)
        if match:
            return match.groups()[0].strip(' \t"\'')
        return ''

    def _set_package_type(self):
        if self.name in self._deb_distros:
            self.package_type = "deb"
        elif self.name in self._rpm_distros:
            self.package_type = "rpm"

    def to_dict(self):
        return dict(
            name=self.name,
            version=self.version,
            codename=self.codename,
        )

    def __str__(self):
        return " ".join([self.name, self.version]).strip()

    def __repr__(self):
        return "OS(name={name}, version={version}, codename={codename})"\
            .format(name=repr(self.name),
                    version=repr(self.version),
                    codename=repr(self.codename))

    def __eq__(self, other):
        for slot in self.__slots__:
            if not getattr(self, slot) == getattr(other, slot):
                return False
        return True
<|endoftext|>


<commit_before>#!/usr/bin/python3

import gmplot
import json
import ast
import pyproj
from shapely.geometry import LineString, Point
import time
# local copy from https://pypi.python.org/pypi/yattag
import yattag
import glob

MAPOUTPUTDIR = 'tfl_bus_routes_maps'

with open('portalData/49k_portalData.json') as f:
    j = json.load(f)

# we create Point objects now, it saves ~20% of the time per iteration
portals = [Point(x[1]['lngE6']/10.0**6, x[1]['latE6']/10.0**6) for x in j.items()]

geod = pyproj.Geod(ellps='WGS84')

start = end = 0

#busroutes = ['tfl_bus_routes/309_outbound.json', 'tfl_bus_routes/309_inbound.json']
busroutes = sorted(glob.glob('tfl_bus_routes/*.json'))

results = []

for busroute in busroutes:

    start = time.time()

    with open(busroute) as f:
        route = json.load(f)

    print('Processing %s %s... ' % (route['lineId'], route['direction']), end="", flush=True)

    # lineString is a Unicode string containing a list of pairs, for the points
    # on the map drawing a line the bus takes on the streets, so need to convert
    # that string into a python datatype
    l = ast.literal_eval(route['lineStrings'][0])

    line = LineString(l[0])

    portals_set = set()

    for portal in portals:

        interp = line.interpolate(line.project(portal))

        # https://github.com/mlaloux/My-Python-GIS_StackExchange-answers/blob/master/What%20is%20the%20unit%20the%20shapely%20length%20attribute%3F.md
        angle1, angle2, distance = geod.inv(portal.x, portal.y, interp.x, interp.y)

        if abs(distance) <= 40.0:
            portals_set.add(portal.coords[0])

    lats = [x[1] for x in l[0]]
    lngs = [x[0] for x in l[0]]

    # center the map around the "centroid" of the bus route
    gmap = gmplot.GoogleMapPlotter(center_lng=line.centroid.x, center_lat=line.centroid.y, zoom=14)
    # fit the map around the bounds of the bus route line
    gmap.fitBounds(line.bounds[1], line.bounds[0], line.bounds[3], line.bounds[2])

    gmap.plot(lats, lngs)
    for port in portals_set:
        gmap.marker(port[1], port[0])
    mapfile = "%s/%s_%s.html" % (MAPOUTPUTDIR, route['lineId'], route['direction'])
    gmap.draw(mapfile)

    end = time.time()

    print('done: portals found = %d, time = %fs' % (len(portals_set), end - start))

    results.append([route['lineId'], route['direction'] + ' (' +
                    route['stopPointSequences'][0]['stopPoint'][0]['name'] +
                    ' to ' +
                    route['stopPointSequences'][0]['stopPoint'][-1]['name'] +
                    ')', len(portals_set), mapfile])

# generate an html with the results
doc, tag, text = yattag.Doc().tagtext()

with tag('html'):
    with tag('title'):
        text('London TfL bus routes and portals in their range')

    with tag('body'):
        with tag('table', border = '1'):
            with tag('tr'):
                with tag('td'):
                    with tag('b'): text('Bus Line')
                with tag('td'):
                    with tag('b'): text('Direction')
                with tag('td'):
                    with tag('b'): text('No. of Portals')
                with tag('td'):
                    with tag('b'): text('Link to GMap')
            for line, direction, portls, mapfile in results:
                with tag('tr'):
                    with tag('td'): text(line)
                    with tag('td'): text(direction)
                    with tag('td'): text(str(portls))
                    with tag('td'):
                        with tag('a', target='_blank', href=mapfile):
                            text('Map')

with open('tfl_bus_routes_maps.html', 'w') as f:
    f.write(doc.getvalue())

print('results written to tfl_bus_routes_maps.html')
<commit_msg>add an arrow to show the direction of the bus route<commit_after>#!/usr/bin/python3

import gmplot
import json
import ast
import pyproj
from shapely.geometry import LineString, Point
import time
# local copy from https://pypi.python.org/pypi/yattag
import yattag
import glob

MAPOUTPUTDIR = 'tfl_bus_routes_maps'

with open('portalData/49k_portalData.json') as f:
    j = json.load(f)

# we create Point objects now, it saves ~20% of the time per iteration
portals = [Point(x[1]['lngE6']/10.0**6, x[1]['latE6']/10.0**6) for x in j.items()]

geod = pyproj.Geod(ellps='WGS84')

start = end = 0

#busroutes = ['tfl_bus_routes/309_outbound.json', 'tfl_bus_routes/309_inbound.json']
busroutes = sorted(glob.glob('tfl_bus_routes/*.json'))

results = []

for busroute in busroutes:

    start = time.time()

    with open(busroute) as f:
        route = json.load(f)

    print('Processing %s %s... ' % (route['lineId'], route['direction']), end="", flush=True)

    # lineString is a Unicode string containing a list of pairs, for the points
    # on the map drawing a line the bus takes on the streets, so need to convert
    # that string into a python datatype
    l = ast.literal_eval(route['lineStrings'][0])

    line = LineString(l[0])

    portals_set = set()

    for portal in portals:

        interp = line.interpolate(line.project(portal))

        # https://github.com/mlaloux/My-Python-GIS_StackExchange-answers/blob/master/What%20is%20the%20unit%20the%20shapely%20length%20attribute%3F.md
        angle1, angle2, distance = geod.inv(portal.x, portal.y, interp.x, interp.y)

        if abs(distance) <= 40.0:
            portals_set.add(portal.coords[0])

    lats = [x[1] for x in l[0]]
    lngs = [x[0] for x in l[0]]

    # center the map around the "centroid" of the bus route
    gmap = gmplot.GoogleMapPlotter(center_lng=line.centroid.x, center_lat=line.centroid.y, zoom=14)
    # fit the map around the bounds of the bus route line
    gmap.fitBounds(line.bounds[1], line.bounds[0], line.bounds[3], line.bounds[2])

    gmap.add_symbol('arrowSymbol', {'path': 'google.maps.SymbolPath.FORWARD_CLOSED_ARROW',
                                    'scale': 2})

    gmap.plot(lats, lngs, icons={'icon': 'arrowSymbol', 'offset': '7%', 'repeat': '7%'})

    for port in portals_set:
        gmap.marker(port[1], port[0])
    mapfile = "%s/%s_%s.html" % (MAPOUTPUTDIR, route['lineId'], route['direction'])
    gmap.draw(mapfile)

    end = time.time()

    print('done: portals found = %d, time = %fs' % (len(portals_set), end - start))

    results.append([route['lineId'], route['direction'] + ' (' +
                    route['stopPointSequences'][0]['stopPoint'][0]['name'] +
                    ' to ' +
                    route['stopPointSequences'][0]['stopPoint'][-1]['name'] +
                    ')', len(portals_set), mapfile])

# generate an html with the results
doc, tag, text = yattag.Doc().tagtext()

with tag('html'):
    with tag('title'):
        text('London TfL bus routes and portals in their range')

    with tag('body'):
        with tag('table', border = '1'):
            with tag('tr'):
                with tag('td'):
                    with tag('b'): text('Bus Line')
                with tag('td'):
                    with tag('b'): text('Direction')
                with tag('td'):
                    with tag('b'): text('No. of Portals')
                with tag('td'):
                    with tag('b'): text('Link to GMap')
            for line, direction, portls, mapfile in results:
                with tag('tr'):
                    with tag('td'): text(line)
                    with tag('td'): text(direction)
                    with tag('td'): text(str(portls))
                    with tag('td'):
                        with tag('a', target='_blank', href=mapfile):
                            text('Map')

with open('tfl_bus_routes_maps.html', 'w') as f:
    f.write(doc.getvalue())

print('results written to tfl_bus_routes_maps.html')
<|endoftext|>


<commit_before>import datetime
import json
import sqlite3

import bottle

# Database set up
connection = sqlite3.connect('meetup.db')
cursor = connection.cursor()
cursor.execute('CREATE TABLE IF NOT EXISTS people (username TEXT, name TEXT)')
cursor.close()

app = bottle.Bottle()

# The base route loads a simple html file that starts require.js
@app.route('/')
def index():
    return bottle.static_file('index.html', root='static')

# Route all files in the /static directory
@app.route('/static/<filepath:path>')
def server_static(filepath):
    return bottle.static_file(filepath, root='static')

@app.route('/api/status')
def status():
    return {'status': 'alive'}

@app.error(404)
def error404(error):
    return "Oops! That's not supported. (404)"

@app.route('/api/people', method='POST')
def create_person():
    person = bottle.request.json
    username = person['username']
    name = person['name']
    cursor = connection.cursor()
    cursor.execute('INSERT INTO people VALUES(?,?)', (username, name))
    cursor.close()
    person['@type'] = 'http://schema.org/Person'
    person['@id'] = '/api/person/' + username
    person['id'] = username
    bottle.response.status = 201
    return json.dumps(person)

@app.route('/api/people')
def get_people():
    cursor = connection.cursor()
    people = []
    for row in cursor.execute('SELECT * FROM people'):
        person = {}
        person['username'] = row[0]
        person['name'] = row[1]
        person['@type'] = 'http://schema.org/Person'
        person['@id'] = '/api/person/' + person['username']
        person['id'] = person['username']
        people.append(person)
    cursor.close()
    return json.dumps(people)

@app.route('/api/people/<username>', method='DELETE')
def delete_person(username):
    cursor = connection.cursor()
    cursor.execute("DELETE FROM people WHERE username='" + username + "'")
    cursor.close()
    bottle.response.status = 204
    return

# Todo: These need to be swapped out with real data from the database
@app.route('/api/people/<username>', method='GET')
def get_person(username):
    return json.dumps({
        "@type": "http://schema.org/Person",
        "@id": "/people/" + username,
        "id": username,
        "name": "Erik Ringsmuth"
    })

@app.route('/api/events')
def get_events():
    return json.dumps([{
        "@type": "http://schema.org/Event",
        "@id": "/events/1",
        "id": "guid",
        "attendees": [],
        "name": "string",
        "description": "string",
        "location": {},
        "startDate": datetime.datetime.now().isoformat(),
        "endDate": datetime.datetime.now().isoformat(),
        "duration": ""
    }])

@app.route('/api/events/<id>', method='GET')
def get_event(id):
    return json.dumps({
        "@type": "http://schema.org/Event",
        "@id": "/events/" + id,
        "id": "guid",
        "attendees": [],
        "name": "string",
        "description": "string",
        "location": {},
        "startDate": datetime.datetime.now().isoformat(),
        "endDate": datetime.datetime.now().isoformat(),
        "duration": ""
    })

@app.route('/api/places')
def get_places():
    return json.dumps([{
        "@type": "http://schema.org/Place",
        "@id": "/places/1",
        "id": "guid",
        "name": "string",
        "description": "string",
        "address": {
            "addressCountry": "string",
            "addressLocality": "string",
            "addressRegion": "string",
            "postalCode": "string",
            "postOfficeBoxNumber": "string",
            "streetAddress": "string"
        }
    }])

@app.route('/api/places/<id>', method='GET')
def get_place(id):
    return json.dumps({
        "@type": "http://schema.org/Place",
        "@id": "/places/" + id,
        "id": "guid",
        "name": "string",
        "description": "string",
        "address": {
            "addressCountry": "string",
            "addressLocality": "string",
            "addressRegion": "string",
            "postalCode": "string",
            "postOfficeBoxNumber": "string",
            "streetAddress": "string"
        }
    })

@app.route('/api/things')
def get_things():
    return json.dumps([{
        "@type": "http://schema.org/Thing",
        "@id": "/things/1",
        "id": "guid",
        "name": "string",
        "description": "string"
    }])

@app.route('/api/things/<id>', method='GET')
def get_thing(id):
    return json.dumps({
        "@type": "http://schema.org/Thing",
        "@id": "/things/" + id,
        "id": "guid",
        "name": "string",
        "description": "string"
    })

# Catch all other routes and have them load the main JS app
@app.route('/<:path>')
def index():
    return bottle.static_file('index.html', root='static')

app.run(host='localhost', port=8080, debug=True)
<commit_msg>working on read single user<commit_after>import datetime
import json
import sqlite3

import bottle

# Database set up
connection = sqlite3.connect('meetup.db')
cursor = connection.cursor()
cursor.execute('CREATE TABLE IF NOT EXISTS people (username TEXT, name TEXT)')
cursor.close()

app = bottle.Bottle()

# The base route loads a simple html file that starts require.js
@app.route('/')
def index():
    return bottle.static_file('index.html', root='static')

# Route all files in the /static directory
@app.route('/static/<filepath:path>')
def server_static(filepath):
    return bottle.static_file(filepath, root='static')

@app.route('/api/status')
def status():
    return {'status': 'alive'}

@app.error(404)
def error404(error):
    return "Oops! That's not supported. (404)"

@app.route('/api/people', method='POST')
def post_person():
    person = bottle.request.json
    username = person['username']
    name = person['name']
    cursor = connection.cursor()
    cursor.execute('INSERT INTO people VALUES(?,?)', (username, name))
    cursor.close()
    person['@type'] = 'http://schema.org/Person'
    person['@id'] = '/api/person/' + username
    person['id'] = username
    bottle.response.status = 201
    return json.dumps(person)

@app.route('/api/people')
def get_people():
    cursor = connection.cursor()
    people = []
    for row in cursor.execute('SELECT * FROM people'):
        person = {}
        person['username'] = row[0]
        person['name'] = row[1]
        person['@type'] = 'http://schema.org/Person'
        person['@id'] = '/api/person/' + person['username']
        person['id'] = person['username']
        people.append(person)
    cursor.close()
    return json.dumps(people)

@app.route('/api/people/<username>', method='GET')
def get_person(username):
    cursor = connection.cursor()
    cursor.execute("SELECT * FROM people WHERE username='" + username + "'")
    data = cursor.fetch_all()
    person = {}
    person['username'] = data[0]
    person['name'] = data[1]
    person['@type'] = 'http://schema.org/Person'
    person['@id'] = '/api/person/' + person['username']
    person['id'] = person['username']
    cursor.close()
    return json.dumps(person)

@app.route('/api/people/<username>', method='DELETE')
def delete_person(username):
    cursor = connection.cursor()
    cursor.execute("DELETE FROM people WHERE username='" + username + "'")
    cursor.close()
    bottle.response.status = 204
    return

# Todo: These need to be swapped out with real data from the database
@app.route('/api/events')
def get_events():
    return json.dumps([{
        "@type": "http://schema.org/Event",
        "@id": "/events/1",
        "id": "guid",
        "attendees": [],
        "name": "string",
        "description": "string",
        "location": {},
        "startDate": datetime.datetime.now().isoformat(),
        "endDate": datetime.datetime.now().isoformat(),
        "duration": ""
    }])

@app.route('/api/events/<id>', method='GET')
def get_event(id):
    return json.dumps({
        "@type": "http://schema.org/Event",
        "@id": "/events/" + id,
        "id": "guid",
        "attendees": [],
        "name": "string",
        "description": "string",
        "location": {},
        "startDate": datetime.datetime.now().isoformat(),
        "endDate": datetime.datetime.now().isoformat(),
        "duration": ""
    })

@app.route('/api/places')
def get_places():
    return json.dumps([{
        "@type": "http://schema.org/Place",
        "@id": "/places/1",
        "id": "guid",
        "name": "string",
        "description": "string",
        "address": {
            "addressCountry": "string",
            "addressLocality": "string",
            "addressRegion": "string",
            "postalCode": "string",
            "postOfficeBoxNumber": "string",
            "streetAddress": "string"
        }
    }])

@app.route('/api/places/<id>', method='GET')
def get_place(id):
    return json.dumps({
        "@type": "http://schema.org/Place",
        "@id": "/places/" + id,
        "id": "guid",
        "name": "string",
        "description": "string",
        "address": {
            "addressCountry": "string",
            "addressLocality": "string",
            "addressRegion": "string",
            "postalCode": "string",
            "postOfficeBoxNumber": "string",
            "streetAddress": "string"
        }
    })

@app.route('/api/things')
def get_things():
    return json.dumps([{
        "@type": "http://schema.org/Thing",
        "@id": "/things/1",
        "id": "guid",
        "name": "string",
        "description": "string"
    }])

@app.route('/api/things/<id>', method='GET')
def get_thing(id):
    return json.dumps({
        "@type": "http://schema.org/Thing",
        "@id": "/things/" + id,
        "id": "guid",
        "name": "string",
        "description": "string"
    })

# Catch all other routes and have them load the main JS app
@app.route('/<:path>')
def index():
    return bottle.static_file('index.html', root='static')

app.run(host='localhost', port=8080, debug=True)
<|endoftext|>


<commit_before>from datetime import datetime, timedelta

from django import forms

from .models import *

class NotafiscalChaveForm(forms.Form):
    chave = forms.CharField(
        widget=forms.TextInput())

class NotafiscalRelForm(forms.Form):

    def data_ini():
        return (datetime.now().replace(day=1)-timedelta(days=1)).replace(day=1)

    data_de = forms.DateField(
        label='Data do Faturamento: De',
        initial=data_ini,
        widget=forms.DateInput(attrs={'type': 'date',
                               'autofocus': 'autofocus'}))
    data_ate = forms.DateField(
        label='Até', required=False,
        widget=forms.DateInput(attrs={'type': 'date'}))

    uf = forms.CharField(
        label='UF', max_length=2, min_length=2, required=False,
        widget=forms.TextInput(attrs={'size': 2}))

    nf = forms.CharField(
        label='Número da NF', required=False,
        widget=forms.TextInput(attrs={'type': 'number'}))

    cliente = forms.CharField(
        label='Cliente', required=False,
        help_text='Parte do nome ou início do CNPJ.',
        widget=forms.TextInput())

    transportadora = forms.CharField(
        label='Transportadora', required=False,
        help_text='Sigla da transportadora.',
        widget=forms.TextInput())

    CHOICES = [('N', 'Não filtra'),
               ('C', 'Com data de saída informada'),
               ('S', 'Sem data de saída')]
    data_saida = forms.ChoiceField(
        label='Quanto a data de saída', choices=CHOICES, initial='S')

    CHOICES = [('T', 'Todos (Sim ou Não)'),
               ('S', 'Sim'),
               ('N', 'Não')]
    entregue = forms.ChoiceField(
        choices=CHOICES, initial='T')

    CHOICES = [('N', 'Número da nota fiscal'),
               ('A', 'Atraso (maior primeiro)')]
    ordem = forms.ChoiceField(
        label='Ordem de apresentação', choices=CHOICES, initial='A')

    CHOICES = [('V', 'Apenas NF de venda e ativas (não canceladas)'),
               ('T', 'Totas as notas fiscais')]
    listadas = forms.ChoiceField(
        label='Notas listadas', choices=CHOICES, initial='V')

    posicao = forms.ModelChoiceField(
        label='Posição', required=False,
        queryset=PosicaoCarga.objects.all().order_by('id'),
        empty_label='--Todas--')

    def clean_uf(self):
        uf = self.cleaned_data['uf'].upper()
        data = self.data.copy()
        data['uf'] = uf
        self.data = data
        return uf

    def clean_data_de(self):
        data_de = self.cleaned_data['data_de']
        if data_de:
            if data_de.year < 100:
                data_de = data_de.timedelta(years=2000)
        return data_de

class NfPosicaoForm(forms.Form):
    data = forms.DateField(
        label='Data de movimento da carga',
        help_text='Só pode ficar vazia de posição form "Entregue ao apoio".',
        initial=datetime.now(), required=False,
        widget=forms.DateInput(attrs={'type': 'date',
                               'autofocus': 'autofocus'}))

    posicao = forms.ModelChoiceField(
        label='Posição',
        queryset=PosicaoCarga.objects.all().order_by(
            'id'), initial=2)
<commit_msg>form aceita "Totas" no campo Posição<commit_after>from datetime import datetime, timedelta

from django import forms

from .models import *

class NotafiscalChaveForm(forms.Form):
    chave = forms.CharField(
        widget=forms.TextInput())

class NotafiscalRelForm(forms.Form):

    def data_ini():
        return (datetime.now().replace(day=1)-timedelta(days=1)).replace(day=1)

    data_de = forms.DateField(
        label='Data do Faturamento: De',
        initial=data_ini,
        widget=forms.DateInput(attrs={'type': 'date',
                               'autofocus': 'autofocus'}))
    data_ate = forms.DateField(
        label='Até', required=False,
        widget=forms.DateInput(attrs={'type': 'date'}))

    uf = forms.CharField(
        label='UF', max_length=2, min_length=2, required=False,
        widget=forms.TextInput(attrs={'size': 2}))

    nf = forms.CharField(
        label='Número da NF', required=False,
        widget=forms.TextInput(attrs={'type': 'number'}))

    cliente = forms.CharField(
        label='Cliente', required=False,
        help_text='Parte do nome ou início do CNPJ.',
        widget=forms.TextInput())

    transportadora = forms.CharField(
        label='Transportadora', required=False,
        help_text='Sigla da transportadora.',
        widget=forms.TextInput())

    CHOICES = [('N', 'Não filtra'),
               ('C', 'Com data de saída informada'),
               ('S', 'Sem data de saída')]
    data_saida = forms.ChoiceField(
        label='Quanto a data de saída', choices=CHOICES, initial='S')

    CHOICES = [('T', 'Todos (Sim ou Não)'),
               ('S', 'Sim'),
               ('N', 'Não')]
    entregue = forms.ChoiceField(
        choices=CHOICES, initial='T')

    CHOICES = [('N', 'Número da nota fiscal'),
               ('A', 'Atraso (maior primeiro)')]
    ordem = forms.ChoiceField(
        label='Ordem de apresentação', choices=CHOICES, initial='A')

    CHOICES = [('V', 'Apenas NF de venda e ativas (não canceladas)'),
               ('T', 'Totas as notas fiscais')]
    listadas = forms.ChoiceField(
        label='Notas listadas', choices=CHOICES, initial='V')

    posicao = forms.ModelChoiceField(
        label='Posição', required=False,
        queryset=PosicaoCarga.objects.all().order_by('id'),
        empty_label='--Todas--')

    def clean_uf(self):
        uf = self.cleaned_data['uf'].upper()
        data = self.data.copy()
        data['uf'] = uf
        self.data = data
        return uf

    def clean_data_de(self):
        data_de = self.cleaned_data['data_de']
        if data_de:
            if data_de.year < 100:
                data_de = data_de.timedelta(years=2000)
        return data_de

class NfPosicaoForm(forms.Form):
    data = forms.DateField(
        label='Data de movimento da carga',
        help_text='Só pode ficar vazia de posição form "Entregue ao apoio".',
        initial=datetime.now(), required=False,
        widget=forms.DateInput(attrs={'type': 'date',
                               'autofocus': 'autofocus'}))

    posicao = forms.ModelChoiceField(
        label='Posição', required=False,
        queryset=PosicaoCarga.objects.all().order_by('id'),
        initial=2, empty_label='--Todas--')
<|endoftext|>


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

{
  'variables': {
    'conditions': [
      ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
        'os_include': 'linux'
      }],
      ['OS=="mac"', {'os_include': 'mac'}],
      ['OS=="win"', {'os_include': 'win32'}],
    ],
    'use_system_libxml%': 0,
  },
  'targets': [
    {
      'target_name': 'libxml',
      'conditions': [
        ['(OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris") and use_system_libxml', {
          'type': 'settings',
          'direct_dependent_settings': {
            'cflags': [
              '<!@(pkg-config --cflags libxml-2.0)',
            ],
            'defines': [
              'USE_SYSTEM_LIBXML',
            ],
          },
          'link_settings': {
            'ldflags': [
              '<!@(pkg-config --libs-only-L --libs-only-other libxml-2.0)',
            ],
            'libraries': [
              '<!@(pkg-config --libs-only-l libxml-2.0)',
            ],
          },
        }, { # else: OS != "linux" or ! use_system_libxml
          'type': '<(library)',
          'msvs_guid': 'F9810DE8-CBC3-4605-A7B1-ECA2D5292FD7',
          'sources': [
            'include/libxml/c14n.h',
            'include/libxml/catalog.h',
            'include/libxml/chvalid.h',
            'include/libxml/debugXML.h',
            'include/libxml/dict.h',
            'include/libxml/DOCBparser.h',
            'include/libxml/encoding.h',
            'include/libxml/entities.h',
            'include/libxml/globals.h',
            'include/libxml/hash.h',
            'include/libxml/HTMLparser.h',
            'include/libxml/HTMLtree.h',
            'include/libxml/list.h',
            'include/libxml/nanoftp.h',
            'include/libxml/nanohttp.h',
            'include/libxml/parser.h',
            'include/libxml/parserInternals.h',
            'include/libxml/pattern.h',
            'include/libxml/relaxng.h',
            'include/libxml/SAX.h',
            'include/libxml/SAX2.h',
            'include/libxml/schemasInternals.h',
            'include/libxml/schematron.h',
            'include/libxml/threads.h',
            'include/libxml/tree.h',
            'include/libxml/uri.h',
            'include/libxml/valid.h',
            'include/libxml/xinclude.h',
            'include/libxml/xlink.h',
            'include/libxml/xmlautomata.h',
            'include/libxml/xmlerror.h',
            'include/libxml/xmlexports.h',
            'include/libxml/xmlIO.h',
            'include/libxml/xmlmemory.h',
            'include/libxml/xmlmodule.h',
            'include/libxml/xmlreader.h',
            'include/libxml/xmlregexp.h',
            'include/libxml/xmlsave.h',
            'include/libxml/xmlschemas.h',
            'include/libxml/xmlschemastypes.h',
            'include/libxml/xmlstring.h',
            'include/libxml/xmlunicode.h',
            'include/libxml/xmlwriter.h',
            'include/libxml/xpath.h',
            'include/libxml/xpathInternals.h',
            'include/libxml/xpointer.h',
            'include/win32config.h',
            'include/wsockcompat.h',
            'linux/config.h',
            'linux/include/libxml/xmlversion.h',
            'mac/config.h',
            'mac/include/libxml/xmlversion.h',
            'win32/config.h',
            'win32/include/libxml/xmlversion.h',
            'acconfig.h',
            'c14n.c',
            'catalog.c',
            'chvalid.c',
            'debugXML.c',
            'dict.c',
            'DOCBparser.c',
            'elfgcchack.h',
            'encoding.c',
            'entities.c',
            'error.c',
            'globals.c',
            'hash.c',
            'HTMLparser.c',
            'HTMLtree.c',
            'legacy.c',
            'libxml.h',
            'list.c',
            'nanoftp.c',
            'nanohttp.c',
            'parser.c',
            'parserInternals.c',
            'pattern.c',
            'relaxng.c',
            'SAX.c',
            'SAX2.c',
            'schematron.c',
            'threads.c',
            'tree.c',
            #'trio.c',
            #'trio.h',
            #'triodef.h',
            #'trionan.c',
            #'trionan.h',
            #'triop.h',
            #'triostr.c',
            #'triostr.h',
            'uri.c',
            'valid.c',
            'xinclude.c',
            'xlink.c',
            'xmlIO.c',
            'xmlmemory.c',
            'xmlmodule.c',
            'xmlreader.c',
            'xmlregexp.c',
            'xmlsave.c',
            'xmlschemas.c',
            'xmlschemastypes.c',
            'xmlstring.c',
            'xmlunicode.c',
            'xmlwriter.c',
            'xpath.c',
            'xpointer.c',
          ],
          'include_dirs': [
            '<(os_include)',
            '<(os_include)/include',
            'include',
          ],
          'dependencies': [
            '../icu/icu.gyp:icuuc',
            '../zlib/zlib.gyp:zlib',
          ],
          'export_dependent_settings': [
            '../icu/icu.gyp:icuuc',
          ],
          'direct_dependent_settings': {
            'include_dirs': [
              '<(os_include)/include',
              'include',
            ],
          },
          'conditions': [
            ['OS=="linux"', {
              'link_settings': {
                'libraries': [
                  # We need dl for dlopen() and friends.
                  '-ldl',
                ],
              },
            }],
            ['OS=="mac"', {'defines': ['_REENTRANT']}],
            ['OS=="win"', {
              'product_name': 'libxml2',
              'defines': [
                # This symbol prevents libxml from marking its functions with
                # __declspec(dllexport).
                'LIBXML_STATIC',
              ],
            }, {  # else: OS!="win"
              'product_name': 'xml2',
            }],
          ],
        }],
      ],
    },
  ],
}

# Local Variables:
# tab-width:2
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=2 shiftwidth=2:
<commit_msg>Revert the changes to libxml.gyp in r52725.<commit_after># Copyright (c) 2009 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

{
  'variables': {
    'conditions': [
      ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
        'os_include': 'linux'
      }],
      ['OS=="mac"', {'os_include': 'mac'}],
      ['OS=="win"', {'os_include': 'win32'}],
    ],
    'use_system_libxml%': 0,
  },
  'targets': [
    {
      'target_name': 'libxml',
      'conditions': [
        ['(OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris") and use_system_libxml', {
          'type': 'settings',
          'direct_dependent_settings': {
            'cflags': [
              '<!@(pkg-config --cflags libxml-2.0)',
            ],
            'defines': [
              'USE_SYSTEM_LIBXML',
            ],
          },
          'link_settings': {
            'ldflags': [
              '<!@(pkg-config --libs-only-L --libs-only-other libxml-2.0)',
            ],
            'libraries': [
              '<!@(pkg-config --libs-only-l libxml-2.0)',
            ],
          },
        }, { # else: OS != "linux" or ! use_system_libxml
          'type': '<(library)',
          'msvs_guid': 'F9810DE8-CBC3-4605-A7B1-ECA2D5292FD7',
          'sources': [
            'include/libxml/c14n.h',
            'include/libxml/catalog.h',
            'include/libxml/chvalid.h',
            'include/libxml/debugXML.h',
            'include/libxml/dict.h',
            'include/libxml/DOCBparser.h',
            'include/libxml/encoding.h',
            'include/libxml/entities.h',
            'include/libxml/globals.h',
            'include/libxml/hash.h',
            'include/libxml/HTMLparser.h',
            'include/libxml/HTMLtree.h',
            'include/libxml/list.h',
            'include/libxml/nanoftp.h',
            'include/libxml/nanohttp.h',
            'include/libxml/parser.h',
            'include/libxml/parserInternals.h',
            'include/libxml/pattern.h',
            'include/libxml/relaxng.h',
            'include/libxml/SAX.h',
            'include/libxml/SAX2.h',
            'include/libxml/schemasInternals.h',
            'include/libxml/schematron.h',
            'include/libxml/threads.h',
            'include/libxml/tree.h',
            'include/libxml/uri.h',
            'include/libxml/valid.h',
            'include/libxml/xinclude.h',
            'include/libxml/xlink.h',
            'include/libxml/xmlautomata.h',
            'include/libxml/xmlerror.h',
            'include/libxml/xmlexports.h',
            'include/libxml/xmlIO.h',
            'include/libxml/xmlmemory.h',
            'include/libxml/xmlmodule.h',
            'include/libxml/xmlreader.h',
            'include/libxml/xmlregexp.h',
            'include/libxml/xmlsave.h',
            'include/libxml/xmlschemas.h',
            'include/libxml/xmlschemastypes.h',
            'include/libxml/xmlstring.h',
            'include/libxml/xmlunicode.h',
            'include/libxml/xmlwriter.h',
            'include/libxml/xpath.h',
            'include/libxml/xpathInternals.h',
            'include/libxml/xpointer.h',
            'include/win32config.h',
            'include/wsockcompat.h',
            'linux/config.h',
            'linux/include/libxml/xmlversion.h',
            'mac/config.h',
            'mac/include/libxml/xmlversion.h',
            'win32/config.h',
            'win32/include/libxml/xmlversion.h',
            'acconfig.h',
            'c14n.c',
            'catalog.c',
            'chvalid.c',
            'debugXML.c',
            'dict.c',
            'DOCBparser.c',
            'elfgcchack.h',
            'encoding.c',
            'entities.c',
            'error.c',
            'globals.c',
            'hash.c',
            'HTMLparser.c',
            'HTMLtree.c',
            'legacy.c',
            'libxml.h',
            'list.c',
            'nanoftp.c',
            'nanohttp.c',
            'parser.c',
            'parserInternals.c',
            'pattern.c',
            'relaxng.c',
            'SAX.c',
            'SAX2.c',
            'schematron.c',
            'threads.c',
            'tree.c',
            #'trio.c',
            #'trio.h',
            #'triodef.h',
            #'trionan.c',
            #'trionan.h',
            #'triop.h',
            #'triostr.c',
            #'triostr.h',
            'uri.c',
            'valid.c',
            'xinclude.c',
            'xlink.c',
            'xmlIO.c',
            'xmlmemory.c',
            'xmlmodule.c',
            'xmlreader.c',
            'xmlregexp.c',
            'xmlsave.c',
            'xmlschemas.c',
            'xmlschemastypes.c',
            'xmlstring.c',
            'xmlunicode.c',
            'xmlwriter.c',
            'xpath.c',
            'xpointer.c',
          ],
          'defines': [
            # Define LIBXML_STATIC as nothing to match how libxml.h
            # (an internal header) defines LIBXML_STATIC, otherwise
            # we get the macro redefined warning from GCC.  (-DFOO
            # defines the macro FOO as 1.)
            'LIBXML_STATIC=',
          ],
          'include_dirs': [
            '<(os_include)',
            '<(os_include)/include',
            'include',
          ],
          'dependencies': [
            '../icu/icu.gyp:icuuc',
            '../zlib/zlib.gyp:zlib',
          ],
          'export_dependent_settings': [
            '../icu/icu.gyp:icuuc',
          ],
          'direct_dependent_settings': {
            'defines': [
              'LIBXML_STATIC',
            ],
            'include_dirs': [
              '<(os_include)/include',
              'include',
            ],
          },
          'conditions': [
            ['OS=="linux"', {
              'link_settings': {
                'libraries': [
                  # We need dl for dlopen() and friends.
                  '-ldl',
                ],
              },
            }],
            ['OS=="mac"', {'defines': ['_REENTRANT']}],
            ['OS=="win"', {
              'product_name': 'libxml2',
            }, {  # else: OS!="win"
              'product_name': 'xml2',
            }],
          ],
        }],
      ],
    },
  ],
}

# Local Variables:
# tab-width:2
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=2 shiftwidth=2:
<|endoftext|>


<commit_before><commit_msg>Don't build sqlite_shell when using the system sqlite. Review URL: http://codereview.chromium.org/42642<commit_after><|endoftext|>


<commit_before># Filename: ztplot.py
"""
Create a zt-Plot.

Usage:
    ztplot [-d DETX_FILE] [-t] -e EVENT_ID FILE
    ztplot [-d DETX_FILE] [-t] -f FRAME -c COUNTER FILE
    ztplot (-h | --help)
    ztplot --version

Options:
    FILE          Input file.
    -c COUNTER    Trigger counter.
    -d DETX_FILE  Detector file.
    -e EVENT_ID   Event ID.
    -f FRAME      Frame index.
    -t            Triggered DUs only.
    -h --help     Show this screen.

"""

import matplotlib.ticker as ticker
import matplotlib.pyplot as plt
import numpy as np

import km3pipe as kp
import km3pipe.style    # noqa
km3pipe.style.use("km3pipe")

__author__ = "Tamas Gal"
__copyright__ = "Copyright 2016, Tamas Gal and the KM3NeT collaboration."
__credits__ = []
__license__ = "MIT"
__maintainer__ = "Tamas Gal"
__email__ = "tgal@km3net.de"
__status__ = "Development"

def main():
    from docopt import docopt
    arguments = docopt(__doc__)

    try:
        event_id = int(arguments['-e'])
    except TypeError:
        pass
    else:
        pump = kp.io.GenericPump(arguments['FILE'])
        blob = pump[event_id]
        event_info = blob['EventInfo']
        hits = blob['Hits']
        if (arguments['-d']):
            cal = kp.calib.Calibration(filename=arguments['-d'])
        else:
            cal = kp.calib.Calibration(det_id=event_info.det_id)
        hits = cal.apply(hits)
        # triggered_dus = set(cal.detector.doms[h.dom_id][0] for h in hits)
        det = cal.detector
        if arguments['-t']:
            dus = set(det.doms[h.dom_id][0] for h in hits if h.triggered)
        else:
            dus = set(det.doms[h.dom_id][0] for h in hits)

        n_plots = len(dus)
        n_cols = int(np.ceil(np.sqrt(n_plots)))
        n_rows = int(n_plots / n_cols) + (n_plots % n_cols > 0)
        fig, axes = plt.subplots(
            ncols=n_cols,
            nrows=n_rows,
            sharex=True,
            sharey=True,
            figsize=(16, 16)
        )

        if n_cols == 1 and n_rows == 1:
            axes = (axes, )

        for ax, du in zip(axes, dus):
            du_hits = hits[hits.du == du]
            trig_hits = du_hits.triggered_rows

            ax.scatter(
                du_hits.time - min(du_hits.time),
                du_hits.pos_z,
                c='#09A9DE',
                label='hit'
            )
            ax.scatter(
                trig_hits.time - min(du_hits.time),
                trig_hits.pos_z,
                c='#FF6363',
                label='triggered hit'
            )
            ax.set_title('DU{0}'.format(du), fontsize=8, fontweight='bold')

        for ax in axes:
            ax.tick_params(labelsize=8)
            ax.yaxis.set_major_locator(ticker.MultipleLocator(50))
            xlabels = ax.get_xticklabels()
            for label in xlabels:
                label.set_rotation(45)

        plt.suptitle(
            "Filename: {0} - Event #{1}".format(arguments['FILE'], event_id),
            fontsize=16
        )
        fig.text(0.5, 0.04, 'time [ns]', ha='center')
        fig.text(0.08, 0.5, 'z [m]', va='center', rotation='vertical')
        #        plt.tight_layout()
        plt.show()
<commit_msg>Fix axes error<commit_after># Filename: ztplot.py
"""
Create a zt-Plot.

Usage:
    ztplot [-d DETX_FILE] [-t] -e EVENT_ID FILE
    ztplot [-d DETX_FILE] [-t] -f FRAME -c COUNTER FILE
    ztplot (-h | --help)
    ztplot --version

Options:
    FILE          Input file.
    -c COUNTER    Trigger counter.
    -d DETX_FILE  Detector file.
    -e EVENT_ID   Event ID.
    -f FRAME      Frame index.
    -t            Triggered DUs only.
    -h --help     Show this screen.

"""

import matplotlib.ticker as ticker
import matplotlib.pyplot as plt
import numpy as np

import km3pipe as kp
import km3pipe.style    # noqa
km3pipe.style.use("km3pipe")

__author__ = "Tamas Gal"
__copyright__ = "Copyright 2016, Tamas Gal and the KM3NeT collaboration."
__credits__ = []
__license__ = "MIT"
__maintainer__ = "Tamas Gal"
__email__ = "tgal@km3net.de"
__status__ = "Development"

def main():
    from docopt import docopt
    arguments = docopt(__doc__)

    try:
        event_id = int(arguments['-e'])
    except TypeError:
        pass
    else:
        pump = kp.io.GenericPump(arguments['FILE'])
        blob = pump[event_id]
        event_info = blob['EventInfo']
        hits = blob['Hits']
        if (arguments['-d']):
            cal = kp.calib.Calibration(filename=arguments['-d'])
        else:
            cal = kp.calib.Calibration(det_id=event_info.det_id)
        hits = cal.apply(hits)
        # triggered_dus = set(cal.detector.doms[h.dom_id][0] for h in hits)
        det = cal.detector
        if arguments['-t']:
            dus = set(det.doms[h.dom_id][0] for h in hits if h.triggered)
        else:
            dus = set(det.doms[h.dom_id][0] for h in hits)

        n_plots = len(dus)
        n_cols = int(np.ceil(np.sqrt(n_plots)))
        n_rows = int(n_plots / n_cols) + (n_plots % n_cols > 0)
        fig, axes = plt.subplots(
            ncols=n_cols,
            nrows=n_rows,
            sharex=True,
            sharey=True,
            figsize=(16, 16)
        )

        if n_cols == 1 and n_rows == 1:
            axes = (axes, )
        else:
            axes = axes.flatten()

        for ax, du in zip(axes, dus):
            du_hits = hits[hits.du == du]
            trig_hits = du_hits.triggered_rows

            ax.scatter(
                du_hits.time - min(du_hits.time),
                du_hits.pos_z,
                c='#09A9DE',
                label='hit'
            )
            ax.scatter(
                trig_hits.time - min(du_hits.time),
                trig_hits.pos_z,
                c='#FF6363',
                label='triggered hit'
            )
            ax.set_title('DU{0}'.format(du), fontsize=8, fontweight='bold')

        for ax in axes:
            ax.tick_params(labelsize=8)
            ax.yaxis.set_major_locator(ticker.MultipleLocator(50))
            xlabels = ax.get_xticklabels()
            for label in xlabels:
                label.set_rotation(45)

        plt.suptitle(
            "Filename: {0} - Event #{1}".format(arguments['FILE'], event_id),
            fontsize=16
        )
        fig.text(0.5, 0.04, 'time [ns]', ha='center')
        fig.text(0.08, 0.5, 'z [m]', va='center', rotation='vertical')
        #        plt.tight_layout()
        plt.show()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function
from kong.exceptions import ConflictError
from kong_admin.models import APIReference, PluginConfigurationReference
from kong_admin.enums import Plugins

from .base import KongProxySyncEngine

class APISyncEngine(KongProxySyncEngine):
    def plugins(self):
        return PluginConfigurationSyncEngine()

    def get_proxy_class(self):
        return APIReference

    def on_retrieve_all(self, client):
        apis = list(client.apis.iterate())
        for api_struct in apis:
            yield api_struct

    def is_published(self, client, kong_id, parent_kong_id=None):
        try:
            result = client.apis.retrieve(str(kong_id))
        except ValueError:
            return False
        return result is not None

    def on_publish(self, client, obj):
        try:
            api_struct = client.apis.add_or_update(
                api_id=obj.kong_id, upstream_url=obj.upstream_url, name=obj.name, inbound_dns=obj.inbound_dns,
                path=obj.path, strip_path=obj.strip_path)
        except ConflictError:
            api_struct = client.apis.update(
                name_or_id=(obj.name or obj.inbound_dns), upstream_url=obj.upstream_url, name=obj.name,
                inbound_dns=obj.inbound_dns, path=obj.path, strip_path=obj.strip_path)

        name = api_struct['name']

        if obj.name != name:
            obj.name = name
            self.get_proxy_class().objects.filter(id=obj.id).update(name=obj.name)

        return api_struct['id']

    def on_withdraw_by_id(self, client, kong_id, parent_kong_id=None):
        client.apis.delete(str(kong_id))

class PluginConfigurationSyncEngine(KongProxySyncEngine):
    def get_proxy_class(self):
        return PluginConfigurationReference

    def on_retrieve_all(self, client):
        apis = list(client.apis.iterate())
        for api_struct in apis:
            api_kong_id = api_struct.get('id', None)
            assert api_kong_id is not None

            plugin_configurations = client.apis.plugins(api_kong_id).list(size=100).get('data', None)
            assert plugin_configurations is not None
            for plugin_configuration_struct in plugin_configurations:
                yield plugin_configuration_struct

    def is_published(self, client, kong_id, parent_kong_id=None):
        try:
            result = client.apis.plugins(str(parent_kong_id)).retrieve(str(kong_id))
        except ValueError:
            return False
        return result is not None

    def get_parent_object(self, obj):
        return obj.api

    def get_parent_key(self):
        return 'api_id'

    def on_publish(self, client, obj):
        api_kong_id = obj.api.kong_id
        consumer_kong_id = obj.consumer.kong_id if obj.consumer is not None else None

        try:
            plugin_configuration_struct = client.apis.plugins(str(api_kong_id)).create_or_update(
                plugin_configuration_id=obj.kong_id, plugin_name=Plugins.label(obj.plugin), enabled=obj.enabled,
                consumer_id=consumer_kong_id, **obj.config)
        except ConflictError:
            plugin_configuration_struct = client.apis.plugins(str(api_kong_id)).update(
                plugin_id=obj.name, enabled=obj.enabled, consumer_id=consumer_kong_id, **obj.config)

        config = plugin_configuration_struct['config']

        if obj.config != config:
            obj.config = config
            self.get_proxy_class().objects.filter(id=obj.id).update(config=obj.config)

        return plugin_configuration_struct['id']

    def on_withdraw_by_id(self, client, kong_id, parent_kong_id=None):
        assert kong_id is not None
        assert parent_kong_id is not None

        client.apis.plugins(parent_kong_id).delete(kong_id)
<commit_msg>Fixed syncing of plugins<commit_after># -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function
from kong.exceptions import ConflictError
from kong_admin.models import APIReference, PluginConfigurationReference
from kong_admin.enums import Plugins

from .base import KongProxySyncEngine

class APISyncEngine(KongProxySyncEngine):
    def plugins(self):
        return PluginConfigurationSyncEngine()

    def get_proxy_class(self):
        return APIReference

    def on_retrieve_all(self, client):
        apis = list(client.apis.iterate())
        for api_struct in apis:
            yield api_struct

    def is_published(self, client, kong_id, parent_kong_id=None):
        try:
            result = client.apis.retrieve(str(kong_id))
        except ValueError:
            return False
        return result is not None

    def on_publish(self, client, obj):
        try:
            api_struct = client.apis.add_or_update(
                api_id=obj.kong_id, upstream_url=obj.upstream_url, name=obj.name, inbound_dns=obj.inbound_dns,
                path=obj.path, strip_path=obj.strip_path)
        except ConflictError:
            api_struct = client.apis.update(
                name_or_id=(obj.name or obj.inbound_dns), upstream_url=obj.upstream_url, name=obj.name,
                inbound_dns=obj.inbound_dns, path=obj.path, strip_path=obj.strip_path)

        name = api_struct['name']

        if obj.name != name:
            obj.name = name
            self.get_proxy_class().objects.filter(id=obj.id).update(name=obj.name)

        return api_struct['id']

    def on_withdraw_by_id(self, client, kong_id, parent_kong_id=None):
        client.apis.delete(str(kong_id))

    def after_publish(self, client, obj):
        self.plugins().synchronize(client, PluginConfigurationReference.objects.filter(api=obj), delete=True)
        super(APISyncEngine, self).after_publish(client, obj)

    def before_withdraw(self, client, obj):
        for plugin in PluginConfigurationReference.objects.filter(api=obj):
            self.plugins().withdraw(client, plugin)
        return super(APISyncEngine, self).before_withdraw(client, obj)

class PluginConfigurationSyncEngine(KongProxySyncEngine):
    def get_proxy_class(self):
        return PluginConfigurationReference

    def on_retrieve_all(self, client):
        apis = list(client.apis.iterate())
        for api_struct in apis:
            api_kong_id = api_struct.get('id', None)
            assert api_kong_id is not None

            plugin_configurations = client.apis.plugins(api_kong_id).list(size=100).get('data', None)
            assert plugin_configurations is not None
            for plugin_configuration_struct in plugin_configurations:
                yield plugin_configuration_struct

    def is_published(self, client, kong_id, parent_kong_id=None):
        try:
            result = client.apis.plugins(str(parent_kong_id)).retrieve(str(kong_id))
        except ValueError:
            return False
        return result is not None

    def get_parent_object(self, obj):
        return obj.api

    def get_parent_key(self):
        return 'api_id'

    def on_publish(self, client, obj):
        api_kong_id = obj.api.kong_id
        consumer_kong_id = obj.consumer.kong_id if obj.consumer is not None else None

        try:
            plugin_configuration_struct = client.apis.plugins(str(api_kong_id)).create_or_update(
                plugin_configuration_id=obj.kong_id, plugin_name=Plugins.label(obj.plugin), enabled=obj.enabled,
                consumer_id=consumer_kong_id, **obj.config)
        except ConflictError:
            plugin_configuration_struct = client.apis.plugins(str(api_kong_id)).update(
                plugin_id=obj.name, enabled=obj.enabled, consumer_id=consumer_kong_id, **obj.config)

        config = plugin_configuration_struct['config']

        if obj.config != config:
            obj.config = config
            self.get_proxy_class().objects.filter(id=obj.id).update(config=obj.config)

        return plugin_configuration_struct['id']

    def on_withdraw_by_id(self, client, kong_id, parent_kong_id=None):
        assert kong_id is not None
        assert parent_kong_id is not None

        client.apis.plugins(parent_kong_id).delete(kong_id)
<|endoftext|>