<commit_before>"""Provide access to Python's configuration information.  The specific names
defined in the module depend heavily on the platform and configuration.

Written by:   Fred L. Drake, Jr.
Email:        <fdrake@acm.org>
Initial date: 17-Dec-1998
"""

__revision__ = "$Id$"

import os
import re
import string
import sys

from errors import DistutilsPlatformError

# These are needed in a couple of spots, so just compute them once.
PREFIX = os.path.normpath(sys.prefix)
EXEC_PREFIX = os.path.normpath(sys.exec_prefix)

def get_python_inc(plat_specific=0, prefix=None):
    """Return the directory containing installed Python header files.

    If 'plat_specific' is false (the default), this is the path to the
    non-platform-specific header files, i.e. Python.h and so on;
    otherwise, this is the path to platform-specific header files
    (namely config.h).

    If 'prefix' is supplied, use it instead of sys.prefix or
    sys.exec_prefix -- i.e., ignore 'plat_specific'.
    """
    if prefix is None:
        prefix = (plat_specific and EXEC_PREFIX or PREFIX)
    if os.name == "posix":
        return os.path.join(prefix, "include", "python" + sys.version[:3])
    elif os.name == "nt":
        return os.path.join(prefix, "Include") # include or Include?
    elif os.name == "mac":
        return os.path.join(prefix, "Include")
    else:
        raise DistutilsPlatformError, \
              ("I don't know where Python installs its C header files " +
               "on platform '%s'") % os.name

def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
    """Return the directory containing the Python library (standard or
    site additions).

    If 'plat_specific' is true, return the directory containing
    platform-specific modules, i.e. any module from a non-pure-Python
    module distribution; otherwise, return the platform-shared library
    directory.  If 'standard_lib' is true, return the directory
    containing standard Python library modules; otherwise, return the
    directory for site-specific modules.

    If 'prefix' is supplied, use it instead of sys.prefix or
    sys.exec_prefix -- i.e., ignore 'plat_specific'.
    """
    if prefix is None:
        prefix = (plat_specific and EXEC_PREFIX or PREFIX)

    if os.name == "posix":
        libpython = os.path.join(prefix,
                                 "lib", "python" + sys.version[:3])
        if standard_lib:
            return libpython
        else:
            return os.path.join(libpython, "site-packages")

    elif os.name == "nt":
        if standard_lib:
            return os.path.join(PREFIX, "Lib")
        else:
            return prefix

    elif os.name == "mac":
        if plat_specific:
            if standard_lib:
                return os.path.join(EXEC_PREFIX, "Mac", "Plugins")
            else:
                raise DistutilsPlatformError, \
                      "OK, where DO site-specific extensions go on the Mac?"
        else:
            if standard_lib:
                return os.path.join(PREFIX, "Lib")
            else:
                raise DistutilsPlatformError, \
                      "OK, where DO site-specific modules go on the Mac?"
    else:
        raise DistutilsPlatformError, \
              ("I don't know where Python installs its library " +
               "on platform '%s'") % os.name

# get_python_lib()

def customize_compiler (compiler):
    """Do any platform-specific customization of the CCompiler instance
    'compiler'.  Mainly needed on Unix, so we can plug in the information
    that varies across Unices and is stored in Python's Makefile.
    """
    if compiler.compiler_type == "unix":
        (cc, opt, ccshared, ldshared, so_ext) = \
            get_config_vars('CC', 'OPT', 'CCSHARED', 'LDSHARED', 'SO')

        cc_cmd = cc + ' ' + opt
        compiler.set_executables(
            preprocessor=cc + " -E",    # not always!
            compiler=cc_cmd,
            compiler_so=cc_cmd + ' ' + ccshared,
            linker_so=ldshared,
            linker_exe=cc)

        compiler.shared_lib_extension = so_ext

def get_config_h_filename():
    """Return full pathname of installed config.h file."""
    inc_dir = get_python_inc(plat_specific=1)
    return os.path.join(inc_dir, "config.h")

def get_makefile_filename():
    """Return full pathname of installed Makefile from the Python build."""
    lib_dir = get_python_lib(plat_specific=1, standard_lib=1)
    return os.path.join(lib_dir, "config", "Makefile")

def parse_config_h(fp, g=None):
    """Parse a config.h-style file.

    A dictionary containing name/value pairs is returned.  If an
    optional dictionary is passed in as the second argument, it is
    used instead of a new dictionary.
    """
    if g is None:
        g = {}
    define_rx = re.compile("#define ([A-Z][A-Z0-9_]+) (.*)\n")
    undef_rx = re.compile("/[*] #undef ([A-Z][A-Z0-9_]+) [*]/\n")
    #
    while 1:
        line = fp.readline()
        if not line:
            break
        m = define_rx.match(line)
        if m:
            n, v = m.group(1, 2)
            try: v = string.atoi(v)
            except ValueError: pass
            g[n] = v
        else:
            m = undef_rx.match(line)
            if m:
                g[m.group(1)] = 0
    return g

# Regexes needed for parsing Makefile (and similar syntaxes,
# like old-style Setup files).
_variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
_findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
_findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")

def parse_makefile(fn, g=None):
    """Parse a Makefile-style file.

    A dictionary containing name/value pairs is returned.  If an
    optional dictionary is passed in as the second argument, it is
    used instead of a new dictionary.

    """
    from distutils.text_file import TextFile
    fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1)

    if g is None:
        g = {}
    done = {}
    notdone = {}

    while 1:
        line = fp.readline()
        if line is None:                # eof
            break
        m = _variable_rx.match(line)
        if m:
            n, v = m.group(1, 2)
            v = string.strip(v)
            if "$" in v:
                notdone[n] = v
            else:
                try: v = string.atoi(v)
                except ValueError: pass
                done[n] = v

    # do variable interpolation here
    while notdone:
        for name in notdone.keys():
            value = notdone[name]
            m = _findvar1_rx.search(value) or _findvar2_rx.search(value)
            if m:
                n = m.group(1)
                if done.has_key(n):
                    after = value[m.end():]
                    value = value[:m.start()] + done[n] + after
                    if "$" in after:
                        notdone[name] = value
                    else:
                        try: value = string.atoi(value)
                        except ValueError: pass
                        done[name] = string.strip(value)
                        del notdone[name]
                elif notdone.has_key(n):
                    # get it on a subsequent round
                    pass
                else:
                    done[n] = ""
                    after = value[m.end():]
                    value = value[:m.start()] + after
                    if "$" in after:
                        notdone[name] = value
                    else:
                        try: value = string.atoi(value)
                        except ValueError: pass
                        done[name] = string.strip(value)
                        del notdone[name]
            else:
                # bogus variable reference; just drop it since we can't deal
                del notdone[name]

    fp.close()

    # save the results in the global dictionary
    g.update(done)
    return g

def expand_makefile_vars(s, vars):
    """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in
    'string' according to 'vars' (a dictionary mapping variable names to
    values).  Variables not present in 'vars' are silently expanded to the
    empty string.  The variable values in 'vars' should not contain further
    variable expansions; if 'vars' is the output of 'parse_makefile()',
    you're fine.  Returns a variable-expanded version of 's'.
    """

    # This algorithm does multiple expansion, so if vars['foo'] contains
    # "${bar}", it will expand ${foo} to ${bar}, and then expand
    # ${bar}... and so forth.  This is fine as long as 'vars' comes from
    # 'parse_makefile()', which takes care of such expansions eagerly,
    # according to make's variable expansion semantics.

    while 1:
        m = _findvar1_rx.search(s) or _findvar2_rx.search(s)
        if m:
            name = m.group(1)
            (beg, end) = m.span()
            s = s[0:beg] + vars.get(m.group(1)) + s[end:]
        else:
            break
    return s

_config_vars = None

def _init_posix():
    """Initialize the module as appropriate for POSIX systems."""
    g = {}
    # load the installed Makefile:
    try:
        filename = get_makefile_filename()
        parse_makefile(filename, g)
    except IOError, msg:
        my_msg = "invalid Python installation: unable to open %s" % filename
        if hasattr(msg, "strerror"):
            my_msg = my_msg + " (%s)" % msg.strerror

        raise DistutilsPlatformError, my_msg

    # On AIX, there are wrong paths to the linker scripts in the Makefile
    # -- these paths are relative to the Python source, but when installed
    # the scripts are in another directory.
    if sys.platform == 'aix4':          # what about AIX 3.x ?
        # Linker script is in the config directory, not in Modules as the
        # Makefile says.
        python_lib = get_python_lib(standard_lib=1)
        ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix')
        python_exp = os.path.join(python_lib, 'config', 'python.exp')

        g['LDSHARED'] = "%s %s -bI:%s" % (ld_so_aix, g['CC'], python_exp)

    elif sys.platform == 'beos':

        # Linker script is in the config directory.  In the Makefile it is
        # relative to the srcdir, which after installation no longer makes
        # sense.
        python_lib = get_python_lib(standard_lib=1)
        linkerscript_name = os.path.basename(string.split(g['LDSHARED'])[0])
        linkerscript = os.path.join(python_lib, 'config', linkerscript_name)

        # XXX this isn't the right place to do this: adding the Python
        # library to the link, if needed, should be in the "build_ext"
        # command.  (It's also needed for non-MS compilers on Windows, and
        # it's taken care of for them by the 'build_ext.get_libraries()'
        # method.)
        g['LDSHARED'] = ("%s -L%s/lib -lpython%s" %
                         (linkerscript, PREFIX, sys.version[0:3]))

    global _config_vars
    _config_vars = g

def _init_nt():
    """Initialize the module as appropriate for NT"""
    g = {}
    # set basic install directories
    g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
    g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)

    # XXX hmmm.. a normal install puts include files here
    g['INCLUDEPY'] = get_python_inc(plat_specific=0)

    g['SO'] = '.pyd'
    g['EXE'] = ".exe"

    global _config_vars
    _config_vars = g

def _init_mac():
    """Initialize the module as appropriate for Macintosh systems"""
    g = {}
    # set basic install directories
    g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
    g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)

    # XXX hmmm.. a normal install puts include files here
    g['INCLUDEPY'] = get_python_inc(plat_specific=0)

    g['SO'] = '.ppc.slb'

    # XXX are these used anywhere?
    g['install_lib'] = os.path.join(EXEC_PREFIX, "Lib")
    g['install_platlib'] = os.path.join(EXEC_PREFIX, "Mac", "Lib")

    global _config_vars
    _config_vars = g

def get_config_vars(*args):
    """With no arguments, return a dictionary of all configuration
    variables relevant for the current platform.  Generally this includes
    everything needed to build extensions and install both pure modules and
    extensions.  On Unix, this means every variable defined in Python's
    installed Makefile; on Windows and Mac OS it's a much smaller set.

    With arguments, return a list of values that result from looking up
    each argument in the configuration variable dictionary.
    """
    global _config_vars
    if _config_vars is None:
        func = globals().get("_init_" + os.name)
        if func:
            func()
        else:
            _config_vars = {}

        # Normalized versions of prefix and exec_prefix are handy to have;
        # in fact, these are the standard versions used most places in the
        # Distutils.
        _config_vars['prefix'] = PREFIX
        _config_vars['exec_prefix'] = EXEC_PREFIX

    if args:
        vals = []
        for name in args:
            vals.append(_config_vars.get(name))
        return vals
    else:
        return _config_vars

