<commit_before># encoding: UTF-8
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import re
import sys
import types

import pytest
from _pytest.config import get_config
from _pytest.config import PytestPluginManager
from _pytest.main import EXIT_NOTESTSCOLLECTED
from _pytest.main import Session

@pytest.fixture
def pytestpm():
    return PytestPluginManager()

class TestPytestPluginInteractions(object):
    def test_addhooks_conftestplugin(self, testdir):
        testdir.makepyfile(
            newhooks="""
            def pytest_myhook(xyz):
                "new hook"
        """
        )
        conf = testdir.makeconftest(
            """
            import newhooks
            def pytest_addhooks(pluginmanager):
                pluginmanager.addhooks(newhooks)
            def pytest_myhook(xyz):
                return xyz + 1
        """
        )
        config = get_config()
        pm = config.pluginmanager
        pm.hook.pytest_addhooks.call_historic(
            kwargs=dict(pluginmanager=config.pluginmanager)
        )
        config.pluginmanager._importconftest(conf)
        # print(config.pluginmanager.get_plugins())
        res = config.hook.pytest_myhook(xyz=10)
        assert res == [11]

    def test_addhooks_nohooks(self, testdir):
        testdir.makeconftest(
            """
            import sys
            def pytest_addhooks(pluginmanager):
                pluginmanager.addhooks(sys)
        """
        )
        res = testdir.runpytest()
        assert res.ret != 0
        res.stderr.fnmatch_lines(["*did not find*sys*"])

    def test_namespace_early_from_import(self, testdir):
        p = testdir.makepyfile(
            """
            from pytest import Item
            from pytest import Item as Item2
            assert Item is Item2
        """
        )
        result = testdir.runpython(p)
        assert result.ret == 0

    @pytest.mark.filterwarnings("ignore:pytest_namespace is deprecated")
    def test_do_ext_namespace(self, testdir):
        testdir.makeconftest(
            """
            def pytest_namespace():
                return {'hello': 'world'}
        """
        )
        p = testdir.makepyfile(
            """
            from pytest import hello
            import pytest
            def test_hello():
                assert hello == "world"
                assert 'hello' in pytest.__all__
        """
        )
        reprec = testdir.inline_run(p)
        reprec.assertoutcome(passed=1)

    def test_do_option_postinitialize(self, testdir):
        config = testdir.parseconfigure()
        assert not hasattr(config.option, "test123")
        p = testdir.makepyfile(
            """
            def pytest_addoption(parser):
                parser.addoption('--test123', action="store_true",
                    default=True)
        """
        )
        config.pluginmanager._importconftest(p)
        assert config.option.test123

    def test_configure(self, testdir):
        config = testdir.parseconfig()
        values = []

        class A(object):
            def pytest_configure(self, config):
                values.append(self)

        config.pluginmanager.register(A())
        assert len(values) == 0
        config._do_configure()
        assert len(values) == 1
        config.pluginmanager.register(A())  # leads to a configured() plugin
        assert len(values) == 2
        assert values[0] != values[1]

        config._ensure_unconfigure()
        config.pluginmanager.register(A())
        assert len(values) == 2

    def test_hook_tracing(self):
        pytestpm = get_config().pluginmanager  # fully initialized with plugins
        saveindent = []

        class api1(object):
            def pytest_plugin_registered(self):
                saveindent.append(pytestpm.trace.root.indent)

        class api2(object):
            def pytest_plugin_registered(self):
                saveindent.append(pytestpm.trace.root.indent)
                raise ValueError()

        values = []
        pytestpm.trace.root.setwriter(values.append)
        undo = pytestpm.enable_tracing()
        try:
            indent = pytestpm.trace.root.indent
            p = api1()
            pytestpm.register(p)
            assert pytestpm.trace.root.indent == indent
            assert len(values) >= 2
            assert "pytest_plugin_registered" in values[0]
            assert "finish" in values[1]

            values[:] = []
            with pytest.raises(ValueError):
                pytestpm.register(api2())
            assert pytestpm.trace.root.indent == indent
            assert saveindent[0] > indent
        finally:
            undo()

    def test_hook_proxy(self, testdir):
        """Test the gethookproxy function(#2016)"""
        config = testdir.parseconfig()
        session = Session(config)
        testdir.makepyfile(**{"tests/conftest.py": "", "tests/subdir/conftest.py": ""})

        conftest1 = testdir.tmpdir.join("tests/conftest.py")
        conftest2 = testdir.tmpdir.join("tests/subdir/conftest.py")

        config.pluginmanager._importconftest(conftest1)
        ihook_a = session.gethookproxy(testdir.tmpdir.join("tests"))
        assert ihook_a is not None
        config.pluginmanager._importconftest(conftest2)
        ihook_b = session.gethookproxy(testdir.tmpdir.join("tests"))
        assert ihook_a is not ihook_b

    def test_warn_on_deprecated_addhooks(self, pytestpm):
        warnings = []

        class get_warnings(object):
            def pytest_logwarning(self, code, fslocation, message, nodeid):
                warnings.append(message)

        class Plugin(object):
            def pytest_testhook():
                pass

        pytestpm.register(get_warnings())
        before = list(warnings)
        pytestpm.addhooks(Plugin())
        assert len(warnings) == len(before) + 1
        assert "deprecated" in warnings[-1]

def test_namespace_has_default_and_env_plugins(testdir):
    p = testdir.makepyfile(
        """
        import pytest
        pytest.mark
    """
    )
    result = testdir.runpython(p)
    assert result.ret == 0

def test_default_markers(testdir):
    result = testdir.runpytest("--markers")
    result.stdout.fnmatch_lines(["*tryfirst*first*", "*trylast*last*"])

def test_importplugin_error_message(testdir, pytestpm):
    """Don't hide import errors when importing plugins and provide
    an easy to debug message.

    See #375 and #1998.
    """
    testdir.syspathinsert(testdir.tmpdir)
    testdir.makepyfile(
        qwe="""
        # encoding: UTF-8
        def test_traceback():
            raise ImportError(u'Not possible to import: ☺')
        test_traceback()
    """
    )
    with pytest.raises(ImportError) as excinfo:
        pytestpm.import_plugin("qwe")

    expected_message = '.*Error importing plugin "qwe": Not possible to import: .'
    expected_traceback = ".*in test_traceback"
    assert re.match(expected_message, str(excinfo.value))
    assert re.match(expected_traceback, str(excinfo.traceback[-1]))

class TestPytestPluginManager(object):
    def test_register_imported_modules(self):
        pm = PytestPluginManager()
        mod = types.ModuleType("x.y.pytest_hello")
        pm.register(mod)
        assert pm.is_registered(mod)
        values = pm.get_plugins()
        assert mod in values
        pytest.raises(ValueError, "pm.register(mod)")
        pytest.raises(ValueError, lambda: pm.register(mod))
        # assert not pm.is_registered(mod2)
        assert pm.get_plugins() == values

    def test_canonical_import(self, monkeypatch):
        mod = types.ModuleType("pytest_xyz")
        monkeypatch.setitem(sys.modules, "pytest_xyz", mod)
        pm = PytestPluginManager()
        pm.import_plugin("pytest_xyz")
        assert pm.get_plugin("pytest_xyz") == mod
        assert pm.is_registered(mod)

    def test_consider_module(self, testdir, pytestpm):
        testdir.syspathinsert()
        testdir.makepyfile(pytest_p1="#")
        testdir.makepyfile(pytest_p2="#")
        mod = types.ModuleType("temp")
        mod.pytest_plugins = ["pytest_p1", "pytest_p2"]
        pytestpm.consider_module(mod)
        assert pytestpm.get_plugin("pytest_p1").__name__ == "pytest_p1"
        assert pytestpm.get_plugin("pytest_p2").__name__ == "pytest_p2"

    def test_consider_module_import_module(self, testdir):
        pytestpm = get_config().pluginmanager
        mod = types.ModuleType("x")
        mod.pytest_plugins = "pytest_a"
        aplugin = testdir.makepyfile(pytest_a="#")
        reprec = testdir.make_hook_recorder(pytestpm)
        testdir.syspathinsert(aplugin.dirpath())
        pytestpm.consider_module(mod)
        call = reprec.getcall(pytestpm.hook.pytest_plugin_registered.name)
        assert call.plugin.__name__ == "pytest_a"

        # check that it is not registered twice
        pytestpm.consider_module(mod)
        values = reprec.getcalls("pytest_plugin_registered")
        assert len(values) == 1

    def test_consider_env_fails_to_import(self, monkeypatch, pytestpm):
        monkeypatch.setenv("PYTEST_PLUGINS", "nonexisting", prepend=",")
        with pytest.raises(ImportError):
            pytestpm.consider_env()

    def test_plugin_skip(self, testdir, monkeypatch):
        p = testdir.makepyfile(
            skipping1="""
            import pytest
            pytest.skip("hello")
        """
        )
        p.copy(p.dirpath("skipping2.py"))
        monkeypatch.setenv("PYTEST_PLUGINS", "skipping2")
        result = testdir.runpytest("-rw", "-p", "skipping1", syspathinsert=True)
        assert result.ret == EXIT_NOTESTSCOLLECTED
        result.stdout.fnmatch_lines(
            ["*skipped plugin*skipping1*hello*", "*skipped plugin*skipping2*hello*"]
        )

    def test_consider_env_plugin_instantiation(self, testdir, monkeypatch, pytestpm):
        testdir.syspathinsert()
        testdir.makepyfile(xy123="#")
        monkeypatch.setitem(os.environ, "PYTEST_PLUGINS", "xy123")
        l1 = len(pytestpm.get_plugins())
        pytestpm.consider_env()
        l2 = len(pytestpm.get_plugins())
        assert l2 == l1 + 1
        assert pytestpm.get_plugin("xy123")
        pytestpm.consider_env()
        l3 = len(pytestpm.get_plugins())
        assert l2 == l3

    def test_pluginmanager_ENV_startup(self, testdir, monkeypatch):
        testdir.makepyfile(pytest_x500="#")
        p = testdir.makepyfile(
            """
            import pytest
            def test_hello(pytestconfig):
                plugin = pytestconfig.pluginmanager.get_plugin('pytest_x500')
                assert plugin is not None
        """
        )
        monkeypatch.setenv("PYTEST_PLUGINS", "pytest_x500", prepend=",")
        result = testdir.runpytest(p, syspathinsert=True)
        assert result.ret == 0
        result.stdout.fnmatch_lines(["*1 passed*"])

    def test_import_plugin_importname(self, testdir, pytestpm):
        pytest.raises(ImportError, 'pytestpm.import_plugin("qweqwex.y")')
        pytest.raises(ImportError, 'pytestpm.import_plugin("pytest_qweqwx.y")')

        testdir.syspathinsert()
        pluginname = "pytest_hello"
        testdir.makepyfile(**{pluginname: ""})
        pytestpm.import_plugin("pytest_hello")
        len1 = len(pytestpm.get_plugins())
        pytestpm.import_plugin("pytest_hello")
        len2 = len(pytestpm.get_plugins())
        assert len1 == len2
        plugin1 = pytestpm.get_plugin("pytest_hello")
        assert plugin1.__name__.endswith("pytest_hello")
        plugin2 = pytestpm.get_plugin("pytest_hello")
        assert plugin2 is plugin1

    def test_import_plugin_dotted_name(self, testdir, pytestpm):
        pytest.raises(ImportError, 'pytestpm.import_plugin("qweqwex.y")')
        pytest.raises(ImportError, 'pytestpm.import_plugin("pytest_qweqwex.y")')

        testdir.syspathinsert()
        testdir.mkpydir("pkg").join("plug.py").write("x=3")
        pluginname = "pkg.plug"
        pytestpm.import_plugin(pluginname)
        mod = pytestpm.get_plugin("pkg.plug")
        assert mod.x == 3

    def test_consider_conftest_deps(self, testdir, pytestpm):
        mod = testdir.makepyfile("pytest_plugins='xyz'").pyimport()
        with pytest.raises(ImportError):
            pytestpm.consider_conftest(mod)

class TestPytestPluginManagerBootstrapming(object):
    def test_preparse_args(self, pytestpm):
        pytest.raises(
            ImportError, lambda: pytestpm.consider_preparse(["xyz", "-p", "hello123"])
        )

    def test_plugin_prevent_register(self, pytestpm):
        pytestpm.consider_preparse(["xyz", "-p", "no:abc"])
        l1 = pytestpm.get_plugins()
        pytestpm.register(42, name="abc")
        l2 = pytestpm.get_plugins()
        assert len(l2) == len(l1)
        assert 42 not in l2

    def test_plugin_prevent_register_unregistered_alredy_registered(self, pytestpm):
        pytestpm.register(42, name="abc")
        l1 = pytestpm.get_plugins()
        assert 42 in l1
        pytestpm.consider_preparse(["xyz", "-p", "no:abc"])
        l2 = pytestpm.get_plugins()
        assert 42 not in l2
<commit_msg>Add test to branch<commit_after># encoding: UTF-8
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import re
import sys
import types

import pytest
from _pytest.config import get_config
from _pytest.config import PytestPluginManager
from _pytest.main import EXIT_NOTESTSCOLLECTED
from _pytest.main import Session

@pytest.fixture
def pytestpm():
    return PytestPluginManager()

class TestPytestPluginInteractions(object):
    def test_addhooks_conftestplugin(self, testdir):
        testdir.makepyfile(
            newhooks="""
            def pytest_myhook(xyz):
                "new hook"
        """
        )
        conf = testdir.makeconftest(
            """
            import newhooks
            def pytest_addhooks(pluginmanager):
                pluginmanager.addhooks(newhooks)
            def pytest_myhook(xyz):
                return xyz + 1
        """
        )
        config = get_config()
        pm = config.pluginmanager
        pm.hook.pytest_addhooks.call_historic(
            kwargs=dict(pluginmanager=config.pluginmanager)
        )
        config.pluginmanager._importconftest(conf)
        # print(config.pluginmanager.get_plugins())
        res = config.hook.pytest_myhook(xyz=10)
        assert res == [11]

    def test_addhooks_nohooks(self, testdir):
        testdir.makeconftest(
            """
            import sys
            def pytest_addhooks(pluginmanager):
                pluginmanager.addhooks(sys)
        """
        )
        res = testdir.runpytest()
        assert res.ret != 0
        res.stderr.fnmatch_lines(["*did not find*sys*"])

    def test_namespace_early_from_import(self, testdir):
        p = testdir.makepyfile(
            """
            from pytest import Item
            from pytest import Item as Item2
            assert Item is Item2
        """
        )
        result = testdir.runpython(p)
        assert result.ret == 0

    @pytest.mark.filterwarnings("ignore:pytest_namespace is deprecated")
    def test_do_ext_namespace(self, testdir):
        testdir.makeconftest(
            """
            def pytest_namespace():
                return {'hello': 'world'}
        """
        )
        p = testdir.makepyfile(
            """
            from pytest import hello
            import pytest
            def test_hello():
                assert hello == "world"
                assert 'hello' in pytest.__all__
        """
        )
        reprec = testdir.inline_run(p)
        reprec.assertoutcome(passed=1)

    def test_do_option_postinitialize(self, testdir):
        config = testdir.parseconfigure()
        assert not hasattr(config.option, "test123")
        p = testdir.makepyfile(
            """
            def pytest_addoption(parser):
                parser.addoption('--test123', action="store_true",
                    default=True)
        """
        )
        config.pluginmanager._importconftest(p)
        assert config.option.test123

    def test_configure(self, testdir):
        config = testdir.parseconfig()
        values = []

        class A(object):
            def pytest_configure(self, config):
                values.append(self)

        config.pluginmanager.register(A())
        assert len(values) == 0
        config._do_configure()
        assert len(values) == 1
        config.pluginmanager.register(A())  # leads to a configured() plugin
        assert len(values) == 2
        assert values[0] != values[1]

        config._ensure_unconfigure()
        config.pluginmanager.register(A())
        assert len(values) == 2

    def test_hook_tracing(self):
        pytestpm = get_config().pluginmanager  # fully initialized with plugins
        saveindent = []

        class api1(object):
            def pytest_plugin_registered(self):
                saveindent.append(pytestpm.trace.root.indent)

        class api2(object):
            def pytest_plugin_registered(self):
                saveindent.append(pytestpm.trace.root.indent)
                raise ValueError()

        values = []
        pytestpm.trace.root.setwriter(values.append)
        undo = pytestpm.enable_tracing()
        try:
            indent = pytestpm.trace.root.indent
            p = api1()
            pytestpm.register(p)
            assert pytestpm.trace.root.indent == indent
            assert len(values) >= 2
            assert "pytest_plugin_registered" in values[0]
            assert "finish" in values[1]

            values[:] = []
            with pytest.raises(ValueError):
                pytestpm.register(api2())
            assert pytestpm.trace.root.indent == indent
            assert saveindent[0] > indent
        finally:
            undo()

    def test_hook_proxy(self, testdir):
        """Test the gethookproxy function(#2016)"""
        config = testdir.parseconfig()
        session = Session(config)
        testdir.makepyfile(**{"tests/conftest.py": "", "tests/subdir/conftest.py": ""})

        conftest1 = testdir.tmpdir.join("tests/conftest.py")
        conftest2 = testdir.tmpdir.join("tests/subdir/conftest.py")

        config.pluginmanager._importconftest(conftest1)
        ihook_a = session.gethookproxy(testdir.tmpdir.join("tests"))
        assert ihook_a is not None
        config.pluginmanager._importconftest(conftest2)
        ihook_b = session.gethookproxy(testdir.tmpdir.join("tests"))
        assert ihook_a is not ihook_b

    def test_warn_on_deprecated_addhooks(self, pytestpm):
        warnings = []

        class get_warnings(object):
            def pytest_logwarning(self, code, fslocation, message, nodeid):
                warnings.append(message)

        class Plugin(object):
            def pytest_testhook():
                pass

        pytestpm.register(get_warnings())
        before = list(warnings)
        pytestpm.addhooks(Plugin())
        assert len(warnings) == len(before) + 1
        assert "deprecated" in warnings[-1]