def get_config_var(name):
    """Return the value of a single variable using the dictionary
    returned by 'get_config_vars()'.  Equivalent to
      get_config_vars().get(name)
    """
    return get_config_vars().get(name)
<commit_msg>Fix bugs with integer-valued variables when parsing Makefiles.  Values for done[n] can be integers as well as strings, but the code concatenates them with strings (fixed by adding a str()) and calls string.strip() on them (fixed by rearranging the logic)<commit_after>"""Provide access to Python's configuration information.  The specific names
defined in the module depend heavily on the platform and configuration.

Written by:   Fred L. Drake, Jr.
Email:        <fdrake@acm.org>
Initial date: 17-Dec-1998
"""

__revision__ = "$Id$"

import os
import re
import string
import sys

from errors import DistutilsPlatformError

# These are needed in a couple of spots, so just compute them once.
PREFIX = os.path.normpath(sys.prefix)
EXEC_PREFIX = os.path.normpath(sys.exec_prefix)

def get_python_inc(plat_specific=0, prefix=None):
    """Return the directory containing installed Python header files.

    If 'plat_specific' is false (the default), this is the path to the
    non-platform-specific header files, i.e. Python.h and so on;
    otherwise, this is the path to platform-specific header files
    (namely config.h).

    If 'prefix' is supplied, use it instead of sys.prefix or
    sys.exec_prefix -- i.e., ignore 'plat_specific'.
    """
    if prefix is None:
        prefix = (plat_specific and EXEC_PREFIX or PREFIX)
    if os.name == "posix":
        return os.path.join(prefix, "include", "python" + sys.version[:3])
    elif os.name == "nt":
        return os.path.join(prefix, "Include") # include or Include?
    elif os.name == "mac":
        return os.path.join(prefix, "Include")
    else:
        raise DistutilsPlatformError, \
              ("I don't know where Python installs its C header files " +
               "on platform '%s'") % os.name

def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
    """Return the directory containing the Python library (standard or
    site additions).

    If 'plat_specific' is true, return the directory containing
    platform-specific modules, i.e. any module from a non-pure-Python
    module distribution; otherwise, return the platform-shared library
    directory.  If 'standard_lib' is true, return the directory
    containing standard Python library modules; otherwise, return the
    directory for site-specific modules.

    If 'prefix' is supplied, use it instead of sys.prefix or
    sys.exec_prefix -- i.e., ignore 'plat_specific'.
    """
    if prefix is None:
        prefix = (plat_specific and EXEC_PREFIX or PREFIX)

    if os.name == "posix":
        libpython = os.path.join(prefix,
                                 "lib", "python" + sys.version[:3])
        if standard_lib:
            return libpython
        else:
            return os.path.join(libpython, "site-packages")

    elif os.name == "nt":
        if standard_lib:
            return os.path.join(PREFIX, "Lib")
        else:
            return prefix

    elif os.name == "mac":
        if plat_specific:
            if standard_lib:
                return os.path.join(EXEC_PREFIX, "Mac", "Plugins")
            else:
                raise DistutilsPlatformError, \
                      "OK, where DO site-specific extensions go on the Mac?"
        else:
            if standard_lib:
                return os.path.join(PREFIX, "Lib")
            else:
                raise DistutilsPlatformError, \
                      "OK, where DO site-specific modules go on the Mac?"
    else:
        raise DistutilsPlatformError, \
              ("I don't know where Python installs its library " +
               "on platform '%s'") % os.name

# get_python_lib()

def customize_compiler (compiler):
    """Do any platform-specific customization of the CCompiler instance
    'compiler'.  Mainly needed on Unix, so we can plug in the information
    that varies across Unices and is stored in Python's Makefile.
    """
    if compiler.compiler_type == "unix":
        (cc, opt, ccshared, ldshared, so_ext) = \
            get_config_vars('CC', 'OPT', 'CCSHARED', 'LDSHARED', 'SO')

        cc_cmd = cc + ' ' + opt
        compiler.set_executables(
            preprocessor=cc + " -E",    # not always!
            compiler=cc_cmd,
            compiler_so=cc_cmd + ' ' + ccshared,
            linker_so=ldshared,
            linker_exe=cc)

        compiler.shared_lib_extension = so_ext

def get_config_h_filename():
    """Return full pathname of installed config.h file."""
    inc_dir = get_python_inc(plat_specific=1)
    return os.path.join(inc_dir, "config.h")

def get_makefile_filename():
    """Return full pathname of installed Makefile from the Python build."""
    lib_dir = get_python_lib(plat_specific=1, standard_lib=1)
    return os.path.join(lib_dir, "config", "Makefile")

def parse_config_h(fp, g=None):
    """Parse a config.h-style file.

    A dictionary containing name/value pairs is returned.  If an
    optional dictionary is passed in as the second argument, it is
    used instead of a new dictionary.
    """
    if g is None:
        g = {}
    define_rx = re.compile("#define ([A-Z][A-Z0-9_]+) (.*)\n")
    undef_rx = re.compile("/[*] #undef ([A-Z][A-Z0-9_]+) [*]/\n")
    #
    while 1:
        line = fp.readline()
        if not line:
            break
        m = define_rx.match(line)
        if m:
            n, v = m.group(1, 2)
            try: v = string.atoi(v)
            except ValueError: pass
            g[n] = v
        else:
            m = undef_rx.match(line)
            if m:
                g[m.group(1)] = 0
    return g

# Regexes needed for parsing Makefile (and similar syntaxes,
# like old-style Setup files).
_variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
_findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
_findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")

def parse_makefile(fn, g=None):
    """Parse a Makefile-style file.

    A dictionary containing name/value pairs is returned.  If an
    optional dictionary is passed in as the second argument, it is
    used instead of a new dictionary.

    """
    from distutils.text_file import TextFile
    fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1)

    if g is None:
        g = {}
    done = {}
    notdone = {}

    while 1:
        line = fp.readline()
        if line is None:                # eof
            break
        m = _variable_rx.match(line)
        if m:
            n, v = m.group(1, 2)
            v = string.strip(v)
            if "$" in v:
                notdone[n] = v
            else:
                try: v = string.atoi(v)
                except ValueError: pass
                done[n] = v

    # do variable interpolation here
    while notdone:
        for name in notdone.keys():
            value = notdone[name]
            m = _findvar1_rx.search(value) or _findvar2_rx.search(value)
            if m:
                n = m.group(1)
                if done.has_key(n):
                    after = value[m.end():]
                    value = value[:m.start()] + str(done[n]) + after
                    if "$" in after:
                        notdone[name] = value
                    else:
                        try: value = string.atoi(value)
                        except ValueError:
                            done[name] = string.strip(value)
                        else:
                            done[name] = value
                        del notdone[name]
                elif notdone.has_key(n):
                    # get it on a subsequent round
                    pass
                else:
                    done[n] = ""
                    after = value[m.end():]
                    value = value[:m.start()] + after
                    if "$" in after:
                        notdone[name] = value
                    else:
                        try: value = string.atoi(value)
                        except ValueError:
                            done[name] = string.strip(value)
                        else:
                            done[name] = value
                        del notdone[name]
            else:
                # bogus variable reference; just drop it since we can't deal
                del notdone[name]

    fp.close()

    # save the results in the global dictionary
    g.update(done)
    return g

def expand_makefile_vars(s, vars):
    """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in
    'string' according to 'vars' (a dictionary mapping variable names to
    values).  Variables not present in 'vars' are silently expanded to the
    empty string.  The variable values in 'vars' should not contain further
    variable expansions; if 'vars' is the output of 'parse_makefile()',
    you're fine.  Returns a variable-expanded version of 's'.
    """

    # This algorithm does multiple expansion, so if vars['foo'] contains
    # "${bar}", it will expand ${foo} to ${bar}, and then expand
    # ${bar}... and so forth.  This is fine as long as 'vars' comes from
    # 'parse_makefile()', which takes care of such expansions eagerly,
    # according to make's variable expansion semantics.

    while 1:
        m = _findvar1_rx.search(s) or _findvar2_rx.search(s)
        if m:
            name = m.group(1)
            (beg, end) = m.span()
            s = s[0:beg] + vars.get(m.group(1)) + s[end:]
        else:
            break
    return s

_config_vars = None

def _init_posix():
    """Initialize the module as appropriate for POSIX systems."""
    g = {}
    # load the installed Makefile:
    try:
        filename = get_makefile_filename()
        parse_makefile(filename, g)
    except IOError, msg:
        my_msg = "invalid Python installation: unable to open %s" % filename
        if hasattr(msg, "strerror"):
            my_msg = my_msg + " (%s)" % msg.strerror

        raise DistutilsPlatformError, my_msg

    # On AIX, there are wrong paths to the linker scripts in the Makefile
    # -- these paths are relative to the Python source, but when installed
    # the scripts are in another directory.
    if sys.platform == 'aix4':          # what about AIX 3.x ?
        # Linker script is in the config directory, not in Modules as the
        # Makefile says.
        python_lib = get_python_lib(standard_lib=1)
        ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix')
        python_exp = os.path.join(python_lib, 'config', 'python.exp')

        g['LDSHARED'] = "%s %s -bI:%s" % (ld_so_aix, g['CC'], python_exp)

    elif sys.platform == 'beos':

        # Linker script is in the config directory.  In the Makefile it is
        # relative to the srcdir, which after installation no longer makes
        # sense.
        python_lib = get_python_lib(standard_lib=1)
        linkerscript_name = os.path.basename(string.split(g['LDSHARED'])[0])
        linkerscript = os.path.join(python_lib, 'config', linkerscript_name)

        # XXX this isn't the right place to do this: adding the Python
        # library to the link, if needed, should be in the "build_ext"
        # command.  (It's also needed for non-MS compilers on Windows, and
        # it's taken care of for them by the 'build_ext.get_libraries()'
        # method.)
        g['LDSHARED'] = ("%s -L%s/lib -lpython%s" %
                         (linkerscript, PREFIX, sys.version[0:3]))

    global _config_vars
    _config_vars = g

def _init_nt():
    """Initialize the module as appropriate for NT"""
    g = {}
    # set basic install directories
    g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
    g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)

    # XXX hmmm.. a normal install puts include files here
    g['INCLUDEPY'] = get_python_inc(plat_specific=0)

    g['SO'] = '.pyd'
    g['EXE'] = ".exe"

    global _config_vars
    _config_vars = g

def _init_mac():
    """Initialize the module as appropriate for Macintosh systems"""
    g = {}
    # set basic install directories
    g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
    g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)

    # XXX hmmm.. a normal install puts include files here
    g['INCLUDEPY'] = get_python_inc(plat_specific=0)

    g['SO'] = '.ppc.slb'

    # XXX are these used anywhere?
    g['install_lib'] = os.path.join(EXEC_PREFIX, "Lib")
    g['install_platlib'] = os.path.join(EXEC_PREFIX, "Mac", "Lib")

    global _config_vars
    _config_vars = g

def get_config_vars(*args):
    """With no arguments, return a dictionary of all configuration
    variables relevant for the current platform.  Generally this includes
    everything needed to build extensions and install both pure modules and
    extensions.  On Unix, this means every variable defined in Python's
    installed Makefile; on Windows and Mac OS it's a much smaller set.

    With arguments, return a list of values that result from looking up
    each argument in the configuration variable dictionary.
    """
    global _config_vars
    if _config_vars is None:
        func = globals().get("_init_" + os.name)
        if func:
            func()
        else:
            _config_vars = {}

        # Normalized versions of prefix and exec_prefix are handy to have;
        # in fact, these are the standard versions used most places in the
        # Distutils.
        _config_vars['prefix'] = PREFIX
        _config_vars['exec_prefix'] = EXEC_PREFIX

    if args:
        vals = []
        for name in args:
            vals.append(_config_vars.get(name))
        return vals
    else:
        return _config_vars

def get_config_var(name):
    """Return the value of a single variable using the dictionary
    returned by 'get_config_vars()'.  Equivalent to
      get_config_vars().get(name)
    """
    return get_config_vars().get(name)
<|endoftext|>


<commit_before>
import time
import urllib

from browse import Browser, Game
metaserver = "http://metaserver.thousandparsec.net/"
metaserver = "http://localhost/metaserver/"

def getpacket(data):
	header, data = data[:objects.Header.size], data[objects.Header.size:]
	p = objects.Header(header)
	p.process(data[:p.length])

 	return p, data[p.length:]

from tp.netlib import objects

class MetaServerBrowser(Browser):
	def __init__(self, timeout=60*10):
		self.timeout = timeout
		self.waittill = 0
		self.games = {}

	def run(self):
		while True:
			now = time.time()
			print self.waittill, now
			if self.waittill < now:
				data = urllib.urlopen(metaserver, urllib.urlencode({'action': 'get'})).read()
				if data[:4] == "TP03":

					p, data = getpacket(data)
					if isinstance(p, objects.Fail):
						print p.error
					elif isinstance(p, objects.Sequence):
						g = self.games
						for game in g.values():
							game.notfound = True

						for i in range(0, p.number):
							p, data = getpacket(data)

							if not isinstance(p, objects.Game):
								raise TypeError("The metaserver returned an incorrect response (expected Game packet)...")

							if not p.name in g:
								game = Game(p.name)
							else:
								game = g[p.name]

							game.updateOptional(p.optional)
							game.updateRequired(p.required)

							game.locations = {}
							for type, dns, ip, port in p.locations:
								game.addLocation(type, (dns, ip, port))

							if game.new:
								self.GameFound(game)
								game.new = False
							else:
								self.GameUpdate(game)

							game.notfound = False

							g[game.name] = game

						for k, game in g.items():
							if game.notfound:
								del g[k]
								self.GameGone(game)
					else:
						raise TypeError("The metaserver returned an incorrect response (expected Failure or Sequence)...")

				self.waittill = now + self.timeout
			time.sleep(min(10, self.waittill - time.time()))

def main():
	a = MetaServerBrowser()
	a.run()

if __name__ == "__main__":
	main()

<commit_msg>Use real metaserver.<commit_after>
import time
import urllib

from browse import Browser, Game
metaserver = "http://metaserver.thousandparsec.net/"

def getpacket(data):
	header, data = data[:objects.Header.size], data[objects.Header.size:]
	p = objects.Header(header)
	p.process(data[:p.length])

 	return p, data[p.length:]

from tp.netlib import objects

class MetaServerBrowser(Browser):
	def __init__(self, timeout=60*10):
		self.timeout = timeout
		self.waittill = 0
		self.games = {}

	def run(self):
		while True:
			now = time.time()
			print self.waittill, now
			if self.waittill < now:
				data = urllib.urlopen(metaserver, urllib.urlencode({'action': 'get'})).read()
				if data[:4] == "TP03":

					p, data = getpacket(data)
					if isinstance(p, objects.Fail):
						print p.error
					elif isinstance(p, objects.Sequence):
						g = self.games
						for game in g.values():
							game.notfound = True

						for i in range(0, p.number):
							p, data = getpacket(data)

							if not isinstance(p, objects.Game):
								raise TypeError("The metaserver returned an incorrect response (expected Game packet)...")

							if not p.name in g:
								game = Game(p.name)
							else:
								game = g[p.name]

							game.updateOptional(p.optional)
							game.updateRequired(p.required)

							game.locations = {}
							for type, dns, ip, port in p.locations:
								game.addLocation(type, (dns, ip, port))

							if game.new:
								self.GameFound(game)
								game.new = False
							else:
								self.GameUpdate(game)

							game.notfound = False

							g[game.name] = game

						for k, game in g.items():
							if game.notfound:
								del g[k]
								self.GameGone(game)
					else:
						raise TypeError("The metaserver returned an incorrect response (expected Failure or Sequence)...")

				self.waittill = now + self.timeout
			time.sleep(min(10, self.waittill - time.time()))

def main():
	a = MetaServerBrowser()
	a.run()

if __name__ == "__main__":
	main()

<|endoftext|>


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

import os

"""
Ansible module to manage elasticsearch plugins
(c) 2015, Mathew Davies <thepixeldeveloper@googlemail.com>

This file is part of Ansible

Ansible is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Ansible is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
"""

DOCUMENTATION = '''
---
module: elasticsearch_plugin
short_description: Manage Elasticsearch plugins
description:
    - Manages Elasticsearch plugins.
version_added: ""
author: Mathew Davies (@ThePixelDeveloper)
options:
    name:
        description:
            - Name of the plugin to install
        required: True
    state:
        description:
            - Desired state of a plugin.
        required: False
        choices: [present, absent]
        default: present
    url:
        description:
            - Set exact URL to download the plugin from
        required: False
        default: None
    timeout:
        description:
            - Timeout setting: 30s, 1m, 1h...
        required: False
        default: 1m
    plugin_bin:
        description:
            - Location of the plugin binary
        required: False
        default: /usr/share/elasticsearch/bin/plugin
    plugin_dir:
        description:
            - Your configured plugin directory specified in Elasticsearch
        required: False
        default: /usr/share/elasticsearch/plugins/
    version:
        description:
            - Version of the plugin to be installed.
              If plugin exists with previous version, it will NOT be updated
        required: False
        default: None
'''

EXAMPLES = '''
# Install Elasticsearch head plugin
- elasticsearch_plugin: state=present name="mobz/elasticsearch-head"

# Install specific version of a plugin
- elasticsearch_plugin: state=present name="com.github.kzwang/elasticsearch-image" version="1.2.0"

# Uninstall Elasticsearch head plugin
- elasticsearch_plugin: state=absent name="mobz/elasticsearch-head"
'''

def parse_plugin_repo(string):
    elements = string.split("/")

    # We first consider the simplest form: pluginname
    repo = elements[0]

    # We consider the form: username/pluginname
    if len(elements) > 1:
        repo = elements[1]

    # remove elasticsearch- prefix
    # remove es- prefix
    for string in ("elasticsearch-", "es-"):
        if repo.startswith(string):
            return repo[len(string):]

    return repo

def is_plugin_present(plugin_dir, working_dir):
    return os.path.isdir(os.path.join(working_dir, plugin_dir))

def parse_error(string):
    reason = "reason: "
    return string[string.index(reason) + len(reason):].strip()

def main():

    package_state_map = dict(
        present="--install",
        absent="--remove"
    )

    module = AnsibleModule(
        argument_spec=dict(
            name=dict(required=True),
            state=dict(default="present", choices=package_state_map.keys()),
            url=dict(default=None),
            timeout=dict(default="1m"),
            plugin_bin=dict(default="/usr/share/elasticsearch/bin/plugin"),
            plugin_dir=dict(default="/usr/share/elasticsearch/plugins/"),
            proxy_host=dict(default=None),
            proxy_port=dict(default=None),
            version=dict(default=None)
        )
    )

    name = module.params["name"]
    state = module.params["state"]
    url = module.params["url"]
    timeout = module.params["timeout"]
    plugin_bin = module.params["plugin_bin"]
    plugin_dir = module.params["plugin_dir"]
    proxy_host = module.params["proxy_host"]
    proxy_port = module.params["proxy_port"]
    version = module.params["version"]

    present = is_plugin_present(parse_plugin_repo(name), plugin_dir)

    # skip if the state is correct
    if (present and state == "present") or (state == "absent" and not present):
        module.exit_json(changed=False, name=name)

    if (version):
       name = name + '/' + version

    cmd_args = [plugin_bin, package_state_map[state], name]

    if proxy_host and proxy_port:
        cmd_args.append("-DproxyHost=%s -DproxyPort=%s" % proxy_host, proxy_port)

    if url:
        cmd_args.append("--url %s" % url)

    if timeout:
        cmd_args.append("--timeout %s" % timeout)

    cmd = " ".join(cmd_args)

    rc, out, err = module.run_command(cmd)

    if rc != 0:
        reason = parse_error(out)
        module.fail_json(msg=reason)

    module.exit_json(changed=True, cmd=cmd, name=name, state=state, url=url, timeout=timeout, stdout=out, stderr=err)

from ansible.module_utils.basic import *

main()
<commit_msg>update doc for proxy support<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-

import os

"""
Ansible module to manage elasticsearch plugins
(c) 2015, Mathew Davies <thepixeldeveloper@googlemail.com>

This file is part of Ansible

Ansible is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Ansible is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
"""

DOCUMENTATION = '''
---
module: elasticsearch_plugin
short_description: Manage Elasticsearch plugins
description:
    - Manages Elasticsearch plugins.
version_added: ""
author: Mathew Davies (@ThePixelDeveloper)
options:
    name:
        description:
            - Name of the plugin to install
        required: True
    state:
        description:
            - Desired state of a plugin.
        required: False
        choices: [present, absent]
        default: present
    url:
        description:
            - Set exact URL to download the plugin from
        required: False
        default: None
    timeout:
        description:
            - Timeout setting: 30s, 1m, 1h...
        required: False
        default: 1m
    plugin_bin:
        description:
            - Location of the plugin binary
        required: False
        default: /usr/share/elasticsearch/bin/plugin
    plugin_dir:
        description:
            - Your configured plugin directory specified in Elasticsearch
        required: False
        default: /usr/share/elasticsearch/plugins/
    proxy_host:
        description:
            - Proxy host to use during plugin installation
        required: False
        default: None
    proxy_port:
        description:
            - Proxy port to use during plugin installation
        required: False
        default: None
    version:
        description:
            - Version of the plugin to be installed.
              If plugin exists with previous version, it will NOT be updated
        required: False
        default: None
'''

EXAMPLES = '''
# Install Elasticsearch head plugin
- elasticsearch_plugin: state=present name="mobz/elasticsearch-head"

# Install specific version of a plugin
- elasticsearch_plugin: state=present name="com.github.kzwang/elasticsearch-image" version="1.2.0"

# Uninstall Elasticsearch head plugin
- elasticsearch_plugin: state=absent name="mobz/elasticsearch-head"
'''

def parse_plugin_repo(string):
    elements = string.split("/")

    # We first consider the simplest form: pluginname
    repo = elements[0]

    # We consider the form: username/pluginname
    if len(elements) > 1:
        repo = elements[1]

    # remove elasticsearch- prefix
    # remove es- prefix
    for string in ("elasticsearch-", "es-"):
        if repo.startswith(string):
            return repo[len(string):]

    return repo

def is_plugin_present(plugin_dir, working_dir):
    return os.path.isdir(os.path.join(working_dir, plugin_dir))