def test_namespace_has_default_and_env_plugins(testdir):
    p = testdir.makepyfile(
        """
        import pytest
        pytest.mark
    """
    )
    result = testdir.runpython(p)
    assert result.ret == 0

def test_default_markers(testdir):
    result = testdir.runpytest("--markers")
    result.stdout.fnmatch_lines(["*tryfirst*first*", "*trylast*last*"])

def test_importplugin_error_message(testdir, pytestpm):
    """Don't hide import errors when importing plugins and provide
    an easy to debug message.

    See #375 and #1998.
    """
    testdir.syspathinsert(testdir.tmpdir)
    testdir.makepyfile(
        qwe="""
        # encoding: UTF-8
        def test_traceback():
            raise ImportError(u'Not possible to import: ☺')
        test_traceback()
    """
    )
    with pytest.raises(ImportError) as excinfo:
        pytestpm.import_plugin("qwe")

    expected_message = '.*Error importing plugin "qwe": Not possible to import: .'
    expected_traceback = ".*in test_traceback"
    assert re.match(expected_message, str(excinfo.value))
    assert re.match(expected_traceback, str(excinfo.traceback[-1]))

class TestPytestPluginManager(object):
    def test_register_imported_modules(self):
        pm = PytestPluginManager()
        mod = types.ModuleType("x.y.pytest_hello")
        pm.register(mod)
        assert pm.is_registered(mod)
        values = pm.get_plugins()
        assert mod in values
        pytest.raises(ValueError, "pm.register(mod)")
        pytest.raises(ValueError, lambda: pm.register(mod))
        # assert not pm.is_registered(mod2)
        assert pm.get_plugins() == values

    def test_canonical_import(self, monkeypatch):
        mod = types.ModuleType("pytest_xyz")
        monkeypatch.setitem(sys.modules, "pytest_xyz", mod)
        pm = PytestPluginManager()
        pm.import_plugin("pytest_xyz")
        assert pm.get_plugin("pytest_xyz") == mod
        assert pm.is_registered(mod)

    def test_consider_module(self, testdir, pytestpm):
        testdir.syspathinsert()
        testdir.makepyfile(pytest_p1="#")
        testdir.makepyfile(pytest_p2="#")
        mod = types.ModuleType("temp")
        mod.pytest_plugins = ["pytest_p1", "pytest_p2"]
        pytestpm.consider_module(mod)
        assert pytestpm.get_plugin("pytest_p1").__name__ == "pytest_p1"
        assert pytestpm.get_plugin("pytest_p2").__name__ == "pytest_p2"

    def test_consider_module_import_module(self, testdir):
        pytestpm = get_config().pluginmanager
        mod = types.ModuleType("x")
        mod.pytest_plugins = "pytest_a"
        aplugin = testdir.makepyfile(pytest_a="#")
        reprec = testdir.make_hook_recorder(pytestpm)
        testdir.syspathinsert(aplugin.dirpath())
        pytestpm.consider_module(mod)
        call = reprec.getcall(pytestpm.hook.pytest_plugin_registered.name)
        assert call.plugin.__name__ == "pytest_a"

        # check that it is not registered twice
        pytestpm.consider_module(mod)
        values = reprec.getcalls("pytest_plugin_registered")
        assert len(values) == 1

    def test_consider_env_fails_to_import(self, monkeypatch, pytestpm):
        monkeypatch.setenv("PYTEST_PLUGINS", "nonexisting", prepend=",")
        with pytest.raises(ImportError):
            pytestpm.consider_env()

    def test_plugin_skip(self, testdir, monkeypatch):
        p = testdir.makepyfile(
            skipping1="""
            import pytest
            pytest.skip("hello")
        """
        )
        p.copy(p.dirpath("skipping2.py"))
        monkeypatch.setenv("PYTEST_PLUGINS", "skipping2")
        result = testdir.runpytest("-rw", "-p", "skipping1", syspathinsert=True)
        assert result.ret == EXIT_NOTESTSCOLLECTED
        result.stdout.fnmatch_lines(
            ["*skipped plugin*skipping1*hello*", "*skipped plugin*skipping2*hello*"]
        )

    def test_consider_env_plugin_instantiation(self, testdir, monkeypatch, pytestpm):
        testdir.syspathinsert()
        testdir.makepyfile(xy123="#")
        monkeypatch.setitem(os.environ, "PYTEST_PLUGINS", "xy123")
        l1 = len(pytestpm.get_plugins())
        pytestpm.consider_env()
        l2 = len(pytestpm.get_plugins())
        assert l2 == l1 + 1
        assert pytestpm.get_plugin("xy123")
        pytestpm.consider_env()
        l3 = len(pytestpm.get_plugins())
        assert l2 == l3

    def test_pluginmanager_ENV_startup(self, testdir, monkeypatch):
        testdir.makepyfile(pytest_x500="#")
        p = testdir.makepyfile(
            """
            import pytest
            def test_hello(pytestconfig):
                plugin = pytestconfig.pluginmanager.get_plugin('pytest_x500')
                assert plugin is not None
        """
        )
        monkeypatch.setenv("PYTEST_PLUGINS", "pytest_x500", prepend=",")
        result = testdir.runpytest(p, syspathinsert=True)
        assert result.ret == 0
        result.stdout.fnmatch_lines(["*1 passed*"])

    def test_import_plugin_importname(self, testdir, pytestpm):
        pytest.raises(ImportError, 'pytestpm.import_plugin("qweqwex.y")')
        pytest.raises(ImportError, 'pytestpm.import_plugin("pytest_qweqwx.y")')

        testdir.syspathinsert()
        pluginname = "pytest_hello"
        testdir.makepyfile(**{pluginname: ""})
        pytestpm.import_plugin("pytest_hello")
        len1 = len(pytestpm.get_plugins())
        pytestpm.import_plugin("pytest_hello")
        len2 = len(pytestpm.get_plugins())
        assert len1 == len2
        plugin1 = pytestpm.get_plugin("pytest_hello")
        assert plugin1.__name__.endswith("pytest_hello")
        plugin2 = pytestpm.get_plugin("pytest_hello")
        assert plugin2 is plugin1

    def test_import_plugin_dotted_name(self, testdir, pytestpm):
        pytest.raises(ImportError, 'pytestpm.import_plugin("qweqwex.y")')
        pytest.raises(ImportError, 'pytestpm.import_plugin("pytest_qweqwex.y")')

        testdir.syspathinsert()
        testdir.mkpydir("pkg").join("plug.py").write("x=3")
        pluginname = "pkg.plug"
        pytestpm.import_plugin(pluginname)
        mod = pytestpm.get_plugin("pkg.plug")
        assert mod.x == 3

    def test_consider_conftest_deps(self, testdir, pytestpm):
        mod = testdir.makepyfile("pytest_plugins='xyz'").pyimport()
        with pytest.raises(ImportError):
            pytestpm.consider_conftest(mod)

class TestPytestPluginManagerBootstrapming(object):
    def test_preparse_args(self, pytestpm):
        pytest.raises(
            ImportError, lambda: pytestpm.consider_preparse(["xyz", "-p", "hello123"])
        )

    def test_plugin_prevent_register(self, pytestpm):
        pytestpm.consider_preparse(["xyz", "-p", "no:abc"])
        l1 = pytestpm.get_plugins()
        pytestpm.register(42, name="abc")
        l2 = pytestpm.get_plugins()
        assert len(l2) == len(l1)
        assert 42 not in l2

    def test_plugin_prevent_register_unregistered_alredy_registered(self, pytestpm):
        pytestpm.register(42, name="abc")
        l1 = pytestpm.get_plugins()
        assert 42 in l1
        pytestpm.consider_preparse(["xyz", "-p", "no:abc"])
        l2 = pytestpm.get_plugins()
        assert 42 not in l2

    def test_plugin_prevent_register_stepwise_on_cacheprovider_unregister(self, pytestpm):
        """ From PR #4304 : The only way to unregister a module is documented at
        the end of https://docs.pytest.org/en/latest/plugins.html.

        When unregister cacheprovider, then unregister stepwise too
        """
        pytestpm.register(42, name="cacheprovider")
        pytestpm.register(43, name="stepwise")
        l1 = pytestpm.get_plugins()
        assert 42 in l1
        assert 43 in l1
        pytestpm.consider_preparse(["xyz", "-p", "no:cacheprovider"])
        l2 = pytestpm.get_plugins()
        assert 42 not in l2
        assert 43 not in l2

<|endoftext|>


<commit_before>"""
Some very beta tools for IRIS
"""

import sunpy.io
import sunpy.time
import sunpy.map

__all__ = ['SJI_to_cube']

def SJI_to_cube(filename, start=0, stop=None):
    """
    Read a SJI file and return a MapCube

    ..warning::
        This function is a very early beta and is not stable. Further work is
        on going to improve SunPy IRIS support.

    Parameters
    ----------
    filename: string
        File to read

    start:
        Temporal axis index to create MapCube from

    stop:
        Temporal index to stop MapCube at

    Returns
    -------

    iris_cube: sunpy.map.MapCube
        A map cube of the SJI sequence
    """

    hdus = sunpy.io.read_file(filename)
    #Get the time delta
    time_range = sunpy.time.TimeRange(hdus[0][1]['STARTOBS'], hdus[0][1]['ENDOBS'])
    splits = time_range.split(hdus[0][0].shape[0])

    if not stop:
        stop = len(splits)

    headers = [hdus[0][1]]*(stop-start)
    datas = hdus[0][0][start:stop]

    #Make the cube:
    iris_cube = sunpy.map.Map(zip(datas,headers),cube=True)
    #Set the date/time
    for i,m in enumerate(iris_cube):
        m.meta['DATE-OBS'] = splits[i].center().isoformat()

    return iris_cube<commit_msg>Change hdu[0] to hdu for optional indexing<commit_after>"""
Some very beta tools for IRIS
"""

import sunpy.io
import sunpy.time
import sunpy.map

__all__ = ['SJI_to_cube']

def SJI_to_cube(filename, start=0, stop=None, hdu=0):
    """
    Read a SJI file and return a MapCube

    ..warning::
        This function is a very early beta and is not stable. Further work is
        on going to improve SunPy IRIS support.

    Parameters
    ----------
    filename: string
        File to read

    start:
        Temporal axis index to create MapCube from

    stop:
        Temporal index to stop MapCube at

    hdu:
        Choose hdu index

    Returns
    -------

    iris_cube: sunpy.map.MapCube
        A map cube of the SJI sequence
    """

    hdus = sunpy.io.read_file(filename)
    #Get the time delta
    time_range = sunpy.time.TimeRange(hdus[hdu][1]['STARTOBS'], hdus[hdu][1]['ENDOBS'])
    splits = time_range.split(hdus[hdu][0].shape[0])

    if not stop:
        stop = len(splits)

    headers = [hdus[hdu][1]]*(stop-start)
    datas = hdus[hdu][0][start:stop]

    #Make the cube:
    iris_cube = sunpy.map.Map(zip(datas,headers),cube=True)
    #Set the date/time
    for i,m in enumerate(iris_cube):
        m.meta['DATE-OBS'] = splits[i].center().isoformat()

    return iris_cube
<|endoftext|>


<commit_before>from django.conf import settings

DEFAULT_PROCESS_TYPE = 'TEXT/RAW'

# The models/fields to process
MODULES = getattr(settings, 'SUPERTAGGING_MODULES', {})
USER_DIR = getattr(settings, 'SUPERTAGGING_CALAIS_USER_DIRECTIVES', {})
PROCESSING_DIR = getattr(settings, 'SUPERTAGGING_CALAIS_PROCESSING_DIRECTIVES', {})
PROCESS_RELATIONS = getattr(settings, 'SUPERTAGGING_PROCESS_RELATIONS', False)
PROCESS_TOPICS = getattr(settings, 'SUPERTAGGING_PROCESS_TOPICS', False)

# If True, raise errors when errors occur
ST_DEBUG = getattr(settings, 'SUPERTAGGING_DEBUG', False)

# Tags (name) to exclude, this will exclude tags from being saved.
EXCLUSIONS = getattr(settings, 'SUPERTAGGING_TAG_TYPE_EXCLUSIONS', [])

# Tags will be saved, but not returned in the queries
QUERY_EXCLUSIONS = getattr(settings, 'SUPERTAGGING_TAG_TYPE_QUERY_EXCLUSIONS', [])

# When resolving related tags, resolve the name or keep the UID
RESOLVE_KEYS = getattr(settings, 'SUPERTAGGING_RESOLVE_PROPERTY_KEYS', True)

# Your Open-Calais API_KEY
API_KEY = getattr(settings, 'SUPERTAGGING_CALAIS_API_KEY', None)

# Auto process tags, (sets up post save and delete signals)
AUTO_PROCESS = getattr(settings, 'SUPERTAGGING_AUTO_PROCESS', False)

# Set the process to be enabled. This will allow enabling and disabling
# the processing of tagging while preserving AUTO_PROCESS
ENABLED = getattr(settings, 'SUPERTAGGING_ENABLED', True)

# Exclude certain instances of a tag to be rendered, ie 'his', 'her' etc
MARKUP_EXCLUDES = getattr(settings, 'SUPERTAGGING_MARKUP_EXCLUDES', [])

# Minimum relevance score needed when adding tags
MIN_RELEVANCE = getattr(settings, 'SUPERTAGGING_MIN_RELEVANCE', 0)<commit_msg>Fixed some comments<commit_after>from django.conf import settings

DEFAULT_PROCESS_TYPE = 'TEXT/RAW'

# The models/fields to process
MODULES = getattr(settings, 'SUPERTAGGING_MODULES', {})
USER_DIR = getattr(settings, 'SUPERTAGGING_CALAIS_USER_DIRECTIVES', {})
PROCESSING_DIR = getattr(settings, 'SUPERTAGGING_CALAIS_PROCESSING_DIRECTIVES', {})
PROCESS_RELATIONS = getattr(settings, 'SUPERTAGGING_PROCESS_RELATIONS', False)
PROCESS_TOPICS = getattr(settings, 'SUPERTAGGING_PROCESS_TOPICS', False)

# If True, raise errors when errors occur
ST_DEBUG = getattr(settings, 'SUPERTAGGING_DEBUG', False)

# Tags (type) to exclude, this will exclude tags from being saved.
EXCLUSIONS = getattr(settings, 'SUPERTAGGING_TAG_TYPE_EXCLUSIONS', [])

# Tags will be saved, but not returned in the queries * NOT IMPLEMENTED *
QUERY_EXCLUSIONS = getattr(settings, 'SUPERTAGGING_TAG_TYPE_QUERY_EXCLUSIONS', [])

# When resolving related tags, resolve the name or keep the UID
RESOLVE_KEYS = getattr(settings, 'SUPERTAGGING_RESOLVE_PROPERTY_KEYS', True)

# Your Open-Calais API_KEY
API_KEY = getattr(settings, 'SUPERTAGGING_CALAIS_API_KEY', None)

# Auto process tags, (sets up post save and delete signals)
AUTO_PROCESS = getattr(settings, 'SUPERTAGGING_AUTO_PROCESS', False)

# Set the process to be enabled. This will allow enabling and disabling
# the processing of tagging while preserving AUTO_PROCESS
ENABLED = getattr(settings, 'SUPERTAGGING_ENABLED', True)

# Exclude certain instances of a tag to be rendered, ie 'his', 'her' etc
MARKUP_EXCLUDES = getattr(settings, 'SUPERTAGGING_MARKUP_EXCLUDES', [])

# Minimum relevance score needed when adding tags
MIN_RELEVANCE = getattr(settings, 'SUPERTAGGING_MIN_RELEVANCE', 0)<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Check the prerequisites for iPhone development
#

import os, sys, subprocess, re, types
import poorjson, run, tempfile, codecs

template_dir = os.path.abspath(os.path.dirname(sys._getframe(0).f_code.co_filename))

def sdk_found(apiversion):
	if not os.path.exists('/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS%s.sdk' % apiversion):
		return False
	if not os.path.exists('/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator%s.sdk' % apiversion):
		return False
	return True

def get_sdks():
	found = []
	output = run.run(["xcodebuild","-showsdks"])
	#print output
	for line in output.split("\n"):
		if line[0:1] == '\t':
			line = line.strip()
			i = line.index('-sdk')
			type = line[0:i]
			cmd = line[i+5:]
			if cmd.find("iphoneos")==0:
				ver = cmd[8:]
				if ver[0]=='3':
					found.append(ver)
	return found

def check_iphone3():
	try:
		found = get_sdks()
		if len(found) > 0:
			sys.stdout.write('{"success":true, "sdks":[')
			c = 0
			for name in found:
				sys.stdout.write(('"%s"' % name))
				if c+1 < len(found):
					sys.stdout.write(",")
				c+=1
			sys.stdout.write(']}')
			print
			sys.exit(0)
		else:
			print '{"success":false,"message":"Missing iPhone SDK which supports either 2.2.1 or 3.0"}'
			sys.exit(2)

	except Exception, e:
		print '{"success":false,"message":"Missing Apple XCode"}'
		sys.exit(1)

def check_itunes_version(props):
	ver = run.run(['osascript',os.path.join(template_dir,'itunes_ver.scpt')]).strip()
	props['itunes_version']=ver
	props['itunes']=False
	props['itunes_message']=None
	if ver:
		major = int(ver[0])
		minor = int(ver[2])
		if (major == 8 and minor >= 2) or major > 8:
			props['itunes']=True
			return
	props['itunes_message'] = 'iTunes 8.2 or later required. You have %s' % ver

def check_for_wwdr(props,line):
	if len(re.findall('Apple Worldwide Developer Relations Certification Authority',line)) > 0:
		props['wwdr']=True
		props['wwdr_message']=None