def parse_error(string):
    reason = "reason: "
    return string[string.index(reason) + len(reason):].strip()

def main():

    package_state_map = dict(
        present="--install",
        absent="--remove"
    )

    module = AnsibleModule(
        argument_spec=dict(
            name=dict(required=True),
            state=dict(default="present", choices=package_state_map.keys()),
            url=dict(default=None),
            timeout=dict(default="1m"),
            plugin_bin=dict(default="/usr/share/elasticsearch/bin/plugin"),
            plugin_dir=dict(default="/usr/share/elasticsearch/plugins/"),
            proxy_host=dict(default=None),
            proxy_port=dict(default=None),
            version=dict(default=None)
        )
    )

    name = module.params["name"]
    state = module.params["state"]
    url = module.params["url"]
    timeout = module.params["timeout"]
    plugin_bin = module.params["plugin_bin"]
    plugin_dir = module.params["plugin_dir"]
    proxy_host = module.params["proxy_host"]
    proxy_port = module.params["proxy_port"]
    version = module.params["version"]

    present = is_plugin_present(parse_plugin_repo(name), plugin_dir)

    # skip if the state is correct
    if (present and state == "present") or (state == "absent" and not present):
        module.exit_json(changed=False, name=name)

    if (version):
       name = name + '/' + version

    cmd_args = [plugin_bin, package_state_map[state], name]

    if proxy_host and proxy_port:
        cmd_args.append("-DproxyHost=%s -DproxyPort=%s" % proxy_host, proxy_port)

    if url:
        cmd_args.append("--url %s" % url)

    if timeout:
        cmd_args.append("--timeout %s" % timeout)

    cmd = " ".join(cmd_args)

    rc, out, err = module.run_command(cmd)

    if rc != 0:
        reason = parse_error(out)
        module.fail_json(msg=reason)

    module.exit_json(changed=True, cmd=cmd, name=name, state=state, url=url, timeout=timeout, stdout=out, stderr=err)

from ansible.module_utils.basic import *

main()
<|endoftext|>


<commit_before>from fontbakery.checkrunner import (PASS, FAIL)
from fontTools.ttLib import TTFont

def test_check_name_empty_records():
    from fontbakery.specifications.adobe_fonts import (
        com_adobe_fonts_check_name_empty_records as check)
    font_path = "data/test/source-sans-pro/OTF/SourceSansPro-Regular.otf"
    test_font = TTFont(font_path)

    # try a font with fully populated name records
    status, message = list(check(test_font))[-1]
    assert status == PASS

    # now try a completely empty string
    test_font['name'].names[3].string = b''
    status, message = list(check(test_font))[-1]
    assert status == FAIL

    # now try a string that only has whitespace
    test_font['name'].names[3].string = b' '
    status, message = list(check(test_font))[-1]
    assert status == FAIL

def test_check_consistent_upm():
    from fontbakery.specifications.adobe_fonts import (
        com_adobe_fonts_check_consistent_upm as check)

    base_path = 'data/test/source-sans-pro/OTF/'

    # these fonts have a consistent unitsPerEm of 1000:
    font_names = ['SourceSansPro-Regular.otf',
                  'SourceSansPro-Bold.otf',
                  'SourceSansPro-It.otf']

    font_paths = [base_path + n for n in font_names]

    test_fonts = [TTFont(x) for x in font_paths]

    # try fonts with consistent UPM (i.e. 1000)
    status, message = list(check(test_fonts))[-1]
    assert status == PASS

    # now try with one font with a different UPM (i.e. 2048)
    test_fonts[1]['head'].unitsPerEm = 2048
    status, message = list(check(test_fonts))[-1]
    assert status == FAIL

def test_get_family_checks():
    from fontbakery.specifications.adobe_fonts import specification
    family_checks = specification.get_family_checks()
    family_check_ids = {check.id for check in family_checks}
    expected_family_check_ids = {
        'com.adobe.fonts/check/consistent_upm',
        'com.adobe.fonts/check/max_4_fonts_per_family_name',
        'com.google.fonts/check/008',
        'com.google.fonts/check/009',
        'com.google.fonts/check/010',
        'com.google.fonts/check/013',
        'com.google.fonts/check/014',
        'com.google.fonts/check/040'
    }
    assert family_check_ids == expected_family_check_ids
<commit_msg>added bold_italic_unique_for_nameid1 to expected_family_check_ids<commit_after>from fontbakery.checkrunner import (PASS, FAIL)
from fontTools.ttLib import TTFont

def test_check_name_empty_records():
    from fontbakery.specifications.adobe_fonts import (
        com_adobe_fonts_check_name_empty_records as check)
    font_path = "data/test/source-sans-pro/OTF/SourceSansPro-Regular.otf"
    test_font = TTFont(font_path)

    # try a font with fully populated name records
    status, message = list(check(test_font))[-1]
    assert status == PASS

    # now try a completely empty string
    test_font['name'].names[3].string = b''
    status, message = list(check(test_font))[-1]
    assert status == FAIL

    # now try a string that only has whitespace
    test_font['name'].names[3].string = b' '
    status, message = list(check(test_font))[-1]
    assert status == FAIL

def test_check_consistent_upm():
    from fontbakery.specifications.adobe_fonts import (
        com_adobe_fonts_check_consistent_upm as check)

    base_path = 'data/test/source-sans-pro/OTF/'

    # these fonts have a consistent unitsPerEm of 1000:
    font_names = ['SourceSansPro-Regular.otf',
                  'SourceSansPro-Bold.otf',
                  'SourceSansPro-It.otf']

    font_paths = [base_path + n for n in font_names]

    test_fonts = [TTFont(x) for x in font_paths]

    # try fonts with consistent UPM (i.e. 1000)
    status, message = list(check(test_fonts))[-1]
    assert status == PASS

    # now try with one font with a different UPM (i.e. 2048)
    test_fonts[1]['head'].unitsPerEm = 2048
    status, message = list(check(test_fonts))[-1]
    assert status == FAIL

def test_get_family_checks():
    from fontbakery.specifications.adobe_fonts import specification
    family_checks = specification.get_family_checks()
    family_check_ids = {check.id for check in family_checks}
    expected_family_check_ids = {
        'com.adobe.fonts/check/bold_italic_unique_for_nameid1',
        'com.adobe.fonts/check/consistent_upm',
        'com.adobe.fonts/check/max_4_fonts_per_family_name',
        'com.google.fonts/check/008',
        'com.google.fonts/check/009',
        'com.google.fonts/check/010',
        'com.google.fonts/check/013',
        'com.google.fonts/check/014',
        'com.google.fonts/check/040'
    }
    assert family_check_ids == expected_family_check_ids
<|endoftext|>


<commit_before>#!/usr/bin/env python
import sys, re, operator, string

#
# Auxiliary functions that can't be lambdas
#
def extract_words(obj, path_to_file):
    with open(path_to_file) as f:
        obj['data'] = f.read()
    pattern = re.compile('[\W_]+')
    data_str = ''.join(pattern.sub(' ', obj['data']).lower())
    obj['data'] = data_str.split()

def load_stop_words(obj):
    with open('../stop_words.txt') as f:
        obj['stop_words'] = f.read().split(',')
    # add single-letter words
    obj['stop_words'].extend(list(string.ascii_lowercase))

def increment_count(obj, w):
    obj['freqs'][w] = 1 if w not in obj['freqs'] else obj['freqs'][w]+1

data_storage_obj = {
    'data' : [],
    'init' : lambda obj, path_to_file : extract_words(obj, path_to_file),
    'words' : lambda obj : obj['data']
}

stop_words_obj = {
    'stop_words' : [],
    'init' : lambda obj : load_stop_words(obj),
    'is_stop_word' : lambda obj, word : word in obj['stop_words']
}

word_freqs_obj = {
    'freqs' : {},
    'increment_count' : lambda obj, w : increment_count(obj, w),
    'sorted' : lambda obj : sorted(obj['freqs'].iteritems(), key=operator.itemgetter(1), reverse=True)
}

data_storage_obj['init'](data_storage_obj, sys.argv[1])
stop_words_obj['init'](stop_words_obj)

for w in data_storage_obj['words'](data_storage_obj):
    if not stop_words_obj['is_stop_word'](stop_words_obj, w):
        word_freqs_obj['increment_count'](word_freqs_obj, w)

word_freqs = word_freqs_obj['sorted'](word_freqs_obj)
for (w, c) in word_freqs[0:25]:
    print w, ' - ', c
<commit_msg>Don't need that first argument. Can be enclosed internally to the maps<commit_after>#!/usr/bin/env python
import sys, re, operator, string

#
# Auxiliary functions that can't be lambdas
#
def extract_words(obj, path_to_file):
    with open(path_to_file) as f:
        obj['data'] = f.read()
    pattern = re.compile('[\W_]+')
    data_str = ''.join(pattern.sub(' ', obj['data']).lower())
    obj['data'] = data_str.split()

def load_stop_words(obj):
    with open('../stop_words.txt') as f:
        obj['stop_words'] = f.read().split(',')
    # add single-letter words
    obj['stop_words'].extend(list(string.ascii_lowercase))

def increment_count(obj, w):
    obj['freqs'][w] = 1 if w not in obj['freqs'] else obj['freqs'][w]+1

data_storage_obj = {
    'data' : [],
    'init' : lambda path_to_file : extract_words(data_storage_obj, path_to_file),
    'words' : lambda : data_storage_obj['data']
}

stop_words_obj = {
    'stop_words' : [],
    'init' : lambda : load_stop_words(stop_words_obj),
    'is_stop_word' : lambda word : word in stop_words_obj['stop_words']
}

word_freqs_obj = {
    'freqs' : {},
    'increment_count' : lambda w : increment_count(word_freqs_obj, w),
    'sorted' : lambda : sorted(word_freqs_obj['freqs'].iteritems(), key=operator.itemgetter(1), reverse=True)
}

data_storage_obj['init'](sys.argv[1])
stop_words_obj['init']()

for w in data_storage_obj['words']():
    if not stop_words_obj['is_stop_word'](w):
        word_freqs_obj['increment_count'](w)

word_freqs = word_freqs_obj['sorted']()
for (w, c) in word_freqs[0:25]:
    print w, ' - ', c
<|endoftext|>


<commit_before>from sqlalchemy import func, and_, or_
from datetime import datetime
from flask import Blueprint, request, make_response, render_template, flash, g, session, redirect, url_for, jsonify, abort, current_app
from flask.ext.babel import gettext
from dataviva import db

from dataviva.attrs.models import Bra, Wld
from dataviva.rais.models import Isic, Cbo
from dataviva.secex.models import Hs

from dataviva.ask.models import Question, Reply, Status, Vote, TYPE_QUESTION, TYPE_REPLY, Flag
from dataviva.ask.forms import AskForm, ReplyForm, SearchForm
from dataviva.utils import strip_html

from dataviva.utils import send_mail
from config import ADMINISTRATOR_EMAIL

mod = Blueprint('about', __name__, url_prefix='/about')

@mod.before_request
def before_request():
    g.page_type = mod.name
    g.color = "#d67ab0"

@mod.route('/analysis/')
def analysis():
    return render_template("about/analysis.html", page = "analysis")

@mod.route('/testimonial/')
def testimonial():
    return render_template("about/testimonial.html", page = "testimonial")

@mod.route('/data/<data>/')
def data(data):
    return render_template("about/data/index.html", data=data, page = "data")

@mod.route('/glossary/<term>/')
def glossary(term):
    return render_template("about/glossary/index.html", term=term, page = "glossary")

@mod.route('/apps/<app>/')
def apps(app):
    return render_template("about/apps/index.html", app=app, page = "apps")

@mod.route('/classification/<attr>/<depth>/')
def attrs(attr="bra",depth="2"):

    data_url = "/attrs/table/{0}/{1}/".format(attr,depth)

    depths = {}
    depths["bra"] = [2,4,7,8]
    depths["isic"] = [1,3,5]
    depths["cbo"] = [1,2,4]
    depths["hs"] = [2,4,6]
    depths["wld"] = [2,5]

    return render_template("about/attrs.html", data_url=data_url, depths = depths[attr], page = "attrs", attr = attr, depth = int(depth))

@mod.route('/')
@mod.route('/contact/')
def contact():
    search_form = SearchForm()
    return render_template("about/ask/index.html", page = "ask", search_form = search_form)

@mod.route('/ask/', methods=['GET', 'POST'])
@mod.route('/ask/<user>/', methods=['GET', 'POST'])
def ask(user=None):
    form = AskForm()
    if request.method == 'POST':

        if g.user is None or not g.user.is_authenticated():
            flash(gettext('You need to be logged in to ask questions.'))
            return redirect(url_for('account.login'))

        if form.validate_on_submit():
            timestamp = datetime.utcnow()
            slug = Question.make_unique_slug(form.question.data)

            from ..utils import ProfanitiesFilter

            file_banned_words = open("dataviva/static/txt/blacklist.txt")
            banned_words = [line.strip() for line in file_banned_words]

            filter = ProfanitiesFilter(banned_words, replacements = '*')

            _question = filter.clean(str(form.question.data))
            _body =  filter.clean(str(form.body.data))

            question = Question(question=_question, body=_body, timestamp=timestamp, user=g.user, slug=slug, language=g.locale)
            if "," in form.tags.data:
                tags = form.tags.data.split(",")
                question.str_tags(tags)
            db.session.add(question)
            db.session.commit()
            flash(gettext('Your message was sent successfully! Soon our team will contact you by e-mail. Thanks for your contribution, it is essential to help other users and to improve our tool!'))
            # if user and request.remote_addr == SITE_MIRROR.split(":")[1][2:]:
            #     return jsonify({"status": "Success"})
            # else:
            return redirect(url_for('about.contact'))
        else:
            return render_template("about/ask/ask.html", page = "ask", form = form)

    return render_template("about/ask/ask.html", page = "ask", form = form)

@mod.route('/question/<slug>/', methods=['GET', 'POST'])
def answer(slug):

    reply_form = ReplyForm()
    question = Question.query.filter_by(slug=slug).first_or_404()
    if request.method == 'POST':

        # if request.remote_addr == SITE_MIRROR.split(":")[1][2:]:
        #     g.user = User.query.get(request.form["user"])
        if g.user is None or not g.user.is_authenticated():
            flash(gettext('You need to be signed in to reply to questions.'))
            return redirect(url_for('about.answer', slug=question.slug))

        # if "user" not in request.form:
        #     form_json = {"user": g.user.id, "reply": reply_form.reply.data, "parent": reply_form.parent.data}
        #     try:
        #         opener = urllib2.urlopen("{0}{1}".format(SITE_MIRROR,request.path[1:]),urllib.urlencode(form_json),5)
        #     except:
        #         flash(gettext("The server is not responding. Please try again later."))
        #         return redirect(url_for('.answer', slug=question.slug))

        timestamp = datetime.utcnow()
        if not reply_form.parent.data:
            parent_id = 0

        reply = Reply(body=reply_form.reply.data, timestamp=timestamp,
                        user=g.user, question=question, parent_id=parent_id)
        db.session.add(reply)
        db.session.commit()
        if not reply_form.parent.data:
            reply.parent_id = reply.id
            db.session.add(reply)
            db.session.commit()
        flash(gettext('Reply submitted.'))

        #envia email para o admin
        send_mail('Aviso de nova publicacao no DataViva', [ADMINISTRATOR_EMAIL], render_template('about/ask/ask_feedback.html', question=question))

        return redirect(url_for('about.answer', slug=question.slug))
    else:

        question.vote = False
        if g.user.is_authenticated():
            vote = Vote.query.filter_by(type = 0, type_id = question.id, user_id = g.user.id).first()
            if vote:
                question.vote = True

        return render_template("about/ask/answer.html",
            reply_form = reply_form,
            question = question, page = "ask")

@mod.route('/terms_of_use', methods=['GET'])
def terms_of_use():
    return render_template("about/terms_of_use.html", page='terms_of_use')<commit_msg>question type was not getting submitted with question<commit_after>from sqlalchemy import func, and_, or_
from datetime import datetime
from flask import Blueprint, request, make_response, render_template, flash, g, session, redirect, url_for, jsonify, abort, current_app
from flask.ext.babel import gettext
from dataviva import db

from dataviva.attrs.models import Bra, Wld
from dataviva.rais.models import Isic, Cbo
from dataviva.secex.models import Hs

from dataviva.ask.models import Question, Reply, Status, Vote, TYPE_QUESTION, TYPE_REPLY, Flag
from dataviva.ask.forms import AskForm, ReplyForm, SearchForm
from dataviva.utils import strip_html

from dataviva.utils import send_mail
from config import ADMINISTRATOR_EMAIL

mod = Blueprint('about', __name__, url_prefix='/about')

@mod.before_request
def before_request():
    g.page_type = mod.name
    g.color = "#d67ab0"

@mod.route('/analysis/')
def analysis():
    return render_template("about/analysis.html", page = "analysis")

@mod.route('/testimonial/')
def testimonial():
    return render_template("about/testimonial.html", page = "testimonial")

@mod.route('/data/<data>/')
def data(data):
    return render_template("about/data/index.html", data=data, page = "data")

@mod.route('/glossary/<term>/')
def glossary(term):
    return render_template("about/glossary/index.html", term=term, page = "glossary")

@mod.route('/apps/<app>/')
def apps(app):
    return render_template("about/apps/index.html", app=app, page = "apps")

@mod.route('/classification/<attr>/<depth>/')
def attrs(attr="bra",depth="2"):

    data_url = "/attrs/table/{0}/{1}/".format(attr,depth)

    depths = {}
    depths["bra"] = [2,4,7,8]
    depths["isic"] = [1,3,5]
    depths["cbo"] = [1,2,4]
    depths["hs"] = [2,4,6]
    depths["wld"] = [2,5]

    return render_template("about/attrs.html", data_url=data_url, depths = depths[attr], page = "attrs", attr = attr, depth = int(depth))

@mod.route('/')
@mod.route('/contact/')
def contact():
    search_form = SearchForm()
    return render_template("about/ask/index.html", page = "ask", search_form = search_form)

@mod.route('/ask/', methods=['GET', 'POST'])
@mod.route('/ask/<user>/', methods=['GET', 'POST'])
def ask(user=None):
    form = AskForm()
    if request.method == 'POST':

        if g.user is None or not g.user.is_authenticated():
            flash(gettext('You need to be logged in to ask questions.'))
            return redirect(url_for('account.login'))

        if form.validate_on_submit():
            timestamp = datetime.utcnow()
            slug = Question.make_unique_slug(form.question.data)

            from ..utils import ProfanitiesFilter

            file_banned_words = open("dataviva/static/txt/blacklist.txt")
            banned_words = [line.strip() for line in file_banned_words]

            filter = ProfanitiesFilter(banned_words, replacements = '*')

            _question = filter.clean(str(form.question.data))
            _body =  filter.clean(str(form.body.data))
            _type = filter.clean(str(form.type.data))

            question = Question(question=_question, body=_body, timestamp=timestamp, user=g.user, slug=slug, language=g.locale, type_id=_type)
            if "," in form.tags.data:
                tags = form.tags.data.split(",")
                question.str_tags(tags)
            db.session.add(question)
            db.session.commit()
            flash(gettext('Your message was sent successfully. Thank you for your contribution, it will be helpful to other users and is essential to improving our tool! Our team will contact you by e-mail shortly.'))
            # if user and request.remote_addr == SITE_MIRROR.split(":")[1][2:]:
            #     return jsonify({"status": "Success"})
            # else:
            return redirect(url_for('about.contact'))
        else:
            return render_template("about/ask/ask.html", page = "ask", form = form)

    return render_template("about/ask/ask.html", page = "ask", form = form)

@mod.route('/question/<slug>/', methods=['GET', 'POST'])
def answer(slug):

    reply_form = ReplyForm()
    question = Question.query.filter_by(slug=slug).first_or_404()
    if request.method == 'POST':

        # if request.remote_addr == SITE_MIRROR.split(":")[1][2:]:
        #     g.user = User.query.get(request.form["user"])
        if g.user is None or not g.user.is_authenticated():
            flash(gettext('You need to be signed in to reply to questions.'))
            return redirect(url_for('about.answer', slug=question.slug))

        # if "user" not in request.form:
        #     form_json = {"user": g.user.id, "reply": reply_form.reply.data, "parent": reply_form.parent.data}
        #     try:
        #         opener = urllib2.urlopen("{0}{1}".format(SITE_MIRROR,request.path[1:]),urllib.urlencode(form_json),5)
        #     except:
        #         flash(gettext("The server is not responding. Please try again later."))
        #         return redirect(url_for('.answer', slug=question.slug))

        timestamp = datetime.utcnow()
        if not reply_form.parent.data:
            parent_id = 0

        reply = Reply(body=reply_form.reply.data, timestamp=timestamp,
                        user=g.user, question=question, parent_id=parent_id)
        db.session.add(reply)
        db.session.commit()
        if not reply_form.parent.data:
            reply.parent_id = reply.id
            db.session.add(reply)
            db.session.commit()
        flash(gettext('Reply submitted.'))

        #envia email para o admin
        send_mail('Aviso de nova publicacao no DataViva', [ADMINISTRATOR_EMAIL], render_template('about/ask/ask_feedback.html', question=question))

        return redirect(url_for('about.answer', slug=question.slug))
    else:

        question.vote = False
        if g.user.is_authenticated():
            vote = Vote.query.filter_by(type = 0, type_id = question.id, user_id = g.user.id).first()
            if vote:
                question.vote = True

        return render_template("about/ask/answer.html",
            reply_form = reply_form,
            question = question, page = "ask")

@mod.route('/terms_of_use', methods=['GET'])
def terms_of_use():
    return render_template("about/terms_of_use.html", page='terms_of_use')<|endoftext|>


<commit_before>import numpy

from chainer import cuda
from chainer.functions.connection import deconvolution_2d
from chainer import initializers
from chainer import link
from chainer.utils import argument
from chainer import variable