def check_for_iphone_dev(props,line):
	m = re.search(r'\"iPhone Developer: (.*)\"',line)
	if not m == None:
		name = m.group(1).strip()
		name = name.decode('string_escape').decode('utf-8')
		props['iphone_dev']=True
		if props.has_key('iphone_dev_name'):
			try:
				props['iphone_dev_name'].index(name)
			except:
				props['iphone_dev_name'].append(name)
		else:
			props['iphone_dev_name']=[name]
		props['iphone_dev_message']=None

def check_for_iphone_dist(props,line):
	m = re.search(r'\"iPhone Distribution: (.*)\"',line)
	if not m == None:
		name = m.group(1).strip()
		name = name.decode('string_escape').decode('utf-8')
		props['iphone_dist']=True
		if props.has_key('iphone_dist_name'):
			try:
				props['iphone_dist_name'].index(name)
			except:
				props['iphone_dist_name'].append(name)
		else:
			props['iphone_dist_name']=[name]
		props['iphone_dist_message']=None

def check_certs(props):
	props['wwdr']=False
	props['wwdr_message'] = "Missing the Apple WWDR intermediate certificate."
	props['iphone_dist']=False
	props['iphone_dev']=False
	props['iphone_dist_message'] = 'Missing iPhone Distribution Certificate'
	props['iphone_dev_message'] = 'Missing iPhone Developer Certificate'
	output = run.run(['security','dump-keychain'])
	for i in output.split('\n'):
		check_for_wwdr(props,i)
		check_for_iphone_dev(props,i)
		check_for_iphone_dist(props,i)

def check_for_package():
	props = {}
	check_itunes_version(props)
	check_certs(props)
	props['sdks']=get_sdks()
	print poorjson.PoorJSON().dump(props)

def main(args):
	if len(args)!=2:
		print "Usage: %s <project|package>" % os.path.basename(args[0])
		sys.exit(1)

	if args[1] == 'project':
		check_iphone3()
	else:
		check_for_package()

	sys.exit(0)

if __name__ == "__main__":
    main(sys.argv)

<commit_msg>fix for distribution/dev certificate that has space in name<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Check the prerequisites for iPhone development
#

import os, sys, subprocess, re, types
import poorjson, run, tempfile, codecs

template_dir = os.path.abspath(os.path.dirname(sys._getframe(0).f_code.co_filename))

def sdk_found(apiversion):
	if not os.path.exists('/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS%s.sdk' % apiversion):
		return False
	if not os.path.exists('/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator%s.sdk' % apiversion):
		return False
	return True

def get_sdks():
	found = []
	output = run.run(["xcodebuild","-showsdks"])
	#print output
	for line in output.split("\n"):
		if line[0:1] == '\t':
			line = line.strip()
			i = line.index('-sdk')
			type = line[0:i]
			cmd = line[i+5:]
			if cmd.find("iphoneos")==0:
				ver = cmd[8:]
				if ver[0]=='3':
					found.append(ver)
	return found

def check_iphone3():
	try:
		found = get_sdks()
		if len(found) > 0:
			sys.stdout.write('{"success":true, "sdks":[')
			c = 0
			for name in found:
				sys.stdout.write(('"%s"' % name))
				if c+1 < len(found):
					sys.stdout.write(",")
				c+=1
			sys.stdout.write(']}')
			print
			sys.exit(0)
		else:
			print '{"success":false,"message":"Missing iPhone SDK which supports either 2.2.1 or 3.0"}'
			sys.exit(2)

	except Exception, e:
		print '{"success":false,"message":"Missing Apple XCode"}'
		sys.exit(1)

def check_itunes_version(props):
	ver = run.run(['osascript',os.path.join(template_dir,'itunes_ver.scpt')]).strip()
	props['itunes_version']=ver
	props['itunes']=False
	props['itunes_message']=None
	if ver:
		major = int(ver[0])
		minor = int(ver[2])
		if (major == 8 and minor >= 2) or major > 8:
			props['itunes']=True
			return
	props['itunes_message'] = 'iTunes 8.2 or later required. You have %s' % ver

def check_for_wwdr(props,line):
	if len(re.findall('Apple Worldwide Developer Relations Certification Authority',line)) > 0:
		props['wwdr']=True
		props['wwdr_message']=None

def check_for_iphone_dev(props,line):
	if props.has_key('iphone_dev') and props['iphone_dev']==True: return
	m = re.search(r'\"iPhone Developer: (.*)\"',line)
	if not m == None:
		name = m.group(1).strip()
		name = name.decode('string_escape').decode('utf-8')
		props['iphone_dev']=True
		if props.has_key('iphone_dev_name'):
			try:
				props['iphone_dev_name'].index(name)
			except:
				props['iphone_dev_name'].append(name)
		else:
			props['iphone_dev_name']=[name]
		props['iphone_dev_message']=None

def check_for_iphone_dist(props,line):
	if props.has_key('iphone_dist') and props['iphone_dist']==True: return
	m = re.search(r'\"iPhone Distribution: (.*)\"',line)
	if not m == None:
		name = m.group(1).strip()
		name = name.decode('string_escape').decode('utf-8')
		props['iphone_dist']=True
		if props.has_key('iphone_dist_name'):
			try:
				props['iphone_dist_name'].index(name)
			except:
				props['iphone_dist_name'].append(name)
		else:
			props['iphone_dist_name']=[name]
		props['iphone_dist_message']=None

def check_certs(props):
	props['wwdr']=False
	props['wwdr_message'] = "Missing the Apple WWDR intermediate certificate."
	props['iphone_dist']=False
	props['iphone_dev']=False
	props['iphone_dist_message'] = 'Missing iPhone Distribution Certificate'
	props['iphone_dev_message'] = 'Missing iPhone Developer Certificate'
	output = run.run(['security','dump-keychain'])
	for i in output.split('\n'):
		check_for_wwdr(props,i)
		check_for_iphone_dev(props,i)
		check_for_iphone_dist(props,i)

def check_for_package():
	props = {}
	check_itunes_version(props)
	check_certs(props)
	props['sdks']=get_sdks()
	print poorjson.PoorJSON().dump(props)

def main(args):
	if len(args)!=2:
		print "Usage: %s <project|package>" % os.path.basename(args[0])
		sys.exit(1)

	if args[1] == 'project':
		check_iphone3()
	else:
		check_for_package()

	sys.exit(0)

if __name__ == "__main__":
    main(sys.argv)

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
#
#  This file is part of django-oembed-works.
#
#  DESCRIPTION_DESCRIPTION_DESCRIPTION
#
#  Development Web Site:
#    - http://www.codetrax.org/projects/django-oembed-works
#  Public Source Code Repository:
#    - https://source.codetrax.org/hgroot/django-oembed-works
#
#  Copyright 2010 George Notaras <gnot [at] g-loaded.eu>
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
#

import re
try:
    import hashlib
    md5 = hashlib.md5
except ImportError:
    import md5  # Python 2.4 fallback
    md5 = md5.new

from django import template
from django.template.loader import render_to_string

from oembed_works import oembed
from oembed_works.exceptions import OEmbedSizeError
from oembed_works.utils import get_dimensions_from_string
from oembed_works import settings

register = template.Library()

class OEmbedNode(template.Node):

    def __init__(self, nodelist, width, height):
        self.nodelist = nodelist
        self.width = width
        self.height = height
        self.consumer = self._get_oembed_consumer()

    def render(self, context):
        output = self.nodelist.render(context)
        # Process output
        output = self._oembed_processor(output, self.width, self.height)
        return output

    def _oembed_processor(self, output, width, height):
        for format, endpoint, regex_list in settings.OEMBED_PROVIDERS.values():
            for regex in regex_list:
                for m in re.finditer(regex, output):
                    #print 'MATCH: %02d-%02d: %s' % (m.start(), m.end(), m.group(0))
                    oembed_html = self._get_oembed_html(self.consumer, m.group(0), width, height)
                    pattern = re.escape(m.group(0)) # The found link is used as the pattern
                    output = re.sub(pattern, oembed_html, output)
        return output

    def _get_oembed_consumer(self):
        consumer = oembed.OEmbedConsumer()
        for format, endpoint_api, regex_list in settings.OEMBED_PROVIDERS.values():
            endpoint = oembed.OEmbedEndpoint(endpoint_api, regex_list)
            consumer.addEndpoint(endpoint)
        return consumer

    def _get_oembed_html(self, consumer, link, width, height):
        link_hash = md5(link).hexdigest()
        response = consumer.embed(link)
        info_dict = {'response': self._set_oembed_dimensions(response, width, height)}
        if response['type'] == 'photo':
            return render_to_string('oembed_works/photo.html', info_dict)
        elif response['type'] == 'video':
            return render_to_string('oembed_works/video.html', info_dict)
        elif response['type'] == 'link':
            return render_to_string('oembed_works/link.html', info_dict)
        elif response['type'] == 'rich':
            return render_to_string('oembed_works/rich.html', info_dict)
        else:
            return link

    def _set_oembed_dimensions(self, response, width, height):
        if width is not None:
            response['width'] = width
            if response.has_key('html'):
                response['html'] = re.sub('width="\d+"', 'width="%d"' % width, response['html'])
        if height is not None:
            response['height'] = height
            if response.has_key('html'):
                response['html'] = re.sub('height="\d+"', 'height="%d"' % height, response['html'])
        return response