class Deconvolution2D(link.Link):

    """__init__(self, in_channels, out_channels, ksize=None, stride=1, pad=0, nobias=False, outsize=None, initialW=None, initial_bias=None)

    Two dimensional deconvolution function.

    This link wraps the :func:`~chainer.functions.deconvolution_2d` function
    and holds the filter weight and bias vector as parameters.

    .. warning::

        ``deterministic`` argument is not supported anymore since v2.
        Instead, use ``chainer.using_config('cudnn_deterministic', value)``
        (value is either ``True`` or ``False``).
        See :func:`chainer.using_config`.

    Args:
        in_channels (int or None): Number of channels of input arrays.
            If ``None``, parameter initialization will be deferred until the
            first forward data pass at which time the size will be determined.
        out_channels (int): Number of channels of output arrays.
        ksize (int or pair of ints): Size of filters (a.k.a. kernels).
            ``ksize=k`` and ``ksize=(k, k)`` are equivalent.
        stride (int or pair of ints): Stride of filter applications.
            ``stride=s`` and ``stride=(s, s)`` are equivalent.
        pad (int or pair of ints): Spatial padding width for input arrays.
            ``pad=p`` and ``pad=(p, p)`` are equivalent.
        nobias (bool): If ``True``, then this function does not use the bias
            term.
        outsize (tuple): Expected output size of deconvolutional operation.
            It should be pair of height and width :math:`(out_H, out_W)`.
            Default value is ``None`` and the outsize is estimated by
            input size, stride and pad.
        initialW (4-D array): Initial weight value. If ``None``, the default
            initializer is used.
            May also be a callable that takes ``numpy.ndarray`` or
            ``cupy.ndarray`` and edits its value.
        initial_bias (1-D array): Initial bias value. If ``None``, the bias
            vector is set to zero.
            May also be a callable that takes ``numpy.ndarray`` or
            ``cupy.ndarray`` and edits its value.

    The filter weight has four dimensions :math:`(c_I, c_O, k_H, k_W)`
    which indicate the number of input channels, output channels,
    height and width of the kernels, respectively.
    The filter weight is initialized with i.i.d. Gaussian random samples, each
    of which has zero mean and deviation :math:`\\sqrt{1/(c_I k_H k_W)}` by
    default.

    The bias vector is of size :math:`c_O`.
    Its elements are initialized by ``bias`` argument.
    If ``nobias`` argument is set to True, then this function does not hold
    the bias parameter.

    The output of this function can be non-deterministic when it uses cuDNN.
    If ``chainer.configuration.config.cudnn_deterministic`` is ``True`` and
    cuDNN version is >= v3, it forces cuDNN to use a deterministic algorithm.

    .. seealso::
       See :func:`chainer.functions.deconvolution_2d` for the definition of
       two-dimensional convolution.

    .. seealso::
        See :func:`chainer.links.Convolution2D` for the examples of ways to
        give arguments to this link.

    .. admonition:: Example

        There are several ways to make a Deconvolution2D link.

        Let an input vector ``x`` be:

        >>> x = np.arange(1 * 3 * 10 * 10, dtype='f').reshape(1, 3, 10, 10)

        1. Give the first three arguments explicitly:

            In this case, all the other arguments are set to the default
            values.

            >>> l = L.Deconvolution2D(3, 7, 4)
            >>> y = l(x)
            >>> y.shape
            (1, 7, 13, 13)

        2. Omit ``in_channels`` or fill it with ``None``:

            The below two cases are the same.

            >>> l = L.Deconvolution2D(7, 4)
            >>> y = l(x)
            >>> y.shape
            (1, 7, 13, 13)

            >>> l = L.Deconvolution2D(None, 7, 4)
            >>> y = l(x)
            >>> y.shape
            (1, 7, 13, 13)

            When you omit the first argument, you need to specify the other
            subsequent arguments from ``stride`` as keyword arguments. So the
            below two cases are the same.

            >>> l = L.Deconvolution2D(None, 7, 4, 2, 1)
            >>> y = l(x)
            >>> y.shape
            (1, 7, 20, 20)

            >>> l = L.Deconvolution2D(7, 4, stride=2, pad=1)
            >>> y = l(x)
            >>> y.shape
            (1, 7, 20, 20)

    """  # NOQA

    def __init__(self, in_channels, out_channels, ksize=None, stride=1, pad=0,
                 nobias=False, outsize=None, initialW=None, initial_bias=None,
                 **kwargs):
        super(Deconvolution2D, self).__init__()

        argument.check_unexpected_kwargs(
            kwargs, deterministic="deterministic argument is not "
            "supported anymore. "
            "Use chainer.using_config('cudnn_deterministic', value) "
            "context where value is either `True` or `False`.")
        argument.assert_kwargs_empty(kwargs)

        if ksize is None:
            out_channels, ksize, in_channels = in_channels, out_channels, None

        self.ksize = ksize
        self.stride = _pair(stride)
        self.pad = _pair(pad)
        self.outsize = (None, None) if outsize is None else outsize
        self.out_channels = out_channels

        with self.init_scope():
            W_initializer = initializers._get_initializer(initialW)
            self.W = variable.Parameter(W_initializer)
            if in_channels is not None:
                self._initialize_params(in_channels)

            if nobias:
                self.b = None
            else:
                if isinstance(initial_bias, (numpy.ndarray, cuda.ndarray)):
                    assert initial_bias.shape == (out_channels,)
                if initial_bias is None:
                    initial_bias = 0
                bias_initializer = initializers._get_initializer(initial_bias)
                self.b = variable.Parameter(bias_initializer, out_channels)

    def _initialize_params(self, in_channels):
        kh, kw = _pair(self.ksize)
        W_shape = (in_channels, self.out_channels, kh, kw)
        self.W.initialize(W_shape)

    def __call__(self, x):
        if self.W.data is None:
            self._initialize_params(x.shape[1])
        return deconvolution_2d.deconvolution_2d(
            x, self.W, self.b, self.stride, self.pad, self.outsize)

def _pair(x):
    if hasattr(x, '__getitem__'):
        return x
    return x, x
<commit_msg>Add an argument group to Deconvolution2D<commit_after>import numpy

from chainer import cuda
from chainer.functions.connection import deconvolution_2d
from chainer import initializers
from chainer import link
from chainer.utils import argument
from chainer import variable

class Deconvolution2D(link.Link):

    """__init__(self, in_channels, out_channels, ksize=None, stride=1, pad=0, nobias=False, outsize=None, initialW=None, initial_bias=None)

    Two dimensional deconvolution function.

    This link wraps the :func:`~chainer.functions.deconvolution_2d` function
    and holds the filter weight and bias vector as parameters.

    .. warning::

        ``deterministic`` argument is not supported anymore since v2.
        Instead, use ``chainer.using_config('cudnn_deterministic', value)``
        (value is either ``True`` or ``False``).
        See :func:`chainer.using_config`.

    Args:
        in_channels (int or None): Number of channels of input arrays.
            If ``None``, parameter initialization will be deferred until the
            first forward data pass at which time the size will be determined.
        out_channels (int): Number of channels of output arrays.
        ksize (int or pair of ints): Size of filters (a.k.a. kernels).
            ``ksize=k`` and ``ksize=(k, k)`` are equivalent.
        stride (int or pair of ints): Stride of filter applications.
            ``stride=s`` and ``stride=(s, s)`` are equivalent.
        pad (int or pair of ints): Spatial padding width for input arrays.
            ``pad=p`` and ``pad=(p, p)`` are equivalent.
        nobias (bool): If ``True``, then this function does not use the bias
            term.
        outsize (tuple): Expected output size of deconvolutional operation.
            It should be pair of height and width :math:`(out_H, out_W)`.
            Default value is ``None`` and the outsize is estimated by
            input size, stride and pad.
        initialW (4-D array): Initial weight value. If ``None``, the default
            initializer is used.
            May also be a callable that takes ``numpy.ndarray`` or
            ``cupy.ndarray`` and edits its value.
        initial_bias (1-D array): Initial bias value. If ``None``, the bias
            vector is set to zero.
            May also be a callable that takes ``numpy.ndarray`` or
            ``cupy.ndarray`` and edits its value.

    The filter weight has four dimensions :math:`(c_I, c_O, k_H, k_W)`
    which indicate the number of input channels, output channels,
    height and width of the kernels, respectively.
    The filter weight is initialized with i.i.d. Gaussian random samples, each
    of which has zero mean and deviation :math:`\\sqrt{1/(c_I k_H k_W)}` by
    default.

    The bias vector is of size :math:`c_O`.
    Its elements are initialized by ``bias`` argument.
    If ``nobias`` argument is set to True, then this function does not hold
    the bias parameter.

    The output of this function can be non-deterministic when it uses cuDNN.
    If ``chainer.configuration.config.cudnn_deterministic`` is ``True`` and
    cuDNN version is >= v3, it forces cuDNN to use a deterministic algorithm.

    .. seealso::
       See :func:`chainer.functions.deconvolution_2d` for the definition of
       two-dimensional convolution.

    .. seealso::
        See :func:`chainer.links.Convolution2D` for the examples of ways to
        give arguments to this link.

    .. admonition:: Example

        There are several ways to make a Deconvolution2D link.

        Let an input vector ``x`` be:

        >>> x = np.arange(1 * 3 * 10 * 10, dtype='f').reshape(1, 3, 10, 10)

        1. Give the first three arguments explicitly:

            In this case, all the other arguments are set to the default
            values.

            >>> l = L.Deconvolution2D(3, 7, 4)
            >>> y = l(x)
            >>> y.shape
            (1, 7, 13, 13)

        2. Omit ``in_channels`` or fill it with ``None``:

            The below two cases are the same.

            >>> l = L.Deconvolution2D(7, 4)
            >>> y = l(x)
            >>> y.shape
            (1, 7, 13, 13)

            >>> l = L.Deconvolution2D(None, 7, 4)
            >>> y = l(x)
            >>> y.shape
            (1, 7, 13, 13)

            When you omit the first argument, you need to specify the other
            subsequent arguments from ``stride`` as keyword arguments. So the
            below two cases are the same.

            >>> l = L.Deconvolution2D(None, 7, 4, 2, 1)
            >>> y = l(x)
            >>> y.shape
            (1, 7, 20, 20)

            >>> l = L.Deconvolution2D(7, 4, stride=2, pad=1)
            >>> y = l(x)
            >>> y.shape
            (1, 7, 20, 20)

    """  # NOQA

    def __init__(self, in_channels, out_channels, ksize=None, stride=1, pad=0,
                 nobias=False, outsize=None, initialW=None, initial_bias=None,
                 **kwargs):
        super(Deconvolution2D, self).__init__()

        argument.check_unexpected_kwargs(
            kwargs, deterministic="deterministic argument is not "
            "supported anymore. "
            "Use chainer.using_config('cudnn_deterministic', value) "
            "context where value is either `True` or `False`.")
        group, = argument.parse_kwargs(kwargs, ('group', 1))

        if ksize is None:
            out_channels, ksize, in_channels = in_channels, out_channels, None

        self.ksize = ksize
        self.stride = _pair(stride)
        self.pad = _pair(pad)
        self.outsize = (None, None) if outsize is None else outsize
        self.out_channels = out_channels
        self.group = int(group)

        with self.init_scope():
            W_initializer = initializers._get_initializer(initialW)
            self.W = variable.Parameter(W_initializer)
            if in_channels is not None:
                self._initialize_params(in_channels)

            if nobias:
                self.b = None
            else:
                if isinstance(initial_bias, (numpy.ndarray, cuda.ndarray)):
                    assert initial_bias.shape == (out_channels,)
                if initial_bias is None:
                    initial_bias = 0
                bias_initializer = initializers._get_initializer(initial_bias)
                self.b = variable.Parameter(bias_initializer, out_channels)

    def _initialize_params(self, in_channels):
        kh, kw = _pair(self.ksize)
        if (self.out_channels % self.group != 0 or
                in_channels % self.group != 0):
            raise ValueError('number of input and output channels must be'
                             'divisible by group count')
        W_shape = (in_channels, int(self.out_channels / self.group), kh, kw)
        self.W.initialize(W_shape)

    def __call__(self, x):
        if self.W.data is None:
            self._initialize_params(x.shape[1])
        return deconvolution_2d.deconvolution_2d(
            x, self.W, self.b, self.stride, self.pad, self.outsize,
            group=self.group)