def do_oembed(parser, token):
    """
    -
    {% oembed [WIDTHxHEIGHT] %}

    {% endoembed %}

    """
    # split_contents() knows not to split quoted strings.
    args = token.split_contents()
    width, height = None, None
    if len(args) not in (2, 3):
        raise template.TemplateSyntaxError('%s tag requires one or two arguments' % args[0])
    elif len(args) == 3:
        try:
            width, height = get_dimensions_from_string(args[1])
        except OEmbedSizeError:
            raise template.TemplateSyntaxError("second argument to %s tag must be a string of the format 'WIDTHxHEIGHT'" % args[0])

    nodelist = parser.parse(('endoembed',))
    parser.delete_first_token()
    return OEmbedNode(nodelist, width, height)

register.tag('oembed', do_oembed)

<commit_msg>Improved code to use stored responses if available<commit_after># -*- coding: utf-8 -*-
#
#  This file is part of django-oembed-works.
#
#  DESCRIPTION_DESCRIPTION_DESCRIPTION
#
#  Development Web Site:
#    - http://www.codetrax.org/projects/django-oembed-works
#  Public Source Code Repository:
#    - https://source.codetrax.org/hgroot/django-oembed-works
#
#  Copyright 2010 George Notaras <gnot [at] g-loaded.eu>
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
#

import re
try:
    import hashlib
    md5 = hashlib.md5
except ImportError:
    import md5  # Python 2.4 fallback
    md5 = md5.new

from django import template
from django.template.loader import render_to_string
from django.db.models.loading import cache

from oembed_works import oembed
from oembed_works.exceptions import OEmbedSizeError
from oembed_works.utils import get_dimensions_from_string
from oembed_works import settings

register = template.Library()

class OEmbedNode(template.Node):

    def __init__(self, nodelist, width, height):
        self.nodelist = nodelist
        self.width = width
        self.height = height
        self.consumer = self._get_oembed_consumer()

    def render(self, context):
        output = self.nodelist.render(context)
        # Process output
        output = self._oembed_processor(output, self.width, self.height)
        return output

    def _oembed_processor(self, output, width, height):
        for format, endpoint, regex_list in settings.OEMBED_PROVIDERS.values():
            for regex in regex_list:
                for m in re.finditer(regex, output):
                    #print 'MATCH: %02d-%02d: %s' % (m.start(), m.end(), m.group(0))
                    oembed_html = self._get_oembed_html(self.consumer, m.group(0), width, height)
                    pattern = re.escape(m.group(0)) # The found link is used as the pattern
                    output = re.sub(pattern, oembed_html, output)
        return output

    def _get_oembed_consumer(self):
        consumer = oembed.OEmbedConsumer()
        for format, endpoint_api, regex_list in settings.OEMBED_PROVIDERS.values():
            endpoint = oembed.OEmbedEndpoint(endpoint_api, regex_list)
            consumer.addEndpoint(endpoint)
        return consumer

    def _set_oembed_dimensions(self, response, width, height):
        if width is not None:
            response['width'] = width
            if response.has_key('html'):
                response['html'] = re.sub('width="\d+"', 'width="%d"' % width, response['html'])
        if height is not None:
            response['height'] = height
            if response.has_key('html'):
                response['html'] = re.sub('height="\d+"', 'height="%d"' % height, response['html'])
        return response

    def _get_oembed_html(self, consumer, link, width, height):
        # First try to get a response object from the cache
        response = self._get_from_cache(link)
        if response is None:
            # Use OEmbed consumer to get a response
            try:
                response = consumer.embed(link)
            except oembed.OEmbedError:
                return link
            else:
                # Also store the response to the cache
                self._store_to_cache(link, response)
        # Return HTML code with embeded object
        info_dict = {'response': self._set_oembed_dimensions(response, width, height)}
        if response['type'] == 'photo':
            return render_to_string('oembed_works/photo.html', info_dict)
        elif response['type'] == 'video':
            return render_to_string('oembed_works/video.html', info_dict)
        elif response['type'] == 'link':
            return render_to_string('oembed_works/link.html', info_dict)
        elif response['type'] == 'rich':
            return render_to_string('oembed_works/rich.html', info_dict)
        else:
            return link

    def _get_from_cache(self, link):
        StoredOEmbedResponse = cache.get_model('oembed_works', 'StoredOEmbedResponse')
        link_hash = md5(link).hexdigest()
        try:
            stored_response = StoredOEmbedResponse.objects.get(link_hash=link_hash)
        except StoredOEmbedResponse.DoesNotExist:
            return None
        else:
            return stored_response.get_response_object()

    def _store_to_cache(self, link, response):
        StoredOEmbedResponse = cache.get_model('oembed_works', 'StoredOEmbedResponse')
        link_hash = md5(link).hexdigest()
        response_data = pickle.dumps(response.getData())
        StoredOEmbedResponse.objects.get_or_create(
            link_hash=link_hash, response_data=response_data)

def do_oembed(parser, token):
    """
    -
    {% oembed [WIDTHxHEIGHT] %}

    {% endoembed %}

    """
    # split_contents() knows not to split quoted strings.
    args = token.split_contents()
    width, height = None, None
    if len(args) not in (2, 3):
        raise template.TemplateSyntaxError('%s tag requires one or two arguments' % args[0])
    elif len(args) == 3:
        try:
            width, height = get_dimensions_from_string(args[1])
        except OEmbedSizeError:
            raise template.TemplateSyntaxError("second argument to %s tag must be a string of the format 'WIDTHxHEIGHT'" % args[0])

    nodelist = parser.parse(('endoembed',))
    parser.delete_first_token()
    return OEmbedNode(nodelist, width, height)

register.tag('oembed', do_oembed)

<|endoftext|>


<commit_before># Licensed to the StackStorm, Inc ('StackStorm') 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.

from __future__ import absolute_import

import eventlet

from integration.orquesta import base

from st2common.constants import action as ac_const

class InquiryWiringTest(base.TestWorkflowExecution):

    def test_basic_inquiry(self):
        # Launch the workflow. The workflow will paused at the pending task.
        ex = self._execute_workflow('examples.orquesta-ask-basic')
        ex = self._wait_for_state(ex, ac_const.LIVEACTION_STATUS_PAUSED)

        # Respond to the inquiry.
        ac_exs = self._wait_for_task(ex, 'get_approval', ac_const.LIVEACTION_STATUS_PENDING)
        self.st2client.inquiries.respond(ac_exs[0].id, {'approved': True})

        # Wait for completion.
        ex = self._wait_for_state(ex, ac_const.LIVEACTION_STATUS_SUCCEEDED)

    def test_consecutive_inquiries(self):
        # Launch the workflow. The workflow will paused at the pending task.
        ex = self._execute_workflow('examples.orquesta-ask-consecutive')
        ex = self._wait_for_state(ex, ac_const.LIVEACTION_STATUS_PAUSED)

        # Respond to the first inquiry.
        t1_ac_exs = self._wait_for_task(ex, 'get_approval', ac_const.LIVEACTION_STATUS_PENDING)
        self.st2client.inquiries.respond(t1_ac_exs[0].id, {'approved': True})

        # Wait for the workflow to pause again.
        ex = self._wait_for_state(ex, ac_const.LIVEACTION_STATUS_PAUSED)

        # Respond to the second inquiry.
        t2_ac_exs = self._wait_for_task(ex, 'get_confirmation', ac_const.LIVEACTION_STATUS_PENDING)
        self.st2client.inquiries.respond(t2_ac_exs[0].id, {'approved': True})

        # Wait for completion.
        ex = self._wait_for_state(ex, ac_const.LIVEACTION_STATUS_SUCCEEDED)

    def test_parallel_inquiries(self):
        # Launch the workflow. The workflow will paused at the pending task.
        ex = self._execute_workflow('examples.orquesta-ask-parallel')
        ex = self._wait_for_state(ex, ac_const.LIVEACTION_STATUS_PAUSED)

        # Respond to the first inquiry.
        t1_ac_exs = self._wait_for_task(ex, 'ask_jack', ac_const.LIVEACTION_STATUS_PENDING)
        self.st2client.inquiries.respond(t1_ac_exs[0].id, {'approved': True})

        # Allow some time for the first inquiry to get processed.
        eventlet.sleep(1)

        # Respond to the second inquiry.
        t2_ac_exs = self._wait_for_task(ex, 'ask_jill', ac_const.LIVEACTION_STATUS_PENDING)
        self.st2client.inquiries.respond(t2_ac_exs[0].id, {'approved': True})

        # Wait for completion.
        ex = self._wait_for_state(ex, ac_const.LIVEACTION_STATUS_SUCCEEDED)

    def test_nested_inquiry(self):
        # Launch the workflow. The workflow will paused at the pending task.
        ex = self._execute_workflow('examples.orquesta-ask-nested')
        ex = self._wait_for_state(ex, ac_const.LIVEACTION_STATUS_PAUSED)

        # Get the action execution of the subworkflow
        ac_exs = self._wait_for_task(ex, 'get_approval', ac_const.LIVEACTION_STATUS_PAUSED)

        # Respond to the inquiry in the subworkflow.
        t2_t2_ac_exs = self._wait_for_task(
            ac_exs[0],
            'get_approval',
            ac_const.LIVEACTION_STATUS_PENDING
        )

        self.st2client.inquiries.respond(t2_t2_ac_exs[0].id, {'approved': True})

        # Wait for completion.
        ex = self._wait_for_state(ex, ac_const.LIVEACTION_STATUS_SUCCEEDED)