def _pair(x):
    if hasattr(x, '__getitem__'):
        return x
    return x, x
<|endoftext|>


<commit_before>
# Should be moved to surpervisor.py
def draw_board(board):
    s = ''
    for i in range(0,64,8):
        s += board[i:i+8]
        s += '\n'
    print s

def get_opponent(p):
    if p in 'Rr':
        return 'b'
    elif p in 'Bb':
        return 'r'
    else:
        raise

def is_king(char):
    return not char.islower()

def initialize():
    """
    Initial board state.
    """

    rx = ' r r r rr r r r  r r r r'
    bx = 'b b b b  b b b bb b b b'

    return rx + ' ' * 16 + bx

def moves(position, direction):
    """
    All potential non-capture moves (1 diagonal square away); no collision detection
    """

    if position % 8 == 0:
        moves = [position + 9, position - 7]
    elif position % 8 == 7:
        moves = [position + 7, position - 9]
    else:
        moves = [position + 7, position + 9, position - 7, position - 9]

    moves = [e for e in moves if 0 <= e <= 63]

    if direction == 1:
        return [e for e in moves if e > position]
    elif direction == -1:
        return [e for e in moves if e < position]
    else:
        return moves

def capture_moves(position, direction):
    """
    All potential capture moves (i.e. moves two diagonal squares away; no collision detection
    """

    if position % 8 in (0,1):
        moves = [position + 18, position - 14]
    elif position % 8 in (6,7):
        moves = [position - 18, position + 14]
    else:
        moves = [position + 14, position + 18, position - 14, position - 18]

    moves = [e for e in moves if 0 <= e <= 63]

    if direction == 1:
        return [e for e in moves if e > position]
    elif direction == -1:
        return [e for e in moves if e < position]
    else:
        return moves

def valid_capture_moves(player, board, direction=None):
    """
    Capture moves that will actually result in a capture.
    """

    opponent = get_opponent(player)
    positions = [i for i, char in enumerate(board) if char == player]

    captures = []

    for position in positions:
        potential_captures = capture_moves(position, direction)
        for end_p in potential_captures:
            jumped_p = (position + end_p) / 2
            if board[end_p] == ' ' and board[jumped_p] == opponent:
                t = (position, end_p)
                captures.append(t)

    return captures

def move_legal(move, board):
    start_position, end_position = move
    start_cell = board[start_position]
    end_cell = board[end_position]

    if start_cell == ' ':
        return False

    if end_cell != ' ':
        return False

    player = start_cell.lower()

    if is_king(start_cell):
        direction = None
    elif start_cell == 'r':
        direction = 1
    elif start_cell == 'b':
        direction = 1

    # Check for forced jumps.
    valid_captures = valid_capture_moves(player, board, direction)
    if valid_captures and move not in valid_captures:
        return False

    if end_position in legal_moves(start_position, direction):
        return True

    if end_position in capture_moves(start_position, direction):
        in_between_cell = (end_position + start_position) / 2
        between_cell = board[in_between_cell]
        if between_cell == opponent(start_cell):
            return True

    return False

def transition(move, board):
    start_p, end_p = move
    distance = abs(start_p - end_p)

    board_list = list(board)
    board_list[start_p], board_list[end_p] = board[end_p], board[start_p]

    if distance > 9:
        in_between = (start_p + end_p) / 2
        board_list[in_between] = ' '

    return ''.join(board_list)

    return board

def winner(board):
    if 'r' not in board:
        return 'b'
    elif 'b' not in board:
        return 'r'
    else:
        return None

if __name__ == "__main__":
    #print initialize()
    board = initialize()
    draw_board(board)
    print valid_capture_moves('r', board)
    board2 = transition((21, 28), board)
    board3 = transition((46, 37), board2)
    print valid_capture_moves('r', board3)

    #board3 = transition((46, 53), board2)
    draw_board(board3)

<commit_msg>wrote some unit tests<commit_after>
# Should be moved to surpervisor.py
def draw_board(board):
    s = ''
    for i in range(0,64,8):
        s += board[i:i+8]
        s += '\n'
    print s

def get_opponent(p):
    """
    Returns char symbol for opponent.

    >>> get_opponent('R')
    'b'
    >>> get_opponent('b')
    'r'
    >>> get_opponent('ew')
    """

    if p in 'Rr':
        return 'b'
    elif p in 'Bb':
        return 'r'
    else:
        return None

def is_king(char):
    """
    >>> is_king('r')
    False
    >>> is_king('B')
    True
    """
    return not char.islower()

def initialize():
    """
    Initial board state.

    >>> initialize()[23]
    'r'
    >>> initialize()[28]
    ' '
    >>> initialize()[62]
    'b'
    """

    rx = ' r r r rr r r r  r r r r'
    bx = 'b b b b  b b b bb b b b'

    return rx + ' ' * 16 + bx

def moves(position, direction):
    """
    All potential non-capture moves (1 diagonal square away); no collision detection

    >>> sorted(moves(28, None))
    [19, 21, 35, 37]
    >>> sorted(moves(31, None))
    [22, 38]
    >>> sorted(moves(63, 1))
    []
    >>> sorted(moves(63, -1))
    [54]
    """

    if position % 8 == 0:
        moves = [position + 9, position - 7]
    elif position % 8 == 7:
        moves = [position + 7, position - 9]
    else:
        moves = [position + 7, position + 9, position - 7, position - 9]

    moves = [e for e in moves if 0 <= e <= 63]

    if direction == 1:
        return [e for e in moves if e > position]
    elif direction == -1:
        return [e for e in moves if e < position]
    else:
        return moves

def capture_moves(position, direction):
    """
    All potential capture moves (i.e. moves two diagonal squares away; no collision detection

    >>> sorted(capture_moves(28, None))
    [10, 14, 42, 46]
    >>> sorted(capture_moves(31, None))
    [13, 45]
    >>> sorted(capture_moves(63, 1))
    []
    >>> sorted(capture_moves(63, -1))
    [45]
    """

    if position % 8 in (0,1):
        moves = [position + 18, position - 14]
    elif position % 8 in (6,7):
        moves = [position - 18, position + 14]
    else:
        moves = [position + 14, position + 18, position - 14, position - 18]

    moves = [e for e in moves if 0 <= e <= 63]

    if direction == 1:
        return [e for e in moves if e > position]
    elif direction == -1:
        return [e for e in moves if e < position]
    else:
        return moves

def valid_capture_moves(player, board, direction=None):
    """
    Capture moves that will actually result in a capture.

    >>> valid_capture_moves('r', 'r' + 8*' ' + 'b' + 54 * ' ', 1)
    [(0, 18)]
    >>> valid_capture_moves('r', 'r' + 8*' ' + 'b' + 54 * ' ', -1)
    []
    >>> valid_capture_moves('b', 'r' + 8*' ' + 'b' + 54 * ' ', -1)
    []
    """

    opponent = get_opponent(player)
    positions = [i for i, char in enumerate(board) if char == player]

    captures = []

    for position in positions:
        potential_captures = capture_moves(position, direction)
        for end_p in potential_captures:
            jumped_p = (position + end_p) / 2
            if board[end_p] == ' ' and board[jumped_p] == opponent:
                t = (position, end_p)
                captures.append(t)

    return captures

def move_legal(move, board):
    start_position, end_position = move
    start_cell = board[start_position]
    end_cell = board[end_position]

    if start_cell == ' ':
        return False

    if end_cell != ' ':
        return False

    player = start_cell.lower()

    if is_king(start_cell):
        direction = None
    elif start_cell == 'r':
        direction = 1
    elif start_cell == 'b':
        direction = 1

    # Check for forced jumps.
    valid_captures = valid_capture_moves(player, board, direction)
    if valid_captures and move not in valid_captures:
        return False

    if end_position in legal_moves(start_position, direction):
        return True

    if end_position in capture_moves(start_position, direction):
        in_between_cell = (end_position + start_position) / 2
        between_cell = board[in_between_cell]
        if between_cell == opponent(start_cell):
            return True

    return False

def transition(move, board):
    start_p, end_p = move
    distance = abs(start_p - end_p)

    board_list = list(board)
    board_list[start_p], board_list[end_p] = board[end_p], board[start_p]

    if distance > 9:
        in_between = (start_p + end_p) / 2
        board_list[in_between] = ' '

    return ''.join(board_list)

    return board

def winner(board):
    """
    >>> winner(64 * 'b')
    'b'
    >>> winner('r' + 64 * ' ')
    'r'
    """

    if 'r' not in board:
        return 'b'
    elif 'b' not in board:
        return 'r'
    else:
        return None

if __name__ == "__main__":

    # Run unit tests
    import doctest
    doctest.testmod()

#    #print initialize()
#    board = initialize()
#    draw_board(board)
#    print valid_capture_moves('r', board)
#    board2 = transition((21, 28), board)
#    board3 = transition((46, 37), board2)
#    print valid_capture_moves('r', board3)
#
#    #board3 = transition((46, 53), board2)
#    draw_board(board3)

<|endoftext|>


<commit_before>## Copyright 2013 Luc Saffre
## This file is part of the Lino-Faggio project.
## Lino-Faggio is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
## Lino-Faggio is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
## You should have received a copy of the GNU General Public License
## along with Lino-Faggio; if not, see <http://www.gnu.org/licenses/>.

"""
The :xfile:`models.py` for the :mod:`lino_faggio` app.

"""

from django.db import models
from django.db.models import loading
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import string_concat

from lino import dd
from lino import mixins
#~ from lino.models import SiteConfig

#~ from lino.modlib.contacts import models as contacts
#~ from lino.modlib.cal import models as cal

contacts = dd.resolve_app('contacts')
ledger = dd.resolve_app('ledger')
#~ cal = dd.resolve_app('cal')
courses = dd.resolve_app('courses')
products = dd.resolve_app('products')
notes = dd.resolve_app('notes')

#~ print 20130607, loading.cache.postponed

#~ notes.Note._meta.verbose_name = _("Note")
#~ notes.Note._meta.verbose_name_plural = _("Notes")

#~ from lino.modlib.cal import models as cal

#~ dd.inject_field('cal.Room','price',dd.PriceField(verbose_name=_("Price"),
    #~ blank=True,null=True,
    #~ default=0))

class PrintAndChangeStateAction(dd.ChangeStateAction):

    def run_from_ui(self,ar,**kw):
        obj = ar.selected_rows[0]

        def ok():
            # to avoid UnboundLocalError local variable 'kw' referenced before assignment
            kw2 = obj.do_print.run_from_ui(ar,**kw)
            kw2 = super(PrintAndChangeStateAction,self).run_from_ui(ar,**kw2)
            kw2.update(refresh_all=True)
            return kw2
        msg = self.get_confirmation_message(obj,ar)
        return ar.confirm(ok, msg, _("Are you sure?"))

class ConfirmEnrolment(PrintAndChangeStateAction):
    required = dd.required(states='requested')
    label = _("Confirm")

    def get_confirmation_message(self,obj,ar):
        return _("Confirm enrolment of %(pupil)s to %(course)s.") % dict(
            pupil=obj.pupil,course=obj.course)

class CertifyEnrolment(PrintAndChangeStateAction):
    required = dd.required(states='confirmed')
    label = _("Certify")
    #~ label = _("Award")
    #~ label = school.EnrolmentStates.award.text

    def get_confirmation_message(self,obj,ar):
        return _("Print certificate for %(pupil)s.") % dict(
            pupil=obj.pupil,course=obj.course)

@dd.receiver(dd.pre_analyze,dispatch_uid='faggio_setup_workflows')
def faggio_setup_workflows(sender,**kw):

    site = sender
    courses = dd.resolve_app('courses')

    #~ from lino.modlib.courses import models as courses
    #~ courses.EnrolmentStates.confirmed.add_transition(ConfirmEnrolment)
    courses.EnrolmentStates.confirmed.add_transition(_("Confirm"))
    courses.EnrolmentStates.certified.add_transition(CertifyEnrolment)
    #~ courses.EnrolmentStates.abandoned.add_transition()

@dd.when_prepared('partners.Person','partners.Organisation')
def hide_region(model):
    model.hide_elements('region')

@dd.when_prepared('partners.Person','partners.Organisation')
def add_merge_action(model):
    model.define_action(merge_row=dd.MergeAction(model))

def site_setup(site):
    site.modules.system.SiteConfigs.set_detail_layout(
        """
        site_company next_partner_id:10
        default_build_method
        clients_account   sales_account     sales_vat_account
        suppliers_account purchases_account purchases_vat_account
        pupil_guestrole
        """)

"""
The following trick worked but was rather hackerish.
Now we have :meth:`lino.modlib.vat.SiteMixin.get_item_vat`.
"""
if False:

    sales = dd.resolve_app('sales')

    @dd.receiver(dd.post_init, sender=sales.Invoice)
    def set_default_item_vat(sender, instance=None,**kwargs):
        instance.item_vat = True

<commit_msg>http://code.google.com/p/lino/source/browse/docs/blog/2013/0928.rst<commit_after>## Copyright 2013 Luc Saffre
## This file is part of the Lino-Faggio project.
## Lino-Faggio is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
## Lino-Faggio is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
## You should have received a copy of the GNU General Public License
## along with Lino-Faggio; if not, see <http://www.gnu.org/licenses/>.

"""
The :xfile:`models.py` for the :mod:`lino_faggio` app.

"""

from django.db import models
from django.db.models import loading
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import string_concat

from lino import dd
from lino import mixins
#~ from lino.models import SiteConfig

#~ from lino.modlib.contacts import models as contacts
#~ from lino.modlib.cal import models as cal

contacts = dd.resolve_app('contacts')
ledger = dd.resolve_app('ledger')
#~ cal = dd.resolve_app('cal')
courses = dd.resolve_app('courses')
products = dd.resolve_app('products')
notes = dd.resolve_app('notes')

#~ print 20130607, loading.cache.postponed

#~ notes.Note._meta.verbose_name = _("Note")
#~ notes.Note._meta.verbose_name_plural = _("Notes")

#~ from lino.modlib.cal import models as cal

#~ dd.inject_field('cal.Room','price',dd.PriceField(verbose_name=_("Price"),
    #~ blank=True,null=True,
    #~ default=0))

class PrintAndChangeStateAction(dd.ChangeStateAction):

    def run_from_ui(self,ar,**kw):
        obj = ar.selected_rows[0]

        def ok():
            # to avoid UnboundLocalError local variable 'kw' referenced before assignment
            kw2 = obj.do_print.run_from_ui(ar,**kw)
            kw2 = super(PrintAndChangeStateAction,self).run_from_ui(ar,**kw2)
            kw2.update(refresh_all=True)
            return kw2
        msg = self.get_confirmation_message(obj,ar)
        return ar.confirm(ok, msg, _("Are you sure?"))

class ConfirmEnrolment(PrintAndChangeStateAction):
    required = dd.required(states='requested')
    label = _("Confirm")

    def get_confirmation_message(self,obj,ar):
        return _("Confirm enrolment of %(pupil)s to %(course)s.") % dict(
            pupil=obj.pupil,course=obj.course)

class CertifyEnrolment(PrintAndChangeStateAction):
    required = dd.required(states='confirmed')
    label = _("Certify")
    #~ label = _("Award")
    #~ label = school.EnrolmentStates.award.text

    def get_confirmation_message(self,obj,ar):
        return _("Print certificate for %(pupil)s.") % dict(
            pupil=obj.pupil,course=obj.course)

@dd.receiver(dd.pre_analyze,dispatch_uid='faggio_setup_workflows')
def faggio_setup_workflows(sender,**kw):

    site = sender
    courses = dd.resolve_app('courses')

    #~ from lino.modlib.courses import models as courses
    #~ courses.EnrolmentStates.confirmed.add_transition(ConfirmEnrolment)
    courses.EnrolmentStates.confirmed.add_transition(_("Confirm"))
    courses.EnrolmentStates.certified.add_transition(CertifyEnrolment)
    #~ courses.EnrolmentStates.abandoned.add_transition()

@dd.when_prepared('partners.Person','partners.Organisation')
def hide_region(model):
    model.hide_elements('region')

@dd.when_prepared('partners.Person','partners.Organisation')
def add_merge_action(model):
    model.define_action(merge_row=dd.MergeAction(model))

def site_setup(site):
    site.modules.accounts.Accounts.set_detail_layout(
        """
        ref:10 name id:5
        seqno chart group type clearable
        ledger.MovementsByAccount ledger.DuePaymentsByAccount
        """)

    site.modules.system.SiteConfigs.set_detail_layout(
        """
        site_company next_partner_id:10
        default_build_method
        clients_account   sales_account     sales_vat_account
        suppliers_account purchases_account purchases_vat_account
        pupil_guestrole
        """)

"""
The following trick worked but was rather hackerish.
Now we have :meth:`lino.modlib.vat.SiteMixin.get_item_vat`.
"""
if False:

    sales = dd.resolve_app('sales')

    @dd.receiver(dd.post_init, sender=sales.Invoice)
    def set_default_item_vat(sender, instance=None,**kwargs):
        instance.item_vat = True

<|endoftext|>


<commit_before>"""
Misc cog.
"""
import asyncio
import time

import discord
from asyncio_extras import threadpool
from discord.ext import commands

from joku.bot import Context
from joku.checks import has_permissions
from joku.cogs._common import Cog

class Misc(Cog):
    @commands.command()
    async def ping(self, ctx: Context):
        """
        Pong.
        """
        before = time.monotonic()
        msg = await ctx.send(":ping_pong: Ping!")  # type: discord.Message
        after = time.monotonic()
        await msg.edit(content=":ping_pong: Ping! | {}ms".format(round((after - before) * 1000, 2)))

    @commands.command()
    async def cleanup(self, ctx: Context):
        """
        Cleans up bot messages in the last 100 messages.
        """
        channel = ctx.channel  # type: discord.TextChannel
        if channel.permissions_for(ctx.guild.me).manage_messages:
            count = len(await channel.purge(limit=100, check=lambda m: m.author == ctx.guild.me, before=ctx.message))
        else:
            count = 0
            async for message in channel.history(limit=100, before=ctx.message):
                if message.author == ctx.guild.me:
                    await message.delete()
                    count += 1

        m = await ctx.send(":heavy_check_mark: Cleaned up `{}` messages.".format(count))
        await asyncio.sleep(5)
        await m.delete()

    @commands.command()
    @has_permissions(manage_messages=True)
    async def redirect(self, ctx: Context, channel: discord.TextChannel, message: int):
        """
        Redirects a message to another channel.

        The message argument passed must be a message ID.
        To get a message ID you should right click on the on a message and then click "Copy ID". You must have Developer
        Mode enabled to get that functionality.
        """
        o_chan = ctx.channel  # type: discord.TextChannel
        try:
            msg = await o_chan.get_message(message)
        except discord.HTTPException:
            await ctx.send(":x: Could not find that message.")
            return

        # delete it and copy it to the target channel
        em = discord.Embed(title="Redirected by {}".format(ctx.author.name))
        em.description = msg.content
        em.set_author(name=msg.author.name, icon_url=msg.author.avatar_url)
        em.timestamp = msg.created_at
        await msg.delete()
        await ctx.message.delete()
        await channel.send("{}: This message was redirected here from {}:"
                           .format(msg.author.mention, ctx.channel.mention),
                           embed=em)

setup = Misc.setup
<commit_msg>Send a channel mention after redirect.<commit_after>"""
Misc cog.
"""
import asyncio
import time

import discord
from asyncio_extras import threadpool
from discord.ext import commands

from joku.bot import Context
from joku.checks import has_permissions
from joku.cogs._common import Cog

class Misc(Cog):
    @commands.command()
    async def ping(self, ctx: Context):
        """
        Pong.
        """
        before = time.monotonic()
        msg = await ctx.send(":ping_pong: Ping!")  # type: discord.Message
        after = time.monotonic()
        await msg.edit(content=":ping_pong: Ping! | {}ms".format(round((after - before) * 1000, 2)))

    @commands.command()
    async def cleanup(self, ctx: Context):
        """
        Cleans up bot messages in the last 100 messages.
        """
        channel = ctx.channel  # type: discord.TextChannel
        if channel.permissions_for(ctx.guild.me).manage_messages:
            count = len(await channel.purge(limit=100, check=lambda m: m.author == ctx.guild.me, before=ctx.message))
        else:
            count = 0
            async for message in channel.history(limit=100, before=ctx.message):
                if message.author == ctx.guild.me:
                    await message.delete()
                    count += 1

        m = await ctx.send(":heavy_check_mark: Cleaned up `{}` messages.".format(count))
        await asyncio.sleep(5)
        await m.delete()

    @commands.command()
    @has_permissions(manage_messages=True)
    async def redirect(self, ctx: Context, channel: discord.TextChannel, message: int):
        """
        Redirects a message to another channel.

        The message argument passed must be a message ID.
        To get a message ID you should right click on the on a message and then click "Copy ID". You must have Developer
        Mode enabled to get that functionality.
        """
        o_chan = ctx.channel  # type: discord.TextChannel
        try:
            msg = await o_chan.get_message(message)
        except discord.HTTPException:
            await ctx.send(":x: Could not find that message.")
            return

        # delete it and copy it to the target channel
        em = discord.Embed(title="Redirected by {}".format(ctx.author.name))
        em.description = msg.content
        em.set_author(name=msg.author.name, icon_url=msg.author.avatar_url)
        em.timestamp = msg.created_at
        await msg.delete()
        await ctx.message.delete()
        await channel.send("{}: This message was redirected here from {}:"
                           .format(msg.author.mention, ctx.channel.mention),
                           embed=em)
        # send a link to the channel
        m = await ctx.channel.send(channel.mention)
        await asyncio.sleep(15)
        await m.delete()

setup = Misc.setup
<|endoftext|>