<commit_msg>Modify the parallel inquiry tests to minimize failure<commit_after># Licensed to the StackStorm, Inc ('StackStorm') 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.

from __future__ import absolute_import

import eventlet

from integration.orquesta import base

from st2common.constants import action as ac_const

class InquiryWiringTest(base.TestWorkflowExecution):

    def test_basic_inquiry(self):
        # Launch the workflow. The workflow will paused at the pending task.
        ex = self._execute_workflow('examples.orquesta-ask-basic')
        ex = self._wait_for_state(ex, ac_const.LIVEACTION_STATUS_PAUSED)

        # Respond to the inquiry.
        ac_exs = self._wait_for_task(ex, 'get_approval', ac_const.LIVEACTION_STATUS_PENDING)
        self.st2client.inquiries.respond(ac_exs[0].id, {'approved': True})

        # Wait for completion.
        ex = self._wait_for_state(ex, ac_const.LIVEACTION_STATUS_SUCCEEDED)

    def test_consecutive_inquiries(self):
        # Launch the workflow. The workflow will paused at the pending task.
        ex = self._execute_workflow('examples.orquesta-ask-consecutive')
        ex = self._wait_for_state(ex, ac_const.LIVEACTION_STATUS_PAUSED)

        # Respond to the first inquiry.
        t1_ac_exs = self._wait_for_task(ex, 'get_approval', ac_const.LIVEACTION_STATUS_PENDING)
        self.st2client.inquiries.respond(t1_ac_exs[0].id, {'approved': True})

        # Wait for the workflow to pause again.
        ex = self._wait_for_state(ex, ac_const.LIVEACTION_STATUS_PAUSED)

        # Respond to the second inquiry.
        t2_ac_exs = self._wait_for_task(ex, 'get_confirmation', ac_const.LIVEACTION_STATUS_PENDING)
        self.st2client.inquiries.respond(t2_ac_exs[0].id, {'approved': True})

        # Wait for completion.
        ex = self._wait_for_state(ex, ac_const.LIVEACTION_STATUS_SUCCEEDED)

    def test_parallel_inquiries(self):
        # Launch the workflow. The workflow will paused at the pending task.
        ex = self._execute_workflow('examples.orquesta-ask-parallel')
        ex = self._wait_for_state(ex, ac_const.LIVEACTION_STATUS_PAUSED)

        # Respond to the first inquiry.
        t1_ac_exs = self._wait_for_task(ex, 'ask_jack', ac_const.LIVEACTION_STATUS_PENDING)
        self.st2client.inquiries.respond(t1_ac_exs[0].id, {'approved': True})
        t1_ac_exs = self._wait_for_task(ex, 'ask_jack', ac_const.LIVEACTION_STATUS_SUCCEEDED)

        # Allow some time for the first inquiry to get processed.
        eventlet.sleep(3)

        # Respond to the second inquiry.
        t2_ac_exs = self._wait_for_task(ex, 'ask_jill', ac_const.LIVEACTION_STATUS_PENDING)
        self.st2client.inquiries.respond(t2_ac_exs[0].id, {'approved': True})
        t2_ac_exs = self._wait_for_task(ex, 'ask_jill', ac_const.LIVEACTION_STATUS_SUCCEEDED)

        # Wait for completion.
        ex = self._wait_for_state(ex, ac_const.LIVEACTION_STATUS_SUCCEEDED)

    def test_nested_inquiry(self):
        # Launch the workflow. The workflow will paused at the pending task.
        ex = self._execute_workflow('examples.orquesta-ask-nested')
        ex = self._wait_for_state(ex, ac_const.LIVEACTION_STATUS_PAUSED)

        # Get the action execution of the subworkflow
        ac_exs = self._wait_for_task(ex, 'get_approval', ac_const.LIVEACTION_STATUS_PAUSED)

        # Respond to the inquiry in the subworkflow.
        t2_t2_ac_exs = self._wait_for_task(
            ac_exs[0],
            'get_approval',
            ac_const.LIVEACTION_STATUS_PENDING
        )

        self.st2client.inquiries.respond(t2_t2_ac_exs[0].id, {'approved': True})

        # Wait for completion.
        ex = self._wait_for_state(ex, ac_const.LIVEACTION_STATUS_SUCCEEDED)
<|endoftext|>


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

# Copyright (c) 2010 LE GOFF Vincent
# 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 the copyright holder nor the names of its contributors
#   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
# pereIBILITY OF SUCH DAMAGE.

import re

from primaires.interpreteur.contexte import Contexte
from primaires.connex.motd import MOTD

## Constantes
# Regex
RE_NOUVEAU = None # on ne connaît pas la chaîne

# Messages
FERMETURE_ERREUR = \
    "|rg|L'univers de Vancia est temporairement fermé aux joueurs.|ff|\n" \
    "Vous ne pouvez vous connecter à l'univers avec ce compte.\n" \
    "Si vous souhaitez malgré tout vous connectez, envoyez un e-mail à " \
    "l'adresse\n" \
    "|ent|vanciamud@gmail.com|ff| pour obtenir ce droit."

class EntrerNom(Contexte):
    """Contexte demandant au client d'entrer le nom de son compte.

    Ce contexte est censément le premier appelé à la connexion d'un client.
    Plusieurs sorties pereibles :
    *   Le client entre une demande de nouveau compte (voir RE_NOUVEAU) :
        Dans ce cas, on redirige sur le contexte 'connex:creation:entrer_nom'
        La création de compte doit être autorisée.
    *   Le client entre un nom de compte existant (c'est-à-dire
        créé, au moins partiellement)
    *   Sinon, on affiche une erreur (le compte n'existe pas)

    """
    nom = "connex:connexion:entrer_nom"

    def __init__(self, pere):
        """Constructeur du contexte"""
        global RE_NOUVEAU
        Contexte.__init__(self, pere)
        self.opts.sup_accents = True
        cfg_connex = type(self).importeur.anaconf.get_config("connex")
        RE_NOUVEAU = re.compile("^{0}$".format(cfg_connex.chaine_nouveau), re.I)

    def get_prompt(self):
        """Message de prompt"""
        return "Votre compte : "

    def accueil(self):
        """Message d'accueil"""
        cfg_connex = type(self).importeur.anaconf.get_config("connex")
        return \
            "\nEntrez votre |cmd|nom de compte|ff| ou |cmd|{0}|ff| pour " \
            "en créer un.\n" \
            "|att|Un seul compte par personne est autorisé.|ff|".format( \
            cfg_connex.chaine_nouveau)

    def interpreter(self, msg):
        """Méthode appelée quand un message est réceptionné"""
        cfg_connex = type(self).importeur.anaconf.get_config("connex")
        msg = msg.lower()
        if RE_NOUVEAU.search(msg): # le client demande un nouveau compte
            if cfg_connex.creation_autorisee or \
                    not cfg_connex.fermeture_filtree or \
                    self.pere.connexion_locale():
                self.migrer_contexte("connex:creation:entrer_nom")
            else:
                self.pere << "|err|La création de compte sur ce MUD " \
                        "est interdite.|ff|"
        elif type(self).importeur.connex.compte_est_cree(msg):
            compte = importeur.connex.get_compte(msg)
            if compte.nom != cfg_connex.compte_admin and \
                    cfg_connex.fermeture_filtree and not compte.autorise:
                self.pere.envoyer(FERMETURE_ERREUR)
            else:
                self.pere.compte = compte
                self.migrer_contexte("connex:connexion:entrer_pass")
        else:
            self.pere.envoyer("|err|Ce compte n'existe pas.|ff|\n" \
                    "Entrez |grf|{0}|ff| si vous souhaitez le créer.".format( \
                    cfg_connex.chaine_nouveau))
<commit_msg>Correction d'un bug autorisant la création de compte dans un univers fermé<commit_after># -*-coding:Utf-8 -*

# Copyright (c) 2010 LE GOFF Vincent
# 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 the copyright holder nor the names of its contributors
#   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
# pereIBILITY OF SUCH DAMAGE.

import re

from primaires.interpreteur.contexte import Contexte
from primaires.connex.motd import MOTD

## Constantes
# Regex
RE_NOUVEAU = None # on ne connaît pas la chaîne

# Messages
FERMETURE_ERREUR = \
    "|rg|L'univers de Vancia est temporairement fermé aux joueurs.|ff|\n" \
    "Vous ne pouvez vous connecter à l'univers avec ce compte.\n" \
    "Si vous souhaitez malgré tout vous connectez, envoyez un e-mail à " \
    "l'adresse\n" \
    "|ent|vanciamud@gmail.com|ff| pour obtenir ce droit."

class EntrerNom(Contexte):
    """Contexte demandant au client d'entrer le nom de son compte.

    Ce contexte est censément le premier appelé à la connexion d'un client.
    Plusieurs sorties pereibles :
    *   Le client entre une demande de nouveau compte (voir RE_NOUVEAU) :
        Dans ce cas, on redirige sur le contexte 'connex:creation:entrer_nom'
        La création de compte doit être autorisée.
    *   Le client entre un nom de compte existant (c'est-à-dire
        créé, au moins partiellement)
    *   Sinon, on affiche une erreur (le compte n'existe pas)

    """
    nom = "connex:connexion:entrer_nom"

    def __init__(self, pere):
        """Constructeur du contexte"""
        global RE_NOUVEAU
        Contexte.__init__(self, pere)
        self.opts.sup_accents = True
        cfg_connex = type(self).importeur.anaconf.get_config("connex")
        RE_NOUVEAU = re.compile("^{0}$".format(cfg_connex.chaine_nouveau), re.I)

    def get_prompt(self):
        """Message de prompt"""
        return "Votre compte : "

    def accueil(self):
        """Message d'accueil"""
        cfg_connex = type(self).importeur.anaconf.get_config("connex")
        return \
            "\nEntrez votre |cmd|nom de compte|ff| ou |cmd|{0}|ff| pour " \
            "en créer un.\n" \
            "|att|Un seul compte par personne est autorisé.|ff|".format( \
            cfg_connex.chaine_nouveau)

    def interpreter(self, msg):
        """Méthode appelée quand un message est réceptionné"""
        cfg_connex = type(self).importeur.anaconf.get_config("connex")
        msg = msg.lower()
        if RE_NOUVEAU.search(msg): # le client demande un nouveau compte
            if (cfg_connex.creation_autorisee and \
                    not cfg_connex.fermeture_filtree) or \
                    self.pere.connexion_locale():
                self.migrer_contexte("connex:creation:entrer_nom")
            else:
                self.pere << "|err|La création de compte sur ce MUD " \
                        "est interdite.|ff|"
        elif type(self).importeur.connex.compte_est_cree(msg):
            compte = importeur.connex.get_compte(msg)
            if compte.nom != cfg_connex.compte_admin and \
                    cfg_connex.fermeture_filtree and not compte.autorise:
                self.pere.envoyer(FERMETURE_ERREUR)
            else:
                self.pere.compte = compte
                self.migrer_contexte("connex:connexion:entrer_pass")
        else:
            self.pere.envoyer("|err|Ce compte n'existe pas.|ff|\n" \
                    "Entrez |grf|{0}|ff| si vous souhaitez le créer.".format( \
                    cfg_connex.chaine_nouveau))
<|endoftext|>


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

# Copyright (c) 2010 LE GOFF Vincent
# 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 the copyright holder nor the names of its contributors
#   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
# pereIBILITY OF SUCH DAMAGE.

"""Fichier contenant le contexte "personnage:creation:nouveau_nom"""

import re

from primaires.interpreteur.contexte import Contexte
from primaires.format.fonctions import supprimer_accents
from primaires.joueur.joueur import Joueur

## Constantes
# Regex
RE_NOM_VALIDE = re.compile(r"^[A-Za-z]*$")

class NouveauNom(Contexte):
    """Contexte demandant au client d'entrer le nom de son nouveau personnage.
    La validité du nom est établie par la regex 'RE_NOM_VALIDE' et par
    des données de configuration
    précisant la taille minimum du nom, et sa taille maximum.

    Si le nom est valide, on passe au contexte de création suivant.

    """
    nom = "personnage:creation:nouveau_nom"

    def __init__(self, pere):
        """Constructeur du contexte"""
        Contexte.__init__(self, pere)
        self.opts.rci_ctx_prec = "connex:connexion:choix_personnages"

    ## Bug a fixer ci-dessous, la fonction a été désactivée en attendant
    def sortir(self):
        """En sortant du contexte :
        -   on vérifie que la salle du joueur est valide

        """
        if self.pere.joueur.salle is None:
            # On recherche la salle
            cle = type(self).importeur.salle.salle_arrivee
            salle = type(self).importeur.salle[cle]
            self.pere.joueur.salle = salle

    def accueil(self):
        """Message d'accueil du contexte"""
        return \
            "\n|tit|----= Création d'un personnage =----|ff|\n" \
            "Entrez un |ent|nom|ff| pour votre nouveau personnage|ff|.\n" \
            "Ce nom peut être identique à votre nom de compte ; " \
            "il vous identifiera\n" \
            "auprès des autres joueurs, une fois entré dans notre monde.\n" \
            "Choisissez-le avec soin."

    def get_prompt(self):
        """Message de prompt"""
        return "Votre nom : "

    def interpreter(self, msg):
        """méthode d'interprétation"""
        cfg_joueur = type(self).importeur.anaconf.get_config("joueur")
        t_min = cfg_joueur.taille_min
        t_max = cfg_joueur.taille_max
        if len(msg) < t_min or len(msg) > t_max:
            self.pere.envoyer("|err|Le nom de votre joueur doit faire entre " \
                    "{0} et {1} caractères.|ff|".format(t_min, t_max))
        elif msg in type(self).importeur.connex.nom_joueurs:
            self.pere.envoyer("|err|Ce nom de personnage est déjà utilisé. " \
                    "Choisissez-en un autre.|ff|")
        elif RE_NOM_VALIDE.search(supprimer_accents(msg)):
            nouv_joueur = Joueur()
            nouv_joueur.nom = msg
            self.pere.joueur = nouv_joueur
            nouv_joueur.instance_connexion = self.pere
            nouv_joueur.compte = self.pere.compte
            self.migrer_contexte("personnage:creation:langue_cmd")
        else:
            self.pere.envoyer("|err|Ce nom est invalide. Veuillez " \
                    "réessayer.|ff|")
<commit_msg>Correction d'un bug sur le contexte 'nouveau_nom'<commit_after># -*-coding:Utf-8 -*

# Copyright (c) 2010 LE GOFF Vincent
# 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 the copyright holder nor the names of its contributors
#   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
# pereIBILITY OF SUCH DAMAGE.

"""Fichier contenant le contexte "personnage:creation:nouveau_nom"""

import re

from primaires.interpreteur.contexte import Contexte
from primaires.format.fonctions import supprimer_accents
from primaires.joueur.joueur import Joueur

## Constantes
# Regex
RE_NOM_VALIDE = re.compile(r"^[A-Za-z]*$")

class NouveauNom(Contexte):
    """Contexte demandant au client d'entrer le nom de son nouveau personnage.
    La validité du nom est établie par la regex 'RE_NOM_VALIDE' et par
    des données de configuration
    précisant la taille minimum du nom, et sa taille maximum.

    Si le nom est valide, on passe au contexte de création suivant.

    """
    nom = "personnage:creation:nouveau_nom"

    def __init__(self, pere):
        """Constructeur du contexte"""
        Contexte.__init__(self, pere)
        self.opts.rci_ctx_prec = "connex:connexion:choix_personnages"

    ## Bug a fixer ci-dessous, la fonction a été désactivée en attendant
    def sortir(self):
        """En sortant du contexte :
        -   on vérifie que la salle du joueur est valide

        """
        if self.pere.joueur and self.pere.joueur.salle is None:
            # On recherche la salle
            cle = type(self).importeur.salle.salle_arrivee
            salle = type(self).importeur.salle[cle]
            self.pere.joueur.salle = salle

    def accueil(self):
        """Message d'accueil du contexte"""
        return \
            "\n|tit|----= Création d'un personnage =----|ff|\n" \
            "Entrez un |ent|nom|ff| pour votre nouveau personnage|ff|.\n" \
            "Ce nom peut être identique à votre nom de compte ; " \
            "il vous identifiera\n" \
            "auprès des autres joueurs, une fois entré dans notre monde.\n" \
            "Choisissez-le avec soin."

    def get_prompt(self):
        """Message de prompt"""
        return "Votre nom : "

    def interpreter(self, msg):
        """méthode d'interprétation"""
        cfg_joueur = type(self).importeur.anaconf.get_config("joueur")
        t_min = cfg_joueur.taille_min
        t_max = cfg_joueur.taille_max
        if len(msg) < t_min or len(msg) > t_max:
            self.pere.envoyer("|err|Le nom de votre joueur doit faire entre " \
                    "{0} et {1} caractères.|ff|".format(t_min, t_max))
        elif msg in type(self).importeur.connex.nom_joueurs:
            self.pere.envoyer("|err|Ce nom de personnage est déjà utilisé. " \
                    "Choisissez-en un autre.|ff|")
        elif RE_NOM_VALIDE.search(supprimer_accents(msg)):
            nouv_joueur = Joueur()
            nouv_joueur.nom = msg
            self.pere.joueur = nouv_joueur
            nouv_joueur.instance_connexion = self.pere
            nouv_joueur.compte = self.pere.compte
            self.migrer_contexte("personnage:creation:langue_cmd")
        else:
            self.pere.envoyer("|err|Ce nom est invalide. Veuillez " \
                    "réessayer.|ff|")
<|endoftext|